summaryrefslogtreecommitdiffstats
path: root/toolkit/crashreporter/google-breakpad/src/processor
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/crashreporter/google-breakpad/src/processor')
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/address_map-inl.h93
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/address_map.h85
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/address_map_unittest.cc196
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/basic_code_module.h116
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/basic_code_modules.cc155
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/basic_code_modules.h98
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/basic_source_line_resolver.cc612
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/basic_source_line_resolver_types.h177
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/basic_source_line_resolver_unittest.cc682
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/call_stack.cc54
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/cfi_frame_info-inl.h119
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/cfi_frame_info.cc186
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/cfi_frame_info.h275
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/cfi_frame_info_unittest.cc546
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/contained_range_map-inl.h197
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/contained_range_map.h150
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/contained_range_map_unittest.cc263
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/disassembler_x86.cc240
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/disassembler_x86.h127
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/disassembler_x86_unittest.cc233
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/dump_context.cc659
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/dump_object.cc39
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/exploitability.cc119
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/exploitability_linux.cc625
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/exploitability_linux.h129
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/exploitability_unittest.cc306
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/exploitability_win.cc283
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/exploitability_win.h55
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/fast_source_line_resolver.cc275
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/fast_source_line_resolver_types.h185
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/fast_source_line_resolver_unittest.cc491
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/linked_ptr.h193
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/logging.cc111
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/logging.h186
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/map_serializers-inl.h266
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/map_serializers.h168
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/map_serializers_unittest.cc386
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/microdump.cc385
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/microdump_processor.cc100
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/microdump_processor_unittest.cc273
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/microdump_stackwalk.cc151
-rwxr-xr-xtoolkit/crashreporter/google-breakpad/src/processor/microdump_stackwalk_machine_readable_test43
-rwxr-xr-xtoolkit/crashreporter/google-breakpad/src/processor/microdump_stackwalk_test43
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/microdump_stackwalk_test_vars1
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/minidump.cc4989
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/minidump_dump.cc213
-rwxr-xr-xtoolkit/crashreporter/google-breakpad/src/processor/minidump_dump_test36
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/minidump_processor.cc1577
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/minidump_processor_unittest.cc645
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/minidump_stackwalk.cc162
-rwxr-xr-xtoolkit/crashreporter/google-breakpad/src/processor/minidump_stackwalk_machine_readable_test37
-rwxr-xr-xtoolkit/crashreporter/google-breakpad/src/processor/minidump_stackwalk_test37
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/minidump_unittest.cc1521
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/module_comparer.cc302
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/module_comparer.h98
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/module_factory.h72
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/module_serializer.cc207
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/module_serializer.h127
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/moz.build66
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/pathname_stripper.cc56
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/pathname_stripper.h53
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/pathname_stripper_unittest.cc87
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/postfix_evaluator-inl.h363
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/postfix_evaluator.h179
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/postfix_evaluator_unittest.cc403
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/proc_maps_linux.cc106
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/proc_maps_linux_unittest.cc251
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/process_state.cc69
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/processor.gyp184
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/processor_tools.gypi57
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/proto/README20
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/proto/process_state.proto210
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/range_map-inl.h272
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/range_map.h161
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/range_map_shrink_down_unittest.cc355
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/range_map_unittest.cc559
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/simple_serializer-inl.h260
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/simple_serializer.h63
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/simple_symbol_supplier.cc204
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/simple_symbol_supplier.h140
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/source_line_resolver_base.cc341
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/source_line_resolver_base_types.h158
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stack_frame_cpu.cc79
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stack_frame_symbolizer.cc138
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stackwalk_common.cc950
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stackwalk_common.h49
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stackwalker.cc296
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stackwalker_address_list.cc92
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stackwalker_address_list.h72
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stackwalker_address_list_unittest.cc197
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stackwalker_amd64.cc340
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stackwalker_amd64.h116
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stackwalker_amd64_unittest.cc932
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm.cc296
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm.h107
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm64.cc278
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm64.h104
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm64_unittest.cc880
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm_unittest.cc974
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stackwalker_mips.cc448
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stackwalker_mips.h85
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stackwalker_mips_unittest.cc707
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stackwalker_ppc.cc146
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stackwalker_ppc.h79
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stackwalker_ppc64.cc137
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stackwalker_ppc64.h77
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stackwalker_selftest.cc433
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stackwalker_selftest_sol.s111
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stackwalker_sparc.cc139
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stackwalker_sparc.h78
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stackwalker_unittest_utils.h224
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stackwalker_x86.cc672
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stackwalker_x86.h117
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/stackwalker_x86_unittest.cc2128
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/static_address_map-inl.h71
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/static_address_map.h78
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/static_address_map_unittest.cc236
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/static_contained_range_map-inl.h92
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/static_contained_range_map.h96
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/static_contained_range_map_unittest.cc320
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/static_map-inl.h176
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/static_map.h144
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/static_map_iterator-inl.h147
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/static_map_iterator.h112
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/static_map_unittest.cc386
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/static_range_map-inl.h130
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/static_range_map.h106
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/static_range_map_unittest.cc421
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/symbolic_constants_win.cc6418
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/symbolic_constants_win.h50
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/synth_minidump.cc391
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/synth_minidump.h372
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/synth_minidump_unittest.cc336
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/synth_minidump_unittest_data.h418
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/tokenize.cc79
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/tokenize.h63
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/windows_frame_info.h209
137 files changed, 0 insertions, 47048 deletions
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 <assert.h>
-
-#include "processor/logging.h"
-
-namespace google_breakpad {
-
-template<typename AddressType, typename EntryType>
-bool AddressMap<AddressType, EntryType>::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<typename AddressType, typename EntryType>
-bool AddressMap<AddressType, EntryType>::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<typename AddressType, typename EntryType>
-void AddressMap<AddressType, EntryType>::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 <map>
-
-namespace google_breakpad {
-
-// Forward declarations (for later friend declarations).
-template<class, class> class AddressMapSerializer;
-
-template<typename AddressType, typename EntryType>
-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<AddressType, EntryType>;
- friend class ModuleComparer;
-
- // Convenience types.
- typedef std::map<AddressType, EntryType> 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 <limits.h>
-#include <stdio.h>
-
-#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<CountedObject> > TestMap;
-
-static bool DoAddressMapTest() {
- ASSERT_EQ(CountedObject::count(), 0);
-
- TestMap test_map;
- linked_ptr<CountedObject> 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<CountedObject>(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<CountedObject>(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<CountedObject>(new CountedObject(2))));
- ASSERT_EQ(CountedObject::count(), 2);
- ASSERT_TRUE(test_map.Store(20,
- linked_ptr<CountedObject>(new CountedObject(3))));
- ASSERT_TRUE(test_map.Store(15,
- linked_ptr<CountedObject>(new CountedObject(4))));
- ASSERT_FALSE(test_map.Store(10,
- linked_ptr<CountedObject>(new CountedObject(5)))); // already in map
- ASSERT_TRUE(test_map.Store(16,
- linked_ptr<CountedObject>(new CountedObject(6))));
- ASSERT_TRUE(test_map.Store(14,
- linked_ptr<CountedObject>(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 <string>
-
-#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 <assert.h>
-
-#include <vector>
-
-#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<const CodeModule> 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<const CodeModule> 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<CodeModule> 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<const CodeModule> 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<const CodeModule> 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<linked_ptr<const CodeModule> >
-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 <stddef.h>
-
-#include <vector>
-
-#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<linked_ptr<const CodeModule> >
- 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<uint64_t, linked_ptr<const CodeModule> > map_;
-
- // A vector of all CodeModules that were shrunk downs due to
- // address range conflicts.
- std::vector<linked_ptr<const CodeModule> > 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 <assert.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <limits>
-#include <map>
-#include <utility>
-#include <vector>
-
-#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<Function> 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 <guid> <age> <filename>
- } else if (strncmp(buffer, "INFO ", 5) == 0) {
- // Ignore these as well, they're similarly just for housekeeping.
- //
- // INFO CODE_ID <code id> <filename>
- } 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>(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<Function> func;
- linked_ptr<PublicSymbol> 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> 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<WindowsFrameInfo> 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<WindowsFrameInfo> 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> 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<PublicSymbol> 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<CFIFrameInfo> 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<MemAddr, string>::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<PublicSymbol> 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<WindowsFrameInfo>
- 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 <address> <size> <rules...>".
- 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 <address> <rules...>".
- 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 <id> <filename>
- assert(strncmp(file_line, "FILE ", 5) == 0);
- file_line += 5; // skip prefix
-
- vector<char*> 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<long>::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 <address> <size> <stack_param_size> <name>
- assert(strncmp(function_line, "FUNC ", 5) == 0);
- function_line += 5; // skip prefix
-
- vector<char*> 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<unsigned long long>::max()) {
- return false;
- }
- *size = strtoull(tokens[1], &after_number, 16);
- if (!IsValidAfterNumber(after_number) ||
- *size == std::numeric_limits<unsigned long long>::max()) {
- return false;
- }
- *stack_param_size = strtol(tokens[2], &after_number, 16);
- if (!IsValidAfterNumber(after_number) ||
- *stack_param_size == std::numeric_limits<long>::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) {
- // <address> <size> <line number> <source file id>
- vector<char*> 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<unsigned long long>::max()) {
- return false;
- }
- *size = strtoull(tokens[1], &after_number, 16);
- if (!IsValidAfterNumber(after_number) ||
- *size == std::numeric_limits<unsigned long long>::max()) {
- return false;
- }
- *line_number = strtol(tokens[2], &after_number, 10);
- if (!IsValidAfterNumber(after_number) ||
- *line_number == std::numeric_limits<long>::max()) {
- return false;
- }
- *source_file = strtol(tokens[3], &after_number, 10);
- if (!IsValidAfterNumber(after_number) || *source_file < 0 ||
- *source_file == std::numeric_limits<long>::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 <address> <stack_param_size> <name>
- assert(strncmp(public_line, "PUBLIC ", 7) == 0);
- public_line += 7; // skip prefix
-
- vector<char*> 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<unsigned long long>::max()) {
- return false;
- }
- *stack_param_size = strtol(tokens[1], &after_number, 16);
- if (!IsValidAfterNumber(after_number) ||
- *stack_param_size == std::numeric_limits<long>::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 <map>
-#include <string>
-
-#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<Line> > 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<int, string> 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<Function> > functions_;
- AddressMap< MemAddr, linked_ptr<PublicSymbol> > 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<WindowsFrameInfo> >
- 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<MemAddr, string> 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<MemAddr, string> 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 <assert.h>
-#include <stdio.h>
-
-#include <string>
-
-#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<uint32_t> &expected,
- const CFIFrameInfo::RegisterValueMap<uint32_t> &actual) {
- CFIFrameInfo::RegisterValueMap<uint32_t>::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<uint32_t>::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<WindowsFrameInfo> windows_frame_info;
- scoped_ptr<CFIFrameInfo> 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<uint32_t> current_registers;
- CFIFrameInfo::RegisterValueMap<uint32_t> caller_registers;
- CFIFrameInfo::RegisterValueMap<uint32_t> 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<uint32_t>(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<uint32_t>(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<uint32_t>(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<uint32_t>(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<uint32_t>(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<uint32_t>(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 <id> <filename>
-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 <id> <filename>
-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 <address> <size> <stack_param_size> <name>
-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 <address> <size> <stack_param_size> <name>
-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:
-// <address> <size> <line number> <source file id>
-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:
-// <address> <size> <line number> <source file id>
-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 <address> <stack_param_size> <name>
-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 <address> <stack_param_size> <name>
-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<StackFrame *>::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 <jimb@mozilla.com> <jimb@red-bean.com>
-
-// 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 <string.h>
-
-namespace google_breakpad {
-
-template <typename RegisterType, class RawContextType>
-bool SimpleCFIWalker<RegisterType, RawContextType>::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<RegisterType> 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<RegisterType>(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 <jimb@mozilla.com> <jimb@red-bean.com>
-
-// cfi_frame_info.cc: Implementation of CFIFrameInfo class.
-// See cfi_frame_info.h for details.
-
-#include "processor/cfi_frame_info.h"
-
-#include <string.h>
-
-#include <sstream>
-
-#include "common/scoped_ptr.h"
-#include "processor/postfix_evaluator-inl.h"
-
-namespace google_breakpad {
-
-#ifdef _MSC_VER
-#define strtok_r strtok_s
-#endif
-
-template<typename V>
-bool CFIFrameInfo::FindCallerRegs(const RegisterValueMap<V> &registers,
- const MemoryRegion &memory,
- RegisterValueMap<V> *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<V> working;
- PostfixEvaluator<V> 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<uint32_t>(
- const RegisterValueMap<uint32_t> &registers,
- const MemoryRegion &memory,
- RegisterValueMap<uint32_t> *caller_registers) const;
-template bool CFIFrameInfo::FindCallerRegs<uint64_t>(
- const RegisterValueMap<uint64_t> &registers,
- const MemoryRegion &memory,
- RegisterValueMap<uint64_t> *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<std::streamoff>(stream.tellp()) != 0)
- stream << " ";
- stream << ".ra: " << ra_rule_;
- }
- for (RuleMap::const_iterator iter = register_rules_.begin();
- iter != register_rules_.end();
- ++iter) {
- if (static_cast<std::streamoff>(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<char> 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 <jimb@mozilla.com> <jimb@red-bean.com>
-
-// 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 <map>
-#include <string>
-
-#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<typename ValueType> class RegisterValueMap:
- public map<string, ValueType> { };
-
- // 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 &register_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<typename ValueType>
- bool FindCallerRegs(const RegisterValueMap<ValueType> &registers,
- const MemoryRegion &memory,
- RegisterValueMap<ValueType> *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<string, string> 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 <typename RegisterType, class RawContextType>
-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 <jimb@mozilla.com> <jimb@red-bean.com>
-
-// cfi_frame_info_unittest.cc: Unit tests for CFIFrameInfo,
-// CFIRuleParser, CFIFrameInfoParseHandler, and SimpleCFIWalker.
-
-#include <string.h>
-
-#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<uint8_t *>())).Times(0);
- EXPECT_CALL(memory, GetMemoryAtAddress(_, A<uint16_t *>())).Times(0);
- EXPECT_CALL(memory, GetMemoryAtAddress(_, A<uint32_t *>())).Times(0);
- EXPECT_CALL(memory, GetMemoryAtAddress(_, A<uint64_t *>())).Times(0);
- }
-
- CFIFrameInfo cfi;
- MockMemoryRegion memory;
- CFIFrameInfo::RegisterValueMap<uint64_t> 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<uint64_t>(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<uint64_t>(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<uint64_t>(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<uint64_t>(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<uint64_t>(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<uint64_t>(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<uint64_t>(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<uint64_t>(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<uint64_t>(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<uint64_t>(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<uint64_t>(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<uint64_t>(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<uint64_t>(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<uint64_t>(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<uint64_t>(registers, memory,
- &caller_registers));
-
- cfi.SetCFARule("$temp1 76569129 = $temp1");
- cfi.SetRARule("$temp1");
- ASSERT_FALSE(cfi.FindCallerRegs<uint64_t>(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<uint64_t>(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<uint64_t>(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<uint64_t, RawContext> 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<uint64_t *>()))
- .WillRepeatedly(DoAll(SetArgumentPointee<1>(0xdc1975eba8602302ULL),
- Return(true)));
- // Saved return address.
- EXPECT_CALL(memory,
- GetMemoryAtAddress(stack_top + 16, A<uint64_t *>()))
- .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 <assert.h>
-
-#include "processor/logging.h"
-
-
-namespace google_breakpad {
-
-
-template<typename AddressType, typename EntryType>
-ContainedRangeMap<AddressType, EntryType>::~ContainedRangeMap() {
- // Clear frees the children pointed to by the map, and frees the map itself.
- Clear();
-}
-
-
-template<typename AddressType, typename EntryType>
-bool ContainedRangeMap<AddressType, EntryType>::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<typename AddressType, typename EntryType>
-bool ContainedRangeMap<AddressType, EntryType>::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<typename AddressType, typename EntryType>
-void ContainedRangeMap<AddressType, EntryType>::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 <map>
-
-
-namespace google_breakpad {
-
-// Forward declarations (for later friend declarations of specialized template).
-template<class, class> class ContainedRangeMapSerializer;
-
-template<typename AddressType, typename EntryType>
-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<AddressType, EntryType>;
- friend class ModuleComparer;
-
- // AddressToRangeMap stores pointers. This makes reparenting simpler in
- // StoreRange, because it doesn't need to copy entire objects.
- typedef std::map<AddressType, ContainedRangeMap *> 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 <stdio.h>
-
-#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<unsigned int, int> 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 <string.h>
-
-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(&current_instr_);
-
- libdis::x86_cleanup();
-}
-
-uint32_t DisassemblerX86::NextInstruction() {
- if (instr_valid_)
- libdis::x86_oplist_free(&current_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_,
- &current_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(&current_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(&current_instr_);
- libdis::x86_op_t *dest = libdis::x86_get_dest_operand(&current_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(&current_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(&current_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 <stddef.h>
-#include <sys/types.h>
-
-#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_ ? &current_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 <unistd.h>
-
-#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 <assert.h>
-
-#ifdef _WIN32
-#include <io.h>
-#else // _WIN32
-#include <unistd.h>
-#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 <cassert>
-
-#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 <regex.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <sstream>
-#include <iterator>
-#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<StackFrame*>& 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<string> tokens;
- std::istringstream line_stream(line);
- copy(std::istream_iterator<string>(line_stream),
- std::istream_iterator<string>(),
- std::back_inserter(tokens));
-
- // Regex for the data in hex form. Each byte is two hex digits.
- regex_t regex;
- regcomp(&regex, "^[[: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(&regex, 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(&regex);
-
- 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 <stdlib.h>
-#include <unistd.h>
-
-#include <string>
-
-#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 <srcdir>/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 <vector>
-
-#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<MDAccessViolationTypeWin>
- (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 <map>
-#include <string>
-#include <utility>
-
-#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<Function> func(new Function);
- const Function* func_ptr = 0;
- scoped_ptr<PublicSymbol> 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> 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<const WindowsFrameInfo::StackInfoTypes>(
- *reinterpret_cast<const int32_t*>(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<const uint32_t*>(
- 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<const char*>(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<bool>::Read(mem_buffer, &is_corrupt_);
-
- const uint32_t *map_sizes = reinterpret_cast<const uint32_t*>(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<int, char>(mem_buffer + offsets[map_id++]);
- functions_ =
- StaticRangeMap<MemAddr, Function>(mem_buffer + offsets[map_id++]);
- public_symbols_ =
- StaticAddressMap<MemAddr, PublicSymbol>(mem_buffer + offsets[map_id++]);
- for (int i = 0; i < WindowsFrameInfo::STACK_INFO_LAST; ++i)
- windows_frame_info_[i] =
- StaticContainedRangeMap<MemAddr, char>(mem_buffer + offsets[map_id++]);
-
- cfi_initial_rules_ =
- StaticRangeMap<MemAddr, char>(mem_buffer + offsets[map_id++]);
- cfi_delta_rules_ = StaticMap<MemAddr, char>(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<WindowsFrameInfo> 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> 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<PublicSymbol> 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<CFIFrameInfo> 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<MemAddr, char>::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 <map>
-#include <string>
-
-#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<const char*>(line_ptr);
- CopyFrom(raw);
- }
-
- // De-serialize the memory data of a Line.
- void CopyFrom(const char *raw) {
- address = *(reinterpret_cast<const MemAddr*>(raw));
- size = *(reinterpret_cast<const MemAddr*>(raw + sizeof(address)));
- source_file_id = *(reinterpret_cast<const int32_t *>(
- raw + 2 * sizeof(address)));
- line = *(reinterpret_cast<const int32_t*>(
- 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<const char*>(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<const MemAddr*>(raw + name_size));
- size = *(reinterpret_cast<const MemAddr*>(
- raw + name_size + sizeof(MemAddr)));
- parameter_size = *(reinterpret_cast<const int32_t*>(
- raw + name_size + 2 * sizeof(MemAddr)));
- lines = StaticRangeMap<MemAddr, Line>(
- raw + name_size + 2 * sizeof(MemAddr) + sizeof(int32_t));
- }
-
- StaticRangeMap<MemAddr, Line> lines;
-};
-
-struct FastSourceLineResolver::PublicSymbol :
-public SourceLineResolverBase::PublicSymbol {
- void CopyFrom(const PublicSymbol *public_symbol_ptr) {
- const char *raw = reinterpret_cast<const char*>(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<const MemAddr*>(raw + name_size));
- parameter_size = *(reinterpret_cast<const int32_t*>(
- 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<int, char> FileMap;
-
- string name_;
- StaticMap<int, char> files_;
- StaticRangeMap<MemAddr, Function> functions_;
- StaticAddressMap<MemAddr, PublicSymbol> 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<MemAddr, char>
- 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<MemAddr, char> 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<MemAddr, char> 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 <assert.h>
-#include <stdio.h>
-
-#include <sstream>
-#include <string>
-
-#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<uint32_t> &expected,
- const CFIFrameInfo::RegisterValueMap<uint32_t> &actual) {
- CFIFrameInfo::RegisterValueMap<uint32_t>::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<uint32_t>::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<WindowsFrameInfo> windows_frame_info;
- scoped_ptr<CFIFrameInfo> 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<uint32_t> current_registers;
- CFIFrameInfo::RegisterValueMap<uint32_t> caller_registers;
- CFIFrameInfo::RegisterValueMap<uint32_t> 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<uint32_t>(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<uint32_t>(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<uint32_t>(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<uint32_t>(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<uint32_t>(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<uint32_t>(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<Superclass>(obj) vs linked_ptr<Subclass>(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<T>.
-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 <typename T>
-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 <typename U> linked_ptr(linked_ptr<U> const& ptr) { copy(&ptr); }
- linked_ptr(linked_ptr const& ptr) { copy(&ptr); }
-
- // Assignment releases the old value and acquires the new.
- template <typename U> linked_ptr& operator=(linked_ptr<U> 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 <typename U>
- bool operator==(linked_ptr<U> const& ptr) const {
- return value_ == ptr.get();
- }
- template <typename U>
- bool operator!=(linked_ptr<U> const& ptr) const {
- return value_ != ptr.get();
- }
-
- private:
- template <typename U>
- 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 <typename U> void copy(linked_ptr<U> const* ptr) {
- value_ = ptr->get();
- if (value_)
- link_.join(&ptr->link_);
- else
- link_.join_new();
- }
-};
-
-template<typename T> inline
-bool operator==(T* ptr, const linked_ptr<T>& x) {
- return ptr == x.get();
-}
-
-template<typename T> inline
-bool operator!=(T* ptr, const linked_ptr<T>& x) {
- return ptr != x.get();
-}
-
-// A function to convert T* into linked_ptr<T>
-// Doing e.g. make_linked_ptr(new FooBarBaz<type>(arg)) is a shorter notation
-// for linked_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg))
-template <typename T>
-linked_ptr<T> make_linked_ptr(T* ptr) {
- return linked_ptr<T>(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 <assert.h>
-#include <errno.h>
-#include <string.h>
-#include <time.h>
-
-#include <string>
-
-#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 <iostream>
-#include <string>
-
-#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<typename T> 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 <map>
-#include <string>
-
-#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<typename Key, typename Value>
-size_t StdMapSerializer<Key, Value>::SizeOf(
- const std::map<Key, Value> &m) const {
- size_t size = 0;
- size_t header_size = (1 + m.size()) * sizeof(uint32_t);
- size += header_size;
-
- typename std::map<Key, Value>::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<typename Key, typename Value>
-char *StdMapSerializer<Key, Value>::Write(const std::map<Key, Value> &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<uint32_t>::Write(m.size(), dest);
- // Nodes offsets.
- uint32_t *offsets = reinterpret_cast<uint32_t*>(dest);
- dest += sizeof(uint32_t) * m.size();
-
- char *key_address = dest;
- dest += sizeof(Key) * m.size();
-
- // Traverse map.
- typename std::map<Key, Value>::const_iterator iter;
- int index = 0;
- for (iter = m.begin(); iter != m.end(); ++iter, ++index) {
- offsets[index] = static_cast<uint32_t>(dest - start_address);
- key_address = key_serializer_.Write(iter->first, key_address);
- dest = value_serializer_.Write(iter->second, dest);
- }
- return dest;
-}
-
-template<typename Key, typename Value>
-char *StdMapSerializer<Key, Value>::Serialize(
- const std::map<Key, Value> &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<typename Address, typename Entry>
-size_t RangeMapSerializer<Address, Entry>::SizeOf(
- const RangeMap<Address, Entry> &m) const {
- size_t size = 0;
- size_t header_size = (1 + m.map_.size()) * sizeof(uint32_t);
- size += header_size;
-
- typename std::map<Address, Range>::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<typename Address, typename Entry>
-char *RangeMapSerializer<Address, Entry>::Write(
- const RangeMap<Address, Entry> &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<uint32_t>::Write(m.map_.size(), dest);
- // Nodes offsets.
- uint32_t *offsets = reinterpret_cast<uint32_t*>(dest);
- dest += sizeof(uint32_t) * m.map_.size();
-
- char *key_address = dest;
- dest += sizeof(Address) * m.map_.size();
-
- // Traverse map.
- typename std::map<Address, Range>::const_iterator iter;
- int index = 0;
- for (iter = m.map_.begin(); iter != m.map_.end(); ++iter, ++index) {
- offsets[index] = static_cast<uint32_t>(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<typename Address, typename Entry>
-char *RangeMapSerializer<Address, Entry>::Serialize(
- const RangeMap<Address, Entry> &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<class AddrType, class EntryType>
-size_t ContainedRangeMapSerializer<AddrType, EntryType>::SizeOf(
- const ContainedRangeMap<AddrType, EntryType> *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<class AddrType, class EntryType>
-char *ContainedRangeMapSerializer<AddrType, EntryType>::Write(
- const ContainedRangeMap<AddrType, EntryType> *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<uint32_t>::Write(entry_serializer_.SizeOf(m->entry_),
- dest);
- dest = entry_serializer_.Write(m->entry_, dest);
-
- // Write map<<AddrType, ContainedRangeMap*>:
- char *map_address = dest;
- if (m->map_ == NULL) {
- dest = SimpleSerializer<uint32_t>::Write(0, dest);
- } else {
- dest = SimpleSerializer<uint32_t>::Write(m->map_->size(), dest);
- uint32_t *offsets = reinterpret_cast<uint32_t*>(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<uint32_t>(dest - map_address);
- key_address = addr_serializer_.Write(iter->first, key_address);
- // Recursively write.
- dest = Write(iter->second, dest);
- }
- }
- return dest;
-}
-
-template<class AddrType, class EntryType>
-char *ContainedRangeMapSerializer<AddrType, EntryType>::Serialize(
- const ContainedRangeMap<AddrType, EntryType> *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 <map>
-#include <string>
-
-#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<typename Key, typename Value>
-class StdMapSerializer {
- public:
- // Calculate the memory size of serialized data.
- size_t SizeOf(const std::map<Key, Value> &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<Key, Value> &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<Key, Value> &m, unsigned int *size) const;
-
- private:
- SimpleSerializer<Key> key_serializer_;
- SimpleSerializer<Value> value_serializer_;
-};
-
-// AddressMapSerializer allocates memory and serializes an AddressMap into a
-// chunk of memory data.
-template<typename Addr, typename Entry>
-class AddressMapSerializer {
- public:
- // Calculate the memory size of serialized data.
- size_t SizeOf(const AddressMap<Addr, Entry> &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<Addr, Entry> &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<Addr, Entry> &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<Addr, Entry> std_map_serializer_;
-};
-
-// RangeMapSerializer allocates memory and serializes a RangeMap instance into a
-// chunk of memory data.
-template<typename Address, typename Entry>
-class RangeMapSerializer {
- public:
- // Calculate the memory size of serialized data.
- size_t SizeOf(const RangeMap<Address, Entry> &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<Address, Entry> &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<Address, Entry> &m, unsigned int *size) const;
-
- private:
- // Convenient type name for Range.
- typedef typename RangeMap<Address, Entry>::Range Range;
-
- // Serializer for RangeMap's key and Range::base_.
- SimpleSerializer<Address> address_serializer_;
- // Serializer for RangeMap::Range::entry_.
- SimpleSerializer<Entry> entry_serializer_;
-};
-
-// ContainedRangeMapSerializer allocates memory and serializes a
-// ContainedRangeMap instance into a chunk of memory data.
-template<class AddrType, class EntryType>
-class ContainedRangeMapSerializer {
- public:
- // Calculate the memory size of serialized data.
- size_t SizeOf(const ContainedRangeMap<AddrType, EntryType> *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<AddrType, EntryType> *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<AddrType, EntryType> *m,
- unsigned int *size) const;
-
- private:
- // Convenient type name for the underlying map type.
- typedef std::map<AddrType, ContainedRangeMap<AddrType, EntryType>*> Map;
-
- // Serializer for addresses and entries stored in ContainedRangeMap.
- SimpleSerializer<AddrType> addr_serializer_;
- SimpleSerializer<EntryType> 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 <climits>
-#include <map>
-#include <string>
-#include <utility>
-#include <iostream>
-#include <sstream>
-
-#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<AddrType, EntryType> std_map_;
- google_breakpad::StdMapSerializer<AddrType, EntryType> 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<AddrType, EntryType> address_map_;
- google_breakpad::AddressMapSerializer<AddrType, EntryType> 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<AddrType, EntryType> range_map_;
- google_breakpad::RangeMapSerializer<AddrType, EntryType> 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<AddrType, EntryType> crm_map_;
- google_breakpad::ContainedRangeMapSerializer<AddrType, EntryType> 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 <stdio.h>
-#include <string.h>
-
-#include <memory>
-#include <sstream>
-#include <string>
-#include <vector>
-
-#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<typename T>
-T HexStrToL(const string& str) {
- uint64_t res = 0;
- std::istringstream ss(str);
- ss >> std::hex >> res;
- return static_cast<T>(res);
-}
-
-std::vector<uint8_t> ParseHexBuf(const string& str) {
- std::vector<uint8_t> buf;
- for (size_t i = 0; i < str.length(); i += 2) {
- buf.push_back(HexStrToL<uint8_t>(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<const CodeModule> 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<uint8_t>& 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<typename ValueType>
-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<uint8_t>(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<uint8_t> 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<uint8_t>(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<uint64_t>(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<uint8_t> 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<uint8_t> 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<uint64_t>(addr), // base_address
- HexStrToL<uint64_t>(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 <assert.h>
-
-#include <string>
-
-#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 &microdump_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(
- Stackwalker::StackwalkerForCPU(
- &process_state->system_info_,
- microdump.GetContext(),
- microdump.GetMemory(),
- process_state->modules_,
- frame_symbolizer_));
-
- scoped_ptr<CallStack> 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 <fstream>
-#include <iostream>
-#include <string>
-#include <vector>
-
-#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<char> 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, &microdump_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 <stdio.h>
-#include <string.h>
-
-#include <fstream>
-#include <string>
-#include <vector>
-
-#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<string>& symbol_paths,
- bool machine_readable) {
- std::ifstream file_stream(microdump_file);
- std::vector<char> 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<SimpleSymbolSupplier> 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] <microdump-file> [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<string> 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 <assert.h>
-#include <fcntl.h>
-#include <stddef.h>
-#include <string.h>
-#include <time.h>
-
-#ifdef _WIN32
-#include <io.h>
-#else // _WIN32
-#include <unistd.h>
-#endif // _WIN32
-
-#include <algorithm>
-#include <fstream>
-#include <iostream>
-#include <limits>
-#include <map>
-#include <vector>
-
-#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<uint32_t*>(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<uint32_t*>(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<uint16_t>& in,
- bool swap) {
- scoped_ptr<string> 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<uint16_t>::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<char>(unichar);
- } else if (unichar < 0x800) {
- (*out) += 0xc0 | static_cast<char>(unichar >> 6);
- (*out) += 0x80 | static_cast<char>(unichar & 0x3f);
- } else if (unichar < 0x10000) {
- (*out) += 0xe0 | static_cast<char>(unichar >> 12);
- (*out) += 0x80 | static_cast<char>((unichar >> 6) & 0x3f);
- (*out) += 0x80 | static_cast<char>(unichar & 0x3f);
- } else if (unichar < 0x200000) {
- (*out) += 0xf0 | static_cast<char>(unichar >> 18);
- (*out) += 0x80 | static_cast<char>((unichar >> 12) & 0x3f);
- (*out) += 0x80 | static_cast<char>((unichar >> 6) & 0x3f);
- (*out) += 0x80 | static_cast<char>(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<uint16_t> utf16_vector(word_length);
- memcpy(&utf16_vector[0], &utf16_data[0], byte_length);
- scoped_ptr<string> 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(&timestruct, &tt);
-#else
- gmtime_r(&tt, &timestruct);
-#endif
-
- char timestr[20];
- int rv = strftime(timestr, 20, "%Y-%m-%d %H:%M:%S", &timestruct);
- 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<MDRawContextAMD64> 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<MDRawContextPPC64> 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<uint8_t*>(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<uint32_t>(context_ppc64->context_flags));
-
- // Check for data loss when converting context flags from uint64_t into
- // uint32_t
- if (static_cast<uint64_t>(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<MDRawContextARM64> 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<uint8_t*>(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<uint32_t>(context_arm64->context_flags));
-
- // Check for data loss when converting context flags from uint64_t into
- // uint32_t
- if (static_cast<uint64_t>(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<MDRawContextX86> 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<uint8_t*>(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<MDRawContextPPC> 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<uint8_t*>(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<MDRawContextSPARC> 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<uint8_t*>(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<MDRawContextARM> 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<uint8_t*>(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<MDRawContextMIPS> 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<uint8_t*>(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<MDCPUArchitecture>(
- 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<uint64_t>::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<uint8_t> > memory(
- new vector<uint8_t>(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<uint64_t>(-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<typename T>
-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<uint64_t>::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<const T*>(
- &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<uint64_t>::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<MinidumpContext> 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<uint32_t>::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<MinidumpThreads> 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<uint64_t>::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<const MDCVInfoELF*>(&(*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<const MDCVInfoPDB70*>(&(*cv_record_)[0]);
- assert(cv_record_70->cv_signature == MD_CVINFOPDB70_SIGNATURE);
-
- // GetCVRecord guarantees pdb_file_name is null-terminated.
- file = reinterpret_cast<const char*>(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<const MDCVInfoPDB20*>(&(*cv_record_)[0]);
- assert(cv_record_20->cv_header.signature == MD_CVINFOPDB20_SIGNATURE);
-
- // GetCVRecord guarantees pdb_file_name is null-terminated.
- file = reinterpret_cast<const char*>(cv_record_20->pdb_file_name);
- } else if (cv_record_signature_ == MD_CVINFOELF_SIGNATURE) {
- // It's actually an MDCVInfoELF structure.
- assert(reinterpret_cast<const MDCVInfoELF*>(&(*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<const MDImageDebugMisc *>(&(*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<const char*>(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<uint16_t>, so create a temporary one
- // and copy the UTF-16 data into it.
- vector<uint16_t> 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<string> 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<const MDCVInfoPDB70*>(&(*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<const MDCVInfoPDB20*>(&(*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<const MDCVInfoELF*>(&(*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<uint8_t> > cv_record(
- new vector<uint8_t>(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<MDCVInfoPDB70*>(&(*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<MDCVInfoPDB70*>(&(*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<MDCVInfoPDB20*>(&(*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<uint8_t> > misc_record_mem(
- new vector<uint8_t>(module_.misc_record.data_size));
- MDImageDebugMisc* misc_record =
- reinterpret_cast<MDImageDebugMisc*>(&(*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<uint16_t*>(&(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<MDImageDebugMisc*>(&(*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<const MDCVInfoPDB70*>(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<const MDCVInfoPDB20*>(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<const MDCVInfoELF*>(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<const uint16_t*>(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<uint64_t, unsigned int>()),
- 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<uint32_t>::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<MinidumpModules> 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<uint64_t>(-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<linked_ptr<const CodeModule> >
-MinidumpModuleList::GetShrunkRangeModules() const {
- return vector<linked_ptr<const CodeModule> >();
-}
-
-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<uint64_t, unsigned int>()),
- 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(&region_count, sizeof(region_count))) {
- BPLOG(ERROR) << "MinidumpMemoryList could not read memory region count";
- return false;
- }
-
- if (minidump_->swap())
- Swap(&region_count);
-
- if (region_count >
- numeric_limits<uint32_t>::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<MemoryDescriptors> 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<MemoryRegions> 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<uint64_t>::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, &region_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<MinidumpContext> 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<uint64_t>::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<uint64_t, unsigned int>()),
- 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<uint32_t>::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<unsigned int>(header.number_of_entries);
- if (static_cast<uint64_t>(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<MinidumpMemoryInfos> 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<char> 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<MappedMemoryRegion> all_regions;
-
- // Parse string into mapping data.
- if (!ParseProcMaps(map_string, &all_regions)) {
- return false;
- }
-
- scoped_ptr<MinidumpLinuxMappings> maps(new MinidumpLinuxMappings());
-
- // Push mapping data into wrapper classes.
- for (size_t i = 0; i < all_regions.size(); i++) {
- scoped_ptr<MinidumpLinuxMaps> 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<MinidumpDirectoryEntries> 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<char*>(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<size_t>(bytes_read);
- if (static_cast<std::streamsize>(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<off_t>(std_streamoff);
- if (static_cast<std::streamoff>(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<uint16_t> 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<typename T>
-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<T*>(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<T> 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 <stdio.h>
-#include <string.h>
-
-#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<char> 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<char *>(
- 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 <file>\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 <assert.h>
-
-#include <string>
-
-#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<const CodeModule> 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(
- Stackwalker::StackwalkerForCPU(process_state->system_info(),
- context,
- thread_memory,
- process_state->modules_,
- frame_symbolizer_));
-
- scoped_ptr<CallStack> 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(
- 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<MDAccessViolationTypeWin>
- (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<MDInPageErrorTypeWin>
- (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<uint32_t>
- (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 <stdlib.h>
-
-#include <string>
-#include <iostream>
-#include <fstream>
-#include <map>
-#include <utility>
-
-#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<string, char *> 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<string, char *>::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<MDRawHeader*>(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<MinidumpThreadList*>(NULL)));
- EXPECT_CALL(dump, GetSystemInfo()).
- WillRepeatedly(Return(reinterpret_cast<MinidumpSystemInfo*>(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<MinidumpMemoryRegion*>(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<MinidumpMemoryRegion*>(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<SymbolSupplier*>(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<SymbolSupplier*>(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<MinidumpContext*>(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<SymbolSupplier*>(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 <stdio.h>
-#include <string.h>
-
-#include <string>
-#include <vector>
-
-#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<string> &symbol_paths,
- bool machine_readable,
- bool output_stack_contents) {
- scoped_ptr<SimpleSymbolSupplier> 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] <minidump-file> [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<string> 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 <iostream>
-#include <fstream>
-#include <sstream>
-#include <stdlib.h>
-#include <string>
-#include <vector>
-
-#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<char> 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<MinidumpContext*>(NULL), md_context);
-
- MinidumpMemoryRegion* md_stack = md_thread->GetMemory();
- ASSERT_EQ(reinterpret_cast<MinidumpMemoryRegion*>(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<MinidumpMemoryRegion*>(NULL), md_stack);
-
- MinidumpContext* md_context = md_thread->GetContext();
- ASSERT_EQ(reinterpret_cast<MinidumpContext*>(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 <map>
-#include <string>
-
-#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<BasicModule> basic_module(new BasicModule("test_module"));
- scoped_ptr<FastModule> fast_module(new FastModule("test_module"));
-
- // Load symbol data into basic_module
- scoped_array<char> 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<char> 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<MemAddr, linked_ptr<BasicFunc> >::MapConstIterator iter1;
- StaticRangeMap<MemAddr, FastFunc>::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<MemAddr, linked_ptr<BasicPubSymbol> >::MapConstIterator iter1;
- StaticAddressMap<MemAddr, FastPubSymbol>::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<MemAddr, string>::MapConstIterator iter1;
- StaticRangeMap<MemAddr, char>::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<MemAddr, string>::const_iterator iter1;
- StaticMap<MemAddr, char>::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<MemAddr, linked_ptr<BasicLine> >::MapConstIterator iter1;
- StaticRangeMap<MemAddr, FastLine>::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<MemAddr, linked_ptr<WFI> >* basic_crm,
- const StaticContainedRangeMap<MemAddr, char>* 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<MemAddr, linked_ptr<WFI> >::MapConstIterator iter1;
- StaticContainedRangeMap<MemAddr, char>::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<MemAddr, char> *child =
- new StaticContainedRangeMap<MemAddr, char>(
- reinterpret_cast<const char*>(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 <string>
-
-#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<MemAddr, linked_ptr<WFI> >*,
- const StaticContainedRangeMap<MemAddr, char>*) 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 <map>
-#include <string>
-
-#include "processor/basic_code_module.h"
-#include "processor/logging.h"
-
-namespace google_breakpad {
-
-// Definition of static member variable in SimplerSerializer<Funcion>, which
-// is declared in file "simple_serializer-inl.h"
-RangeMapSerializer< MemAddr, linked_ptr<BasicSourceLineResolver::Line> >
-SimpleSerializer<BasicSourceLineResolver::Function>::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<bool>::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<char>::SizeOf(0);
-
- return total_size_alloc_;
-}
-
-char *ModuleSerializer::Write(const BasicSourceLineResolver::Module &module,
- char *dest) {
- // Write the is_corrupt flag.
- dest = SimpleSerializer<bool>::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<char>::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<unsigned int>(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<BasicSourceLineResolver::Module*>(iter->second);
-
- unsigned int size = 0;
- scoped_array<char> 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<CodeModule> 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<BasicSourceLineResolver::Module> module(
- new BasicSourceLineResolver::Module("no name"));
- scoped_array<char> 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 <map>
-#include <string>
-
-#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<int, string> files_serializer_;
- RangeMapSerializer<MemAddr, linked_ptr<Function> > functions_serializer_;
- AddressMapSerializer<MemAddr, linked_ptr<PublicSymbol> > pubsym_serializer_;
- ContainedRangeMapSerializer<MemAddr,
- linked_ptr<WindowsFrameInfo> > wfi_serializer_;
- RangeMapSerializer<MemAddr, string> cfi_init_rules_serializer_;
- StdMapSerializer<MemAddr, string> 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 <string>
-
-#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 <stdio.h>
-
-#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 <stdio.h>
-
-#include <sstream>
-
-#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<string> *stack) : stack_(stack) {}
- ~AutoStackClearer() { stack_->clear(); }
-
- private:
- vector<string> *stack_;
-};
-
-
-template<typename ValueType>
-bool PostfixEvaluator<ValueType>::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<ValueType>(-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<typename ValueType>
-bool PostfixEvaluator<ValueType>::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<typename ValueType>
-bool PostfixEvaluator<ValueType>::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<typename ValueType>
-bool PostfixEvaluator<ValueType>::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 ValueType>
-typename PostfixEvaluator<ValueType>::PopResult
-PostfixEvaluator<ValueType>::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<typename ValueType>
-bool PostfixEvaluator<ValueType>::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<typename ValueType>
-bool PostfixEvaluator<ValueType>::PopValues(ValueType *value1,
- ValueType *value2) {
- return PopValue(value2) && PopValue(value1);
-}
-
-
-template<typename ValueType>
-void PostfixEvaluator<ValueType>::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 <map>
-#include <string>
-#include <vector>
-
-#include "common/using_std_string.h"
-
-namespace google_breakpad {
-
-using std::map;
-using std::vector;
-
-class MemoryRegion;
-
-template<typename ValueType>
-class PostfixEvaluator {
- public:
- typedef map<string, ValueType> DictionaryType;
- typedef map<string, bool> 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<string> 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 <assert.h>
-#include <stdio.h>
-
-#include <map>
-#include <string>
-
-#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<unsigned int>::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<string, unsigned int> *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<unsigned int>::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<string, unsigned int> 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<unsigned int>::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<string, unsigned int> 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<unsigned int> postfix_evaluator =
- PostfixEvaluator<unsigned int>(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<unsigned int>::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<string, unsigned int>::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<string, unsigned int>::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<unsigned int>::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<unsigned int>::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<string, unsigned int> 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<string, unsigned int>::iterator v = validate_data_2.begin();
- v != validate_data_2.end(); v++) {
- map<string, unsigned int>::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<string, unsigned int>::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 <fcntl.h>
-#include <inttypes.h>
-#include <stdio.h>
-
-#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<MappedMemoryRegion>* regions_out) {
- std::vector<MappedMemoryRegion> 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<string> 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", &region.start, &region.end, permissions,
- &region.offset, &region.major_device, &region.minor_device,
- &region.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<google_breakpad::MappedMemoryRegion> regions;
- EXPECT_TRUE(ParseProcMaps("", &regions));
- 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<google_breakpad::MappedMemoryRegion> regions;
- ASSERT_TRUE(ParseProcMaps(kNoSpaces, &regions));
- 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<google_breakpad::MappedMemoryRegion> regions;
- ASSERT_TRUE(ParseProcMaps(kSpaces, &regions));
- 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<google_breakpad::MappedMemoryRegion> regions;
- ASSERT_FALSE(ParseProcMaps(kNoSpaces, &regions));
-}
-
-TEST(ProcMapsTest, NoPath) {
- static const char kNoPath[] =
- "00400000-0040b000 rw-p 00000000 00:00 0 \n";
-
- std::vector<google_breakpad::MappedMemoryRegion> regions;
- ASSERT_TRUE(ParseProcMaps(kNoPath, &regions));
- 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<google_breakpad::MappedMemoryRegion> regions;
- ASSERT_TRUE(ParseProcMaps(kHeap, &regions));
- 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<google_breakpad::MappedMemoryRegion> regions;
- ASSERT_TRUE(ParseProcMaps(kStack, &regions));
- 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<google_breakpad::MappedMemoryRegion> regions;
- ASSERT_TRUE(ParseProcMaps(kStack, &regions));
- 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<google_breakpad::MappedMemoryRegion> regions;
- ASSERT_TRUE(ParseProcMaps(kMultiple, &regions));
- 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<google_breakpad::MappedMemoryRegion> regions;
- EXPECT_TRUE(ParseProcMaps(kTestCases[i].input, &regions));
- 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<google_breakpad::MappedMemoryRegion> regions;
- EXPECT_FALSE(ParseProcMaps(kTestCases[i], &regions));
- }
-}
-
-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<google_breakpad::MappedMemoryRegion> regions;
- EXPECT_FALSE(ParseProcMaps(kTestCases[i], &regions));
- }
-}
-
-TEST(ProcMapsTest, ParseProcMapsEmptyString) {
- std::vector<google_breakpad::MappedMemoryRegion> regions;
- EXPECT_TRUE(ParseProcMaps("", &regions));
- 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<google_breakpad::MappedMemoryRegion> 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, &regions));
- 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<CallStack *>::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 <assert.h>
-
-#include "processor/range_map.h"
-#include "processor/linked_ptr.h"
-#include "processor/logging.h"
-
-
-namespace google_breakpad {
-
-template<typename AddressType, typename EntryType>
-void RangeMap<AddressType, EntryType>::SetEnableShrinkDown(
- bool enable_shrink_down) {
- enable_shrink_down_ = enable_shrink_down;
-}
-
-template<typename AddressType, typename EntryType>
-bool RangeMap<AddressType, EntryType>::IsShrinkDownEnabled() const {
- return enable_shrink_down_;
-}
-
-template<typename AddressType, typename EntryType>
-bool RangeMap<AddressType, EntryType>::StoreRange(const AddressType &base,
- const AddressType &size,
- const EntryType &entry) {
- return StoreRangeInternal(base, 0 /* delta */, size, entry);
-}
-
-template<typename AddressType, typename EntryType>
-bool RangeMap<AddressType, EntryType>::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<typename AddressType, typename EntryType>
-bool RangeMap<AddressType, EntryType>::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<typename AddressType, typename EntryType>
-bool RangeMap<AddressType, EntryType>::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<typename AddressType, typename EntryType>
-bool RangeMap<AddressType, EntryType>::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<typename AddressType, typename EntryType>
-int RangeMap<AddressType, EntryType>::GetCount() const {
- return map_.size();
-}
-
-
-template<typename AddressType, typename EntryType>
-void RangeMap<AddressType, EntryType>::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 <map>
-
-
-namespace google_breakpad {
-
-// Forward declarations (for later friend declarations of specialized template).
-template<class, class> class RangeMapSerializer;
-
-template<typename AddressType, typename EntryType>
-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<AddressType, EntryType>;
-
- // 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<AddressType, Range> 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 <limits.h>
-#include <stdio.h>
-
-#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<AddressType, linked_ptr<CountedObject>> TestMap;
-
-// Same range cannot be stored wice.
-TEST(RangeMap, TestShinkDown_SameRange) {
- TestMap range_map;
- range_map.SetEnableShrinkDown(true);
- linked_ptr<CountedObject> 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<CountedObject> 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<CountedObject> 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<CountedObject> object_2(new CountedObject(2));
- EXPECT_TRUE(range_map.StoreRange(10 /* base address */, 80 /* size */,
- object_2));
- linked_ptr<CountedObject> 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<CountedObject> object_1(new CountedObject(1));
- EXPECT_TRUE(range_map.StoreRange(10 /* base address */, 80 /* size */,
- object_1));
- // Larger range is added second.
- linked_ptr<CountedObject> object_2(new CountedObject(2));
- EXPECT_TRUE(range_map.StoreRange(0 /* base address */, 100 /* size */,
- object_2));
- linked_ptr<CountedObject> 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<CountedObject> 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<CountedObject> object_2(new CountedObject(2));
- EXPECT_TRUE(range_map.StoreRange(90 /* base address */, 110 /* size */,
- object_2));
-
- linked_ptr<CountedObject> 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<CountedObject> 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<CountedObject> object_2(new CountedObject(2));
- EXPECT_TRUE(range_map.StoreRange(0 /* base address */, 70 /* size */,
- object_2));
-
- linked_ptr<CountedObject> 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<CountedObject> 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<CountedObject> 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<CountedObject> object_3(new CountedObject(3));
- EXPECT_TRUE(range_map.StoreRange(50 /* base address */, 100 /* size */,
- object_3));
-
- linked_ptr<CountedObject> 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<CountedObject> 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<CountedObject> 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<CountedObject> object_3(new CountedObject(3));
- EXPECT_TRUE(range_map.StoreRange(0 /* base address */, 300 /* size */,
- object_3));
-
- linked_ptr<CountedObject> 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<CountedObject> 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<CountedObject> object_2(new CountedObject(2));
- EXPECT_TRUE(range_map.StoreRange(110 /* base address */, 90 /* size */,
- object_2));
-
- linked_ptr<CountedObject> 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 <limits.h>
-#include <stdio.h>
-
-#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<CountedObject> > 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<CountedObject> 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<CountedObject> 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<CountedObject> 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<CountedObject> 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<TestMap> 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<CountedObject> object(new CountedObject(object_id));
- int base_address = 2 * object_id;
- range_map->StoreRange(base_address, range_size, object);
- }
-
- linked_ptr<CountedObject> 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<TestMap> 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 <string>
-
-#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<bool> {
- public:
- static size_t SizeOf(bool boolean) { return 1; }
-
- static char *Write(bool boolean, char *dest) {
- *dest = static_cast<char>(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<string> {
- 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<const char*> {
- 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<BasicSourceLineResolver::Line> {
- typedef BasicSourceLineResolver::Line Line;
- public:
- static size_t SizeOf(const Line &line) {
- return SimpleSerializer<MemAddr>::SizeOf(line.address)
- + SimpleSerializer<MemAddr>::SizeOf(line.size)
- + SimpleSerializer<int32_t>::SizeOf(line.source_file_id)
- + SimpleSerializer<int32_t>::SizeOf(line.line);
- }
- static char *Write(const Line &line, char *dest) {
- dest = SimpleSerializer<MemAddr>::Write(line.address, dest);
- dest = SimpleSerializer<MemAddr>::Write(line.size, dest);
- dest = SimpleSerializer<int32_t>::Write(line.source_file_id, dest);
- dest = SimpleSerializer<int32_t>::Write(line.line, dest);
- return dest;
- }
-};
-
-// Specializations of SimpleSerializer: PublicSymbol
-template<>
-class SimpleSerializer<BasicSourceLineResolver::PublicSymbol> {
- typedef BasicSourceLineResolver::PublicSymbol PublicSymbol;
- public:
- static size_t SizeOf(const PublicSymbol &pubsymbol) {
- return SimpleSerializer<string>::SizeOf(pubsymbol.name)
- + SimpleSerializer<MemAddr>::SizeOf(pubsymbol.address)
- + SimpleSerializer<int32_t>::SizeOf(pubsymbol.parameter_size);
- }
- static char *Write(const PublicSymbol &pubsymbol, char *dest) {
- dest = SimpleSerializer<string>::Write(pubsymbol.name, dest);
- dest = SimpleSerializer<MemAddr>::Write(pubsymbol.address, dest);
- dest = SimpleSerializer<int32_t>::Write(pubsymbol.parameter_size, dest);
- return dest;
- }
-};
-
-// Specializations of SimpleSerializer: WindowsFrameInfo
-template<>
-class SimpleSerializer<WindowsFrameInfo> {
- public:
- static size_t SizeOf(const WindowsFrameInfo &wfi) {
- unsigned int size = 0;
- size += sizeof(int32_t); // wfi.type_
- size += SimpleSerializer<int32_t>::SizeOf(wfi.valid);
- size += SimpleSerializer<uint32_t>::SizeOf(wfi.prolog_size);
- size += SimpleSerializer<uint32_t>::SizeOf(wfi.epilog_size);
- size += SimpleSerializer<uint32_t>::SizeOf(wfi.parameter_size);
- size += SimpleSerializer<uint32_t>::SizeOf(wfi.saved_register_size);
- size += SimpleSerializer<uint32_t>::SizeOf(wfi.local_size);
- size += SimpleSerializer<uint32_t>::SizeOf(wfi.max_stack_size);
- size += SimpleSerializer<bool>::SizeOf(wfi.allocates_base_pointer);
- size += SimpleSerializer<string>::SizeOf(wfi.program_string);
- return size;
- }
- static char *Write(const WindowsFrameInfo &wfi, char *dest) {
- dest = SimpleSerializer<int32_t>::Write(
- static_cast<const int32_t>(wfi.type_), dest);
- dest = SimpleSerializer<int32_t>::Write(wfi.valid, dest);
- dest = SimpleSerializer<uint32_t>::Write(wfi.prolog_size, dest);
- dest = SimpleSerializer<uint32_t>::Write(wfi.epilog_size, dest);
- dest = SimpleSerializer<uint32_t>::Write(wfi.parameter_size, dest);
- dest = SimpleSerializer<uint32_t>::Write(wfi.saved_register_size, dest);
- dest = SimpleSerializer<uint32_t>::Write(wfi.local_size, dest);
- dest = SimpleSerializer<uint32_t>::Write(wfi.max_stack_size, dest);
- dest = SimpleSerializer<bool>::Write(wfi.allocates_base_pointer, dest);
- return SimpleSerializer<string>::Write(wfi.program_string, dest);
- }
-};
-
-// Specializations of SimpleSerializer: Linked_ptr version of
-// Line, Function, PublicSymbol, WindowsFrameInfo.
-template<>
-class SimpleSerializer< linked_ptr<BasicSourceLineResolver::Line> > {
- typedef BasicSourceLineResolver::Line Line;
- public:
- static size_t SizeOf(const linked_ptr<Line> &lineptr) {
- if (lineptr.get() == NULL) return 0;
- return SimpleSerializer<Line>::SizeOf(*(lineptr.get()));
- }
- static char *Write(const linked_ptr<Line> &lineptr, char *dest) {
- if (lineptr.get())
- dest = SimpleSerializer<Line>::Write(*(lineptr.get()), dest);
- return dest;
- }
-};
-
-template<>
-class SimpleSerializer<BasicSourceLineResolver::Function> {
- // 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<string>::SizeOf(func.name);
- size += SimpleSerializer<MemAddr>::SizeOf(func.address);
- size += SimpleSerializer<MemAddr>::SizeOf(func.size);
- size += SimpleSerializer<int32_t>::SizeOf(func.parameter_size);
- size += range_map_serializer_.SizeOf(func.lines);
- return size;
- }
-
- static char *Write(const Function &func, char *dest) {
- dest = SimpleSerializer<string>::Write(func.name, dest);
- dest = SimpleSerializer<MemAddr>::Write(func.address, dest);
- dest = SimpleSerializer<MemAddr>::Write(func.size, dest);
- dest = SimpleSerializer<int32_t>::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<Line> > range_map_serializer_;
-};
-
-template<>
-class SimpleSerializer< linked_ptr<BasicSourceLineResolver::Function> > {
- typedef BasicSourceLineResolver::Function Function;
- public:
- static size_t SizeOf(const linked_ptr<Function> &func) {
- if (!func.get()) return 0;
- return SimpleSerializer<Function>::SizeOf(*(func.get()));
- }
-
- static char *Write(const linked_ptr<Function> &func, char *dest) {
- if (func.get())
- dest = SimpleSerializer<Function>::Write(*(func.get()), dest);
- return dest;
- }
-};
-
-template<>
-class SimpleSerializer< linked_ptr<BasicSourceLineResolver::PublicSymbol> > {
- typedef BasicSourceLineResolver::PublicSymbol PublicSymbol;
- public:
- static size_t SizeOf(const linked_ptr<PublicSymbol> &pubsymbol) {
- if (pubsymbol.get() == NULL) return 0;
- return SimpleSerializer<PublicSymbol>::SizeOf(*(pubsymbol.get()));
- }
- static char *Write(const linked_ptr<PublicSymbol> &pubsymbol, char *dest) {
- if (pubsymbol.get())
- dest = SimpleSerializer<PublicSymbol>::Write(*(pubsymbol.get()), dest);
- return dest;
- }
-};
-
-template<>
-class SimpleSerializer< linked_ptr<WindowsFrameInfo> > {
- public:
- static size_t SizeOf(const linked_ptr<WindowsFrameInfo> &wfi) {
- if (wfi.get() == NULL) return 0;
- return SimpleSerializer<WindowsFrameInfo>::SizeOf(*(wfi.get()));
- }
- static char *Write(const linked_ptr<WindowsFrameInfo> &wfi, char *dest) {
- if (wfi.get())
- dest = SimpleSerializer<WindowsFrameInfo>::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 Type> 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 <assert.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <algorithm>
-#include <iostream>
-#include <fstream>
-
-#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<string, char *>::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 <map>
-#include <string>
-#include <vector>
-
-#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<string> &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<string, char *> memory_buffers_;
- vector<string> 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 <stdio.h>
-#include <string.h>
-#include <sys/stat.h>
-
-#include <map>
-#include <utility>
-
-#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 <stdio.h>
-
-#include <map>
-#include <string>
-
-#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 <assert.h>
-
-#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 <assert.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <string>
-#include <vector>
-
-#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<ssize_t>(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<ssize_t>(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<const StackFrameX86*>(frame);
- const StackFrameX86 *prev_frame_x86 =
- static_cast<const StackFrameX86*>(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<const StackFrameAMD64*>(frame);
- const StackFrameAMD64 *prev_frame_amd64 =
- static_cast<const StackFrameAMD64*>(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<const StackFrameARM*>(frame);
- const StackFrameARM *prev_frame_arm =
- static_cast<const StackFrameARM*>(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<const StackFrameARM64*>(frame);
- const StackFrameARM64 *prev_frame_arm64 =
- static_cast<const StackFrameARM64*>(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<uint32_t>(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<uint32_t>(address),
- static_cast<uint32_t>(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(" <no frames>\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<const StackFrameX86*>(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<const StackFramePPC*>(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<const StackFrameAMD64*>(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<const StackFrameSPARC*>(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<const StackFrameARM*>(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<const StackFrameARM64*>(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<const StackFrameMIPS*>(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<const CodeModule*> *modules,
- const CodeModule *module) {
- assert(modules);
- assert(module);
- vector<const CodeModule*>::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<const CodeModule*> *modules_without_symbols,
- const vector<const CodeModule*> *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<const CodeModule*> *modules_without_symbols,
- const vector<const CodeModule*> *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 <assert.h>
-
-#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<const CodeModule*>* modules) {
- if (!module) {
- return;
- }
- assert(symbolizer_result == StackFrameSymbolizer::kError ||
- symbolizer_result == StackFrameSymbolizer::kWarningCorruptSymbols);
- bool found = false;
- vector<const CodeModule*>::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<const CodeModule*>* modules_without_symbols,
- vector<const CodeModule*>* 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<StackFrame> 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 <chrisha@chromium.org>
-
-#include <assert.h>
-
-#include <vector>
-
-#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 <chrisha@chromium.org>
-
-#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 <chrisha@chromium.org>
-
-#include <string>
-#include <vector>
-
-#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<StackFrame*>* 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<const CodeModule*>(&module2), frames->at(0)->module);
- ASSERT_EQ(static_cast<const CodeModule*>(&module2), frames->at(1)->module);
- ASSERT_EQ(static_cast<const CodeModule*>(&module2), frames->at(2)->module);
- ASSERT_EQ(static_cast<const CodeModule*>(&module1), frames->at(3)->module);
- ASSERT_EQ(static_cast<const CodeModule*>(&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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrame*>* 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 <assert.h>
-
-#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<StackFrame*> &frames,
- CFIFrameInfo* cfi_frame_info) {
- StackFrameAMD64* last_frame = static_cast<StackFrameAMD64*>(frames.back());
-
- scoped_ptr<StackFrameAMD64> 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<StackFrame*>& frames) {
- StackFrameAMD64* last_frame = static_cast<StackFrameAMD64*>(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<StackFrame*> &frames) {
- StackFrameAMD64* last_frame = static_cast<StackFrameAMD64*>(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<StackFrame*> &frames = *stack->frames();
- StackFrameAMD64* last_frame = static_cast<StackFrameAMD64*>(frames.back());
- scoped_ptr<StackFrameAMD64> new_frame;
-
- // If we have DWARF CFI information, use it.
- scoped_ptr<CFIFrameInfo> 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<uint32_t>(new_frame->context.rip);
- new_frame->context.rsp = static_cast<uint32_t>(new_frame->context.rsp);
- new_frame->context.rbp = static_cast<uint32_t>(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 <vector>
-
-#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<uint64_t, MDRawContextAMD64> 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<StackFrame*> &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<StackFrame*>& frames);
-
- // Scan the stack for plausible return addresses. The caller takes ownership
- // of the returned frame. Return NULL on failure.
- StackFrameAMD64* GetCallerByStackScan(const vector<StackFrame*> &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 <jimb@mozilla.com> <jimb@red-bean.com>
-
-// stackwalker_amd64_unittest.cc: Unit tests for StackwalkerAMD64 class.
-
-#include <string.h>
-#include <string>
-#include <vector>
-
-#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<uint8_t *>(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<StackFrame *> *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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameAMD64 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameAMD64 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameAMD64 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameAMD64 *>(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<StackFrameAMD64 *>(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<StackFrameAMD64 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameAMD64 *>(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<StackFrameAMD64 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameAMD64 *>(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<StackFrameAMD64 *>(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<StackFrameAMD64 *>(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(&not_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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameAMD64 *>(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<StackFrameAMD64 *>(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(&not_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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameAMD64 *>(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<StackFrameAMD64 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameAMD64 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameAMD64 *>(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<StackFrameAMD64 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameAMD64 *>(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<StackFrameAMD64 *>(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 <vector>
-
-#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<StackFrame*> &frames,
- CFIFrameInfo* cfi_frame_info) {
- StackFrameARM* last_frame = static_cast<StackFrameARM*>(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<uint32_t> 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<uint32_t> 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<StackFrameARM> frame(new StackFrameARM());
- for (int i = 0; register_names[i]; i++) {
- CFIFrameInfo::RegisterValueMap<uint32_t>::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<uint32_t>::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<uint32_t>::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<StackFrame*> &frames) {
- StackFrameARM* last_frame = static_cast<StackFrameARM*>(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<StackFrame*> &frames) {
- StackFrameARM* last_frame = static_cast<StackFrameARM*>(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<StackFrame*> &frames = *stack->frames();
- StackFrameARM* last_frame = static_cast<StackFrameARM*>(frames.back());
- scoped_ptr<StackFrameARM> frame;
-
- // See if there is DWARF call frame information covering this address.
- scoped_ptr<CFIFrameInfo> 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<StackFrame*> &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<StackFrame*> &frames);
-
- // Scan the stack for plausible return addresses. The caller takes ownership
- // of the returned frame. Return NULL on failure.
- StackFrameARM* GetCallerByStackScan(const vector<StackFrame*> &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 <vector>
-
-#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<StackFrame*> &frames,
- CFIFrameInfo* cfi_frame_info) {
- StackFrameARM64* last_frame = static_cast<StackFrameARM64*>(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<uint64_t> 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<uint64_t> 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<StackFrameARM64> frame(new StackFrameARM64());
- for (int i = 0; register_names[i]; i++) {
- CFIFrameInfo::RegisterValueMap<uint64_t>::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<uint64_t>::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<uint64_t>::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<StackFrame*> &frames) {
- StackFrameARM64* last_frame = static_cast<StackFrameARM64*>(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<StackFrame*> &frames) {
- StackFrameARM64* last_frame = static_cast<StackFrameARM64*>(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<StackFrame*> &frames = *stack->frames();
- StackFrameARM64* last_frame = static_cast<StackFrameARM64*>(frames.back());
- scoped_ptr<StackFrameARM64> frame;
-
- // See if there is DWARF call frame information covering this address.
- scoped_ptr<CFIFrameInfo> 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<StackFrame*> &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<StackFrame*> &frames);
-
- // Scan the stack for plausible return addresses. The caller takes ownership
- // of the returned frame. Return NULL on failure.
- StackFrameARM64* GetCallerByStackScan(const vector<StackFrame*> &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 <jimb@mozilla.com> <jimb@red-bean.com>
-
-// stackwalker_arm64_unittest.cc: Unit tests for StackwalkerARM64 class.
-
-#include <string.h>
-#include <string>
-#include <vector>
-
-#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<uint8_t *>(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<StackFrame *> *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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameARM64 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameARM64 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameARM64 *>(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<StackFrameARM64 *>(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<StackFrameARM64 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameARM64 *>(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<StackFrameARM64 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameARM64 *>(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<StackFrameARM64 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameARM64 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameARM64 *>(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<StackFrameARM64 *>(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<StackFrameARM64 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameARM64 *>(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<StackFrameARM64 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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 <jimb@mozilla.com> <jimb@red-bean.com>
-
-// stackwalker_arm_unittest.cc: Unit tests for StackwalkerARM class.
-
-#include <string.h>
-#include <string>
-#include <vector>
-
-#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<uint8_t *>(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<StackFrame *> *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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameARM *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameARM *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameARM *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameARM *>(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<StackFrameARM *>(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<StackFrameARM *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameARM *>(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<StackFrameARM *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameARM *>(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<StackFrameARM *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameARM *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameARM *>(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<StackFrameARM *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameARM *>(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<StackFrameARM *>(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<StackFrameARM *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameARM *>(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<StackFrameARM *>(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<StackFrameARM *>(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<StackFrame*>& frames,
- CFIFrameInfo* cfi_frame_info) {
- StackFrameMIPS* last_frame = static_cast<StackFrameMIPS*>(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<uint32_t> callee_registers;
- // Use the STACK CFI data to recover the caller's register values.
- CFIFrameInfo::RegisterValueMap<uint32_t> 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<uint32_t>::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<StackFrameMIPS> frame(new StackFrameMIPS());
-
- for (int i = 0; kRegisterNames[i]; ++i) {
- CFIFrameInfo::RegisterValueMap<uint32_t>::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<uint64_t> callee_registers;
- // Use the STACK CFI data to recover the caller's register values.
- CFIFrameInfo::RegisterValueMap<uint64_t> 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<uint64_t>::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<StackFrameMIPS> frame(new StackFrameMIPS());
-
- for (int i = 0; kRegisterNames[i]; ++i) {
- CFIFrameInfo::RegisterValueMap<uint64_t>::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<StackFrame*>& frames = *stack->frames();
- StackFrameMIPS* last_frame = static_cast<StackFrameMIPS*>(frames.back());
- scoped_ptr<StackFrameMIPS> new_frame;
-
- // See if there is DWARF call frame information covering this address.
- scoped_ptr<CFIFrameInfo> 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<StackFrame*>& frames) {
- const uint32_t kMaxFrameStackSize = 1024;
- const uint32_t kMinArgsOnStack = 4;
-
- StackFrameMIPS* last_frame = static_cast<StackFrameMIPS*>(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<StackFrame*>& 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<StackFrame*>& 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 <gordana.cmiljanovic@imgtec.com>
-
-// stackwalker_mips_unittest.cc: Unit tests for StackwalkerMIPS class.
-
-#include <string.h>
-#include <string>
-#include <vector>
-
-#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<uint8_t*>(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<StackFrame*>* 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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameMIPS*>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameMIPS*>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameMIPS*>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameMIPS*>(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<StackFrameMIPS*>(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<StackFrameMIPS*>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameMIPS*>(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<StackFrameMIPS*>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameMIPS*>(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<StackFrameMIPS*>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameMIPS*>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameMIPS*>(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<StackFrameMIPS*>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFramePPC*>(
- 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 <stdio.h>
-
-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<StackFramePPC64*>(
- 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 <assert.h>
-
-#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 <stdio.h>
-
-#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<typename T> 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<const T*>(&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<const CodeModule*> 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<StackFrameX86*>(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<StackFramePPC*>(frame);
- printf(" gpr[1] = 0x%08x\n", frame_ppc->context.gpr[1]);
-#elif defined(__sparc__)
- StackFrameSPARC *frame_sparc = reinterpret_cast<StackFrameSPARC*>(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 <sys/asm_linkage.h>
-
-#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<StackFrameSPARC*>(
- 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 <jimb@mozilla.com> <jimb@red-bean.com>
-
-// Mock classes for writing stackwalker tests, shared amongst architectures.
-
-#ifndef PROCESSOR_STACKWALKER_UNITTEST_UTILS_H_
-#define PROCESSOR_STACKWALKER_UNITTEST_UTILS_H_
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string>
-#include <vector>
-
-#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<typename ValueType>
- 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<unsigned char>(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<google_breakpad::linked_ptr<const CodeModule> >
- GetShrunkRangeModules() const {
- return std::vector<google_breakpad::linked_ptr<const CodeModule> >();
- }
-
- // Returns true, if module address range shrink is enabled.
- bool IsModuleShrinkEnabled() const {
- return false;
- }
-
- private:
- typedef std::vector<const MockCodeModule *> 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<char*> 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 <assert.h>
-#include <string>
-
-#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<StackFrame*> &frames,
- WindowsFrameInfo* last_frame_info,
- bool stack_scan_allowed) {
- StackFrame::FrameTrust trust = StackFrame::FRAME_TRUST_NONE;
-
- StackFrameX86* last_frame = static_cast<StackFrameX86*>(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<StackFrameX86*>(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<uint32_t>::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<uint32_t> evaluator =
- PostfixEvaluator<uint32_t>(&dictionary, memory_);
- PostfixEvaluator<uint32_t>::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<StackFrame*> &frames,
- CFIFrameInfo* cfi_frame_info) {
- StackFrameX86* last_frame = static_cast<StackFrameX86*>(frames.back());
- last_frame->cfi_frame_info = cfi_frame_info;
-
- scoped_ptr<StackFrameX86> 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<StackFrame*> &frames,
- bool stack_scan_allowed) {
- StackFrame::FrameTrust trust;
- StackFrameX86* last_frame = static_cast<StackFrameX86*>(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<StackFrame*> &frames = *stack->frames();
- StackFrameX86* last_frame = static_cast<StackFrameX86*>(frames.back());
- scoped_ptr<StackFrameX86> 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 <vector>
-
-#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<uint32_t, MDRawContextX86> 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<StackFrame*> &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<StackFrame*> &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<StackFrame*> &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 <jimb@mozilla.com> <jimb@red-bean.com>
-
-// stackwalker_x86_unittest.cc: Unit tests for StackwalkerX86 class.
-
-#include <string>
-#include <vector>
-
-#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<uint8_t *>(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<StackFrame *> *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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameX86 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameX86 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameX86 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameX86 *>(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<StackFrameX86 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameX86 *>(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<StackFrameX86 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameX86 *>(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<StackFrameX86 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameX86 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameX86 *>(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<StackFrameX86 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameX86 *>(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<StackFrameX86 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameX86 *>(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<StackFrameX86 *>(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<StackFrameX86 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameX86 *>(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<StackFrameX86 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameX86 *>(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<StackFrameX86 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameX86 *>(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<StackFrameX86 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameX86 *>(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<StackFrameX86 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameX86 *>(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<StackFrameX86 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameX86 *>(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<StackFrameX86 *>(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<StackFrameX86 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameX86 *>(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<StackFrameX86 *>(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<StackFrameX86 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameX86 *>(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<StackFrameX86 *>(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<StackFrameX86 *>(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<StackFrameX86 *>(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<const CodeModule*> modules_without_symbols;
- vector<const CodeModule*> 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<StackFrameX86 *>(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<StackFrameX86 *>(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<typename AddressType, typename EntryType>
-bool StaticAddressMap<AddressType, EntryType>::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<typename AddressType, typename EntryType>
-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<AddressType, EntryType> 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 <climits>
-#include <cstdlib>
-#include <ctime>
-#include <string>
-#include <iostream>
-#include <sstream>
-
-#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<int, char> TestMap;
-typedef google_breakpad::AddressMap<int, string> 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<int, string> 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<typename AddressType, typename EntryType>
-StaticContainedRangeMap<AddressType, EntryType>::StaticContainedRangeMap(
- const char *base)
- : base_(*(reinterpret_cast<const AddressType*>(base))),
- entry_size_(*(reinterpret_cast<const uint32_t*>(base + sizeof(base_)))),
- entry_ptr_(reinterpret_cast<const EntryType *>(
- base + sizeof(base_) + sizeof(entry_size_))),
- map_(base + sizeof(base_) + sizeof(entry_size_) + entry_size_) {
- if (entry_size_ == 0)
- entry_ptr_ = NULL;
-}
-
-
-template<typename AddressType, typename EntryType>
-bool StaticContainedRangeMap<AddressType, EntryType>::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<const char*>(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<typename AddressType, typename EntryType>
-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<AddressType, StaticContainedRangeMap> 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<unsigned int, int> CRMMap;
-typedef google_breakpad::StaticContainedRangeMap<unsigned int, int> 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<unsigned int, int> 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<unsigned int, int> test_map_;
-
- google_breakpad::ContainedRangeMapSerializer<unsigned int, int> serializer_;
-
- scoped_array<char> 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<char> serialized_data;
- serialized_data.reset(serializer_.Serialize(&empty_crm_map, &size));
- scoped_ptr<TestMap> 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<char> serialized_data;
- serialized_data.reset(serializer_.Serialize(&crm_map, &size));
- scoped_ptr<TestMap> 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<typename Key, typename Value, typename Compare>
-StaticMap<Key, Value, Compare>::StaticMap(const char* raw_data)
- : raw_data_(raw_data),
- compare_() {
- // First 4 Bytes store the number of nodes.
- num_nodes_ = *(reinterpret_cast<const uint32_t*>(raw_data_));
-
- offsets_ = reinterpret_cast<const uint32_t*>(
- raw_data_ + sizeof(num_nodes_));
-
- keys_ = reinterpret_cast<const Key*>(
- raw_data_ + (1 + num_nodes_) * sizeof(uint32_t));
-}
-
-// find(), lower_bound() and upper_bound() implement binary search algorithm.
-template<typename Key, typename Value, typename Compare>
-StaticMapIterator<Key, Value, Compare>
-StaticMap<Key, Value, Compare>::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<typename Key, typename Value, typename Compare>
-StaticMapIterator<Key, Value, Compare>
-StaticMap<Key, Value, Compare>::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<typename Key, typename Value, typename Compare>
-StaticMapIterator<Key, Value, Compare>
-StaticMap<Key, Value, Compare>::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<typename Key, typename Value, typename Compare>
-bool StaticMap<Key, Value, Compare>::ValidateInMemoryStructure() const {
- // check the number of nodes is non-negative:
- if (!raw_data_) return false;
- int32_t num_nodes = *(reinterpret_cast<const int32_t*>(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<uint32_t>(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<typename Key, typename Value, typename Compare>
-const Key StaticMap<Key, Value, Compare>::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<typename Key>
-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<typename Key, typename Value, typename Compare = DefaultCompare<Key> >
-class StaticMap {
- public:
- typedef StaticMapIterator<Key, Value, Compare> iterator;
- typedef StaticMapIterator<Key, Value, Compare> 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<typename Key, typename Value, typename Compare>
-StaticMapIterator<Key, Value, Compare>::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<const int32_t*>(base_));
- offsets_ = reinterpret_cast<const uint32_t*>(base_ + sizeof(num_nodes_));
- keys_ = reinterpret_cast<const Key*>(
- base_ + (1 + num_nodes_) * sizeof(num_nodes_));
-}
-
-// Increment & Decrement operators:
-template<typename Key, typename Value, typename Compare>
-StaticMapIterator<Key, Value, Compare>&
-StaticMapIterator<Key, Value, Compare>::operator++() {
- if (!IsValid()) {
- BPLOG(ERROR) << "operator++ on invalid iterator";
- return *this;
- }
- if (++index_ > num_nodes_) index_ = num_nodes_;
- return *this;
-}
-
-template<typename Key, typename Value, typename Compare>
-StaticMapIterator<Key, Value, Compare>
-StaticMapIterator<Key, Value, Compare>::operator++(int postfix_operator) {
- if (!IsValid()) {
- BPLOG(ERROR) << "operator++ on invalid iterator";
- return *this;
- }
- StaticMapIterator<Key, Value, Compare> tmp = *this;
- if (++index_ > num_nodes_) index_ = num_nodes_;
- return tmp;
-}
-
-template<typename Key, typename Value, typename Compare>
-StaticMapIterator<Key, Value, Compare>&
-StaticMapIterator<Key, Value, Compare>::operator--() {
- if (!IsValid()) {
- BPLOG(ERROR) << "operator++ on invalid iterator";
- return *this;
- }
-
- if (--index_ < 0) index_ = 0;
- return *this;
-}
-
-template<typename Key, typename Value, typename Compare>
-StaticMapIterator<Key, Value, Compare>
-StaticMapIterator<Key, Value, Compare>::operator--(int postfix_operator) {
- if (!IsValid()) {
- BPLOG(ERROR) << "operator++ on invalid iterator";
- return *this;
- }
- StaticMapIterator<Key, Value, Compare> tmp = *this;
-
- if (--index_ < 0) index_ = 0;
- return tmp;
-}
-
-template<typename Key, typename Value, typename Compare>
-const Key* StaticMapIterator<Key, Value, Compare>::GetKeyPtr() const {
- if (!IsValid()) {
- BPLOG(ERROR) << "call GetKeyPtr() on invalid iterator";
- return NULL;
- }
- return &(keys_[index_]);
-}
-
-template<typename Key, typename Value, typename Compare>
-const char* StaticMapIterator<Key, Value, Compare>::GetValueRawPtr() const {
- if (!IsValid()) {
- BPLOG(ERROR) << "call GetValuePtr() on invalid iterator";
- return NULL;
- }
- return base_ + offsets_[index_];
-}
-
-template<typename Key, typename Value, typename Compare>
-bool StaticMapIterator<Key, Value, Compare>::operator==(
- const StaticMapIterator<Key, Value, Compare>& x) const {
- return base_ == x.base_ && index_ == x.index_;
-}
-
-template<typename Key, typename Value, typename Compare>
-bool StaticMapIterator<Key, Value, Compare>::operator!=(
- const StaticMapIterator<Key, Value, Compare>& x) const {
- // Only need to compare base_ and index_.
- // Other data members are auxiliary.
- return base_ != x.base_ || index_ != x.index_;
-}
-
-template<typename Key, typename Value, typename Compare>
-bool StaticMapIterator<Key, Value, Compare>::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<typename Key, typename Value, typename Compare> class StaticMap;
-
-// StaticMapIterator does not support operator*() or operator->(),
-// User should use GetKey(), GetKeyPtr(), GetValuePtr() instead;
-template<typename Key, typename Value, typename Compare>
-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<const Value*>(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<Key, Value, Compare>;
-
- // 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 <climits>
-#include <map>
-
-#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<typename Key, typename Value>
-class SimpleMapSerializer {
- public:
- static char* Serialize(const std::map<Key, Value> &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<char*>(operator new(memsize));
- char* address = mem;
-
- // Writer the number of nodes:
- new (address) uint32_t(static_cast<uint32_t>(stdmap.size()));
- address += sizeof(uint32_t);
-
- // Nodes' offset:
- uint32_t* offsets = reinterpret_cast<uint32_t*>(address);
- address += sizeof(uint32_t) * stdmap.size();
-
- // Keys:
- Key* keys = reinterpret_cast<Key*>(address);
- address += sizeof(Key) * stdmap.size();
-
- // Traversing map:
- typename std::map<Key, Value>::const_iterator iter = stdmap.begin();
- for (int index = 0; iter != stdmap.end(); ++iter, ++index) {
- offsets[index] = static_cast<unsigned int>(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<uint32_t*>(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<uint32_t*>(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<KeyType*>(
- 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<KeyType, ValueType> 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<typename AddressType, typename EntryType>
-bool StaticRangeMap<AddressType, EntryType>::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<typename AddressType, typename EntryType>
-bool StaticRangeMap<AddressType, EntryType>::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<typename AddressType, typename EntryType>
-bool StaticRangeMap<AddressType, EntryType>::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<typename AddressType, typename EntryType>
-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<const AddressType*>(this));
- }
- const EntryType* entryptr() const {
- return reinterpret_cast<const EntryType*>(this + sizeof(AddressType));
- }
- };
-
- // Convenience types.
- typedef StaticRangeMap* SelfPtr;
- typedef StaticMap<AddressType, Range> 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<AddressType, EntryType> 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> 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<char> memaddr(serializer_.Serialize(*rmap, NULL));
- scoped_ptr<TestMap> 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 <string>
-
-#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 <string>
-
-#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 <jimb@mozilla.com> <jimb@red-bean.com>
-
-// 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<SynthMinidump::Section *>(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<SynthMinidump::Section *>(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<test_assembler::Section &>(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 <jimb@mozilla.com> <jimb@red-bean.com>
-
-// 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 <assert.h>
-
-#include <iostream>
-#include <string>
-
-#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<typename Element>
-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> thread_list_;
-
- // This minidump's module list. We construct this incrementally from
- // Add(Module *) calls.
- List<Module> 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<SynthMinidump::Section> 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 <jimb@mozilla.com> <jimb@red-bean.com>
-
-// synth_minidump_unittest.cc: Unit tests for google_breakpad::SynthMinidump
-// classes.
-
-#include <sstream>
-#include <string>
-
-#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(&section1);
- 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(&section);
- 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(&section);
- 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(&section);
- 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<Section> 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<Section> list(dump, 0x26c9f498);
- Section section1(dump);
- section1.Append("section one contents");
- EXPECT_TRUE(list.Empty());
- list.Add(&section1);
- EXPECT_FALSE(list.Empty());
- Section section2(dump);
- section2.Append("section two contents");
- list.Add(&section2);
- 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(&section);
- 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 <string.h>
-
-#include <string>
-#include <vector>
-
-#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<char*> *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<unsigned int>(max_tokens);
-}
-
-void StringToVector(const string &str, vector<char> &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 <string>
-#include <vector>
-
-#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<char*> *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<char> &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 <string.h>
-#include <stdlib.h>
-
-#include <string>
-#include <vector>
-
-#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<char> buffer;
- StringToVector(string, buffer);
- std::vector<char*> 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<StackInfoTypes>(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__