summaryrefslogtreecommitdiffstats
path: root/toolkit/crashreporter/google-breakpad/src/processor/postfix_evaluator_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/crashreporter/google-breakpad/src/processor/postfix_evaluator_unittest.cc')
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/postfix_evaluator_unittest.cc403
1 files changed, 0 insertions, 403 deletions
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;
-}