15f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// Copyright (c) 2013, Google Inc.
25f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// All rights reserved.
35f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com//
45f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// Redistribution and use in source and binary forms, with or without
55f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// modification, are permitted provided that the following conditions are
65f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// met:
75f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com//
85f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com//     * Redistributions of source code must retain the above copyright
95f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// notice, this list of conditions and the following disclaimer.
105f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com//     * Redistributions in binary form must reproduce the above
115f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// copyright notice, this list of conditions and the following disclaimer
125f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// in the documentation and/or other materials provided with the
135f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// distribution.
145f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com//     * Neither the name of Google Inc. nor the names of its
155f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// contributors may be used to endorse or promote products derived from
165f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// this software without specific prior written permission.
175f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com//
185f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
195f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
205f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
215f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
225f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
235f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
245f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
255f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
265f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
275f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
285f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
295f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
305f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// Original author: Gordana Cmiljanovic <gordana.cmiljanovic@imgtec.com>
315f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
325f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// stackwalker_mips_unittest.cc: Unit tests for StackwalkerMIPS class.
335f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
345f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com#include <string.h>
355f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com#include <string>
365f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com#include <vector>
375f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
385f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com#include "breakpad_googletest_includes.h"
395f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com#include "common/test_assembler.h"
405f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com#include "common/using_std_string.h"
415f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com#include "google_breakpad/common/minidump_format.h"
425f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com#include "google_breakpad/processor/basic_source_line_resolver.h"
435f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com#include "google_breakpad/processor/call_stack.h"
445f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com#include "google_breakpad/processor/code_module.h"
455f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com#include "google_breakpad/processor/source_line_resolver_interface.h"
465f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com#include "google_breakpad/processor/stack_frame_cpu.h"
475f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com#include "processor/stackwalker_unittest_utils.h"
485f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com#include "processor/stackwalker_mips.h"
495f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com#include "processor/windows_frame_info.h"
505f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
515f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comusing google_breakpad::BasicSourceLineResolver;
525f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comusing google_breakpad::CallStack;
535f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comusing google_breakpad::CodeModule;
545f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comusing google_breakpad::StackFrameSymbolizer;
555f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comusing google_breakpad::StackFrame;
565f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comusing google_breakpad::StackFrameMIPS;
575f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comusing google_breakpad::Stackwalker;
585f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comusing google_breakpad::StackwalkerMIPS;
595f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comusing google_breakpad::SystemInfo;
605f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comusing google_breakpad::WindowsFrameInfo;
615f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comusing google_breakpad::test_assembler::kLittleEndian;
625f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comusing google_breakpad::test_assembler::Label;
635f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comusing google_breakpad::test_assembler::Section;
645f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comusing std::vector;
655f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comusing testing::_;
665f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comusing testing::AnyNumber;
675f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comusing testing::Return;
685f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comusing testing::SetArgumentPointee;
695f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comusing testing::Test;
705f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
715f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comclass StackwalkerMIPSFixture {
725f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com public:
735f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  StackwalkerMIPSFixture()
745f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    : stack_section(kLittleEndian),
755f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com      // Give the two modules reasonable standard locations and names
765f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com      // for tests to play with.
775f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com      module1(0x00400000, 0x10000, "module1", "version1"),
785f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com      module2(0x00500000, 0x10000, "module2", "version2") {
795f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    // Identify the system as a Linux system.
805f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    system_info.os = "Linux";
815f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    system_info.os_short = "linux";
825f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    system_info.os_version = "Observant Opossum";  // Jealous Jellyfish
835f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    system_info.cpu = "mips";
845f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    system_info.cpu_info = "";
855f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
865f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    // Put distinctive values in the raw CPU context.
875f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    BrandContext(&raw_context);
885f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
895f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    // Create some modules with some stock debugging information.
905f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    modules.Add(&module1);
915f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    modules.Add(&module2);
925f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
935f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    // By default, none of the modules have symbol info; call
945f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    // SetModuleSymbols to override this.
955f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    EXPECT_CALL(supplier, GetCStringSymbolData(_, _, _, _, _))
965f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com      .WillRepeatedly(Return(MockSymbolSupplier::NOT_FOUND));
975f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
985f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    // Avoid GMOCK WARNING "Uninteresting mock function call - returning
995f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    // directly" for FreeSymbolData().
1005f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    EXPECT_CALL(supplier, FreeSymbolData(_)).Times(AnyNumber());
1015f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
1025f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    // Reset max_frames_scanned since it's static.
1035f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    Stackwalker::set_max_frames_scanned(1024);
1045f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  }
1055f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
1065f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // Set the Breakpad symbol information that supplier should return for
1075f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // MODULE to INFO.
1085f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  void SetModuleSymbols(MockCodeModule* module, const string& info) {
1095f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    size_t buffer_size;
1105f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    char* buffer = supplier.CopySymbolDataAndOwnTheCopy(info, &buffer_size);
1115f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    EXPECT_CALL(supplier, GetCStringSymbolData(module, &system_info, _, _, _))
1125f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com      .WillRepeatedly(DoAll(SetArgumentPointee<3>(buffer),
1135f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                            SetArgumentPointee<4>(buffer_size),
1145f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                            Return(MockSymbolSupplier::FOUND)));
1155f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  }
1165f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
1175f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // Populate stack_region with the contents of stack_section. Use
1185f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // stack_section.start() as the region's starting address.
1195f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  void RegionFromSection() {
1205f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    string contents;
1215f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    ASSERT_TRUE(stack_section.GetContents(&contents));
1225f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    stack_region.Init(stack_section.start().Value(), contents);
1235f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  }
1245f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
1255f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // Fill RAW_CONTEXT with pseudo-random data, for round-trip checking.
1265f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  void BrandContext(MDRawContextMIPS* raw_context) {
1275f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    uint8_t x = 173;
1285f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    for (size_t i = 0; i < sizeof(*raw_context); ++i)
1295f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com      reinterpret_cast<uint8_t*>(raw_context)[i] = (x += 17);
1305f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  }
1315f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
1325f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  SystemInfo system_info;
1335f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  MDRawContextMIPS raw_context;
1345f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  Section stack_section;
1355f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  MockMemoryRegion stack_region;
1365f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  MockCodeModule module1;
1375f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  MockCodeModule module2;
1385f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  MockCodeModules modules;
1395f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  MockSymbolSupplier supplier;
1405f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  BasicSourceLineResolver resolver;
1415f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  CallStack call_stack;
1425f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  const vector<StackFrame*>* frames;
1435f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com};
1445f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
1455f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comclass SanityCheck: public StackwalkerMIPSFixture, public Test { };
1465f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
1475f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comTEST_F(SanityCheck, NoResolver) {
1485f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  stack_section.start() = 0x80000000;
1495f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  stack_section.D32(0).D32(0x0);
1505f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  RegionFromSection();
1515f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  raw_context.epc = 0x00400020;
1525f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000;
1535f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
1545f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  StackFrameSymbolizer frame_symbolizer(NULL, NULL);
1555f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules,
1565f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                        &frame_symbolizer);
1575f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // This should succeed, even without a resolver or supplier.
1585f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  vector<const CodeModule*> modules_without_symbols;
1595f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  vector<const CodeModule*> modules_with_corrupt_symbols;
1605f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
1615f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                          &modules_with_corrupt_symbols));
1625f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ(1U, modules_without_symbols.size());
1635f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
1645f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
1655f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  frames = call_stack.frames();
1665f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ(1U, frames->size());
1675f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  StackFrameMIPS* frame = static_cast<StackFrameMIPS*>(frames->at(0));
1685f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // Check that the values from the original raw context made it
1695f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // through to the context in the stack frame.
1705f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context)));
1715f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com}
1725f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
1735f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comclass GetContextFrame: public StackwalkerMIPSFixture, public Test { };
1745f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
1755f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comTEST_F(GetContextFrame, Simple) {
1765f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  stack_section.start() = 0x80000000;
1775f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  stack_section.D32(0).D32(0x0);
1785f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  RegionFromSection();
1795f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  raw_context.epc = 0x00400020;
1805f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000;
1815f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
1825f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
1835f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules,
1845f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                         &frame_symbolizer);
1855f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  vector<const CodeModule*> modules_without_symbols;
1865f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  vector<const CodeModule*> modules_with_corrupt_symbols;
1875f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
1885f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                          &modules_with_corrupt_symbols));
1895f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ(1U, modules_without_symbols.size());
1905f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
1915f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
1925f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  frames = call_stack.frames();
1935f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  StackFrameMIPS* frame = static_cast<StackFrameMIPS*>(frames->at(0));
1945f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // Check that the values from the original raw context made it
1955f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // through to the context in the stack frame.
1965f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context)));
1975f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com}
1985f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
1995f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// The stackwalker should be able to produce the context frame even
2005f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// without stack memory present.
2015f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comTEST_F(GetContextFrame, NoStackMemory) {
2025f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  raw_context.epc = 0x00400020;
2035f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000;
2045f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
2055f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
2065f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  StackwalkerMIPS walker(&system_info, &raw_context, NULL, &modules,
2075f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                         &frame_symbolizer);
2085f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  vector<const CodeModule*> modules_without_symbols;
2095f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  vector<const CodeModule*> modules_with_corrupt_symbols;
2105f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
2115f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                          &modules_with_corrupt_symbols));
2125f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ(1U, modules_without_symbols.size());
2135f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
2145f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
2155f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  frames = call_stack.frames();
2165f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  StackFrameMIPS* frame = static_cast<StackFrameMIPS*>(frames->at(0));
2175f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // Check that the values from the original raw context made it
2185f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // through to the context in the stack frame.
2195f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context)));
2205f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com}
2215f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
2225f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comclass GetCallerFrame: public StackwalkerMIPSFixture, public Test { };
2235f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
2245f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comTEST_F(GetCallerFrame, ScanWithoutSymbols) {
2255f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // When the stack walker resorts to scanning the stack,
2265f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // only addresses located within loaded modules are
2275f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // considered valid return addresses.
2285f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // Force scanning through three frames to ensure that the
2295f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // stack pointer is set properly in scan-recovered frames.
2305f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  stack_section.start() = 0x80000000;
2315f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  uint32_t return_address1 = 0x00400100;
2325f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  uint32_t return_address2 = 0x00400900;
2335f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  Label frame1_sp, frame2_sp;
2345f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  stack_section
2355f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    // frame 0
2365f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .Append(16, 0)                      // space
2375f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
2385f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(0x00490000)                    // junk that's not
2395f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(0x00600000)                    // a return address
2405f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
2415f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(frame1_sp)                     // stack pointer
2425f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(return_address1)               // actual return address
2435f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    // frame 1
2445f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .Mark(&frame1_sp)
2455f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .Append(16, 0)                      // space
2465f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
2475f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(0xF0000000)                    // more junk
2485f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(0x0000000D)
2495f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
2505f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(frame2_sp)                     // stack pointer
2515f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(return_address2)               // actual return address
2525f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    // frame 2
2535f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .Mark(&frame2_sp)
2545f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .Append(32, 0);                     // end of stack
2555f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  RegionFromSection();
2565f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
2575f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  raw_context.epc = 0x00405510;
2585f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = stack_section.start().Value();
2595f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  raw_context.iregs[MD_CONTEXT_MIPS_REG_RA] = return_address1;
2605f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
2615f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
2625f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules,
2635f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                         &frame_symbolizer);
2645f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  vector<const CodeModule*> modules_without_symbols;
2655f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  vector<const CodeModule*> modules_with_corrupt_symbols;
2665f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
2675f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                          &modules_with_corrupt_symbols));
2685f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ(1U, modules_without_symbols.size());
2695f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
2705f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
2715f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  frames = call_stack.frames();
2725f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ(3U, frames->size());
2735f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
2745f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  StackFrameMIPS* frame0 = static_cast<StackFrameMIPS*>(frames->at(0));
2755f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
2765f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ(StackFrameMIPS::CONTEXT_VALID_ALL, frame0->context_validity);
2775f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
2785f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
2795f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  StackFrameMIPS* frame1 = static_cast<StackFrameMIPS*>(frames->at(1));
2805f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
2815f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ((StackFrameMIPS::CONTEXT_VALID_PC |
2825f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com             StackFrameMIPS::CONTEXT_VALID_SP |
2835f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com             StackFrameMIPS::CONTEXT_VALID_FP |
2845f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com             StackFrameMIPS::CONTEXT_VALID_RA),
2855f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com            frame1->context_validity);
2865f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  EXPECT_EQ(return_address1 - 2 * sizeof(return_address1), frame1->context.epc);
2875f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_MIPS_REG_SP]);
2885f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
2895f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  StackFrameMIPS* frame2 = static_cast<StackFrameMIPS*>(frames->at(2));
2905f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame2->trust);
2915f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ((StackFrameMIPS::CONTEXT_VALID_PC |
2925f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com             StackFrameMIPS::CONTEXT_VALID_SP |
2935f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com             StackFrameMIPS::CONTEXT_VALID_FP |
2945f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com             StackFrameMIPS::CONTEXT_VALID_RA),
2955f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com            frame2->context_validity);
2965f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  EXPECT_EQ(return_address2 - 2 * sizeof(return_address2), frame2->context.epc);
2975f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  EXPECT_EQ(frame2_sp.Value(), frame2->context.iregs[MD_CONTEXT_MIPS_REG_SP]);
2985f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com}
2995f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
3005f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comTEST_F(GetCallerFrame, ScanWithFunctionSymbols) {
3015f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // During stack scanning, if a potential return address
3025f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // is located within a loaded module that has symbols,
3035f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // it is only considered a valid return address if it
3045f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // lies within a function's bounds.
3055f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  stack_section.start() = 0x80000000;
3065f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  uint32_t return_address = 0x00500200;
3075f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  Label frame1_sp;
3085f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  stack_section
3095f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    // frame 0
3105f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .Append(16, 0)                      // space
3115f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
3125f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(0x00490000)                    // junk that's not
3135f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(0x00600000)                    // a return address
3145f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
3155f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(0x00401000)                    // a couple of plausible addresses
3165f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(0x0050F000)                    // that are not within functions
3175f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
3185f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(frame1_sp)                     // stack pointer
3195f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(return_address)                // actual return address
3205f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    // frame 1
3215f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .Mark(&frame1_sp)
3225f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .Append(32, 0);                     // end of stack
3235f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  RegionFromSection();
3245f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
3255f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  raw_context.epc = 0x00400200;
3265f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = stack_section.start().Value();
3275f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  raw_context.iregs[MD_CONTEXT_MIPS_REG_RA] = return_address;
3285f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
3295f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  SetModuleSymbols(&module1,
3305f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                   // The youngest frame's function.
3315f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                   "FUNC 100 400 10 monotreme\n");
3325f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  SetModuleSymbols(&module2,
3335f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                   // The calling frame's function.
3345f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                   "FUNC 100 400 10 marsupial\n");
3355f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
3365f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
3375f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules,
3385f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                         &frame_symbolizer);
3395f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  vector<const CodeModule*> modules_without_symbols;
3405f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  vector<const CodeModule*> modules_with_corrupt_symbols;
3415f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
3425f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                          &modules_with_corrupt_symbols));
3435f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ(0U, modules_without_symbols.size());
3445f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
3455f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  frames = call_stack.frames();
3465f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ(2U, frames->size());
3475f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
3485f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  StackFrameMIPS* frame0 = static_cast<StackFrameMIPS*>(frames->at(0));
3495f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
3505f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ(StackFrameMIPS::CONTEXT_VALID_ALL, frame0->context_validity);
3515f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
3525f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  EXPECT_EQ("monotreme", frame0->function_name);
3535f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  EXPECT_EQ(0x00400100U, frame0->function_base);
3545f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
3555f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  StackFrameMIPS* frame1 = static_cast<StackFrameMIPS*>(frames->at(1));
3565f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
3575f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ((StackFrameMIPS::CONTEXT_VALID_PC |
3585f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com             StackFrameMIPS::CONTEXT_VALID_SP |
3595f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com             StackFrameMIPS::CONTEXT_VALID_FP |
3605f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com             StackFrameMIPS::CONTEXT_VALID_RA),
3615f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com            frame1->context_validity);
3625f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  EXPECT_EQ(return_address - 2 * sizeof(return_address), frame1->context.epc);
3635f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_MIPS_REG_SP]);
3645f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  EXPECT_EQ("marsupial", frame1->function_name);
3655f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  EXPECT_EQ(0x00500100U, frame1->function_base);
3665f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com}
3675f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
3685f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comTEST_F(GetCallerFrame, CheckStackFrameSizeLimit) {
3695f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // If the stackwalker resorts to stack scanning, it will scan only
3705f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // 1024 bytes of stack which correspondes to maximum size of stack frame.
3715f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  stack_section.start() = 0x80000000;
3725f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  uint32_t return_address1 = 0x00500100;
3735f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  uint32_t return_address2 = 0x00500900;
3745f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  Label frame1_sp, frame2_sp;
3755f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  stack_section
3765f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    // frame 0
3775f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .Append(32, 0)                      // space
3785f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
3795f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(0x00490000)                    // junk that's not
3805f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(0x00600000)                    // a return address
3815f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
3825f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .Append(96, 0)                      // more space
3835f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
3845f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(frame1_sp)                     // stack pointer
3855f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(return_address1)               // actual return address
3865f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    // frame 1
3875f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .Mark(&frame1_sp)
3885f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .Append(128 * 4, 0)                 // space
3895f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
3905f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(0x00F00000)                    // more junk
3915f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(0x0000000D)
3925f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
3935f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .Append(128 * 4, 0)                 // more space
3945f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
3955f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(frame2_sp)                     // stack pointer
3965f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(return_address2)               // actual return address
3975f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                                        // (won't be found)
3985f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    // frame 2
3995f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .Mark(&frame2_sp)
4005f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .Append(32, 0);                     // end of stack
4015f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  RegionFromSection();
4025f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
4035f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  raw_context.epc = 0x00405510;
4045f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = stack_section.start().Value();
4055f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  raw_context.iregs[MD_CONTEXT_MIPS_REG_RA] = return_address1;
4065f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
4075f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
4085f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules,
4095f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                         &frame_symbolizer);
4105f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  vector<const CodeModule*> modules_without_symbols;
4115f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  vector<const CodeModule*> modules_with_corrupt_symbols;
4125f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
4135f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                          &modules_with_corrupt_symbols));
4145f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ(2U, modules_without_symbols.size());
4155f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
4165f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ("module2", modules_without_symbols[1]->debug_file());
4175f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
4185f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  frames = call_stack.frames();
4195f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ(2U, frames->size());
4205f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
4215f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  StackFrameMIPS* frame0 = static_cast<StackFrameMIPS*>(frames->at(0));
4225f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
4235f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ(StackFrameMIPS::CONTEXT_VALID_ALL, frame0->context_validity);
4245f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
4255f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
4265f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  StackFrameMIPS* frame1 = static_cast<StackFrameMIPS*>(frames->at(1));
4275f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
4285f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ((StackFrameMIPS::CONTEXT_VALID_PC |
4295f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com             StackFrameMIPS::CONTEXT_VALID_SP |
4305f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com             StackFrameMIPS::CONTEXT_VALID_FP |
4315f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com             StackFrameMIPS::CONTEXT_VALID_RA),
4325f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com            frame1->context_validity);
4335f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  EXPECT_EQ(return_address1 - 2 * sizeof(return_address1), frame1->context.epc);
4345f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_MIPS_REG_SP]);
4355f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com}
4365f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
4375f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// Test that set_max_frames_scanned prevents using stack scanning
4385f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// to find caller frames.
4395f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comTEST_F(GetCallerFrame, ScanningNotAllowed) {
4405f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // When the stack walker resorts to scanning the stack,
4415f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // only fixed number of frames are allowed to be scanned out from stack
4425f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  stack_section.start() = 0x80000000;
4435f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  uint32_t return_address1 = 0x00500100;
4445f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  uint32_t return_address2 = 0x00500900;
4455f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  Label frame1_sp, frame2_sp;
4465f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  stack_section
4475f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    // frame 0
4485f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .Append(32, 0)                      // space
4495f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
4505f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(0x00490000)                    // junk that's not
4515f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(0x00600000)                    // a return address
4525f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
4535f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .Append(96, 0)                      // more space
4545f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
4555f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(frame1_sp)                     // stack pointer
4565f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(return_address1)               // actual return address
4575f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    // frame 1
4585f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .Mark(&frame1_sp)
4595f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .Append(128 * 4, 0)                 // space
4605f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
4615f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(0x00F00000)                    // more junk
4625f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(0x0000000D)
4635f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
4645f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .Append(128 * 4, 0)                 // more space
4655f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
4665f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(frame2_sp)                     // stack pointer
4675f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(return_address2)               // actual return address
4685f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                                        // (won't be found)
4695f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    // frame 2
4705f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .Mark(&frame2_sp)
4715f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .Append(32, 0);                     // end of stack
4725f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  RegionFromSection();
4735f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
4745f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  raw_context.epc = 0x00405510;
4755f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = stack_section.start().Value();
4765f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  raw_context.iregs[MD_CONTEXT_MIPS_REG_RA] = return_address1;
4775f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
4785f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
4795f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules,
4805f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                         &frame_symbolizer);
4815f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  Stackwalker::set_max_frames_scanned(0);
4825f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
4835f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  vector<const CodeModule*> modules_without_symbols;
4845f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  vector<const CodeModule*> modules_with_corrupt_symbols;
4855f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
4865f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                          &modules_with_corrupt_symbols));
4875f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ(1U, modules_without_symbols.size());
4885f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
4895f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
4905f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  frames = call_stack.frames();
4915f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ(1U, frames->size());
4925f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
4935f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  StackFrameMIPS* frame0 = static_cast<StackFrameMIPS*>(frames->at(0));
4945f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
4955f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ(StackFrameMIPS::CONTEXT_VALID_ALL, frame0->context_validity);
4965f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
4975f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com}
4985f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
4995f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comstruct CFIFixture: public StackwalkerMIPSFixture {
5005f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  CFIFixture() {
5015f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    // Provide some STACK CFI records;
5025f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    SetModuleSymbols(&module1,
5035f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                     // The youngest frame's function.
5045f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                     "FUNC 4000 1000 0 enchiridion\n"
5055f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                     // Initially, nothing has been pushed on the stack,
5065f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                     // and the return address is still in the $ra register.
5075f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                     "STACK CFI INIT 4000 1000 .cfa: $sp 0 + .ra: $ra\n"
5085f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                     // Move stack pointer.
5095f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                     "STACK CFI 4004 .cfa: $sp 32 +\n"
5105f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                     // store $fp and ra
5115f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                     "STACK CFI 4008 $fp: .cfa -8 + ^ .ra: .cfa -4 + ^\n"
5125f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                     // restore $fp
5135f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                     "STACK CFI 400c .cfa: $fp 32 +\n"
5145f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                     // restore $sp
5155f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                     "STACK CFI 4018 .cfa: $sp 32 +\n"
5165f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
5175f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                     "STACK CFI 4020 $fp: $fp .cfa: $sp 0 + .ra: .ra\n"
5185f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
5195f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                     // The calling function.
5205f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                     "FUNC 5000 1000 0 epictetus\n"
5215f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                     // Initially, nothing has been pushed on the stack,
5225f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                     // and the return address is still in the $ra register.
5235f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                     "STACK CFI INIT 5000 1000 .cfa: $sp .ra: $ra\n"
5245f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                     // Mark it as end of stack.
5255f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                     "STACK CFI INIT 5000 8 .cfa: $sp 0 + .ra: $ra\n"
5265f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
5275f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                     // A function whose CFI makes the stack pointer
5285f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                     // go backwards.
5295f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                     "FUNC 6000 1000 20 palinal\n"
5305f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                     "STACK CFI INIT 6000 1000 .cfa: $sp 4 - .ra: $ra\n"
5315f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
5325f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                     // A function with CFI expressions that can't be
5335f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                     // evaluated.
5345f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                     "FUNC 7000 1000 20 rhetorical\n"
5355f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                     "STACK CFI INIT 7000 1000 .cfa: moot .ra: ambiguous\n"
5365f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                   );
5375f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
5385f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    // Provide some distinctive values for the caller's registers.
5395f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    expected.epc = 0x00405508;
5405f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    expected.iregs[MD_CONTEXT_MIPS_REG_S0] = 0x0;
5415f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    expected.iregs[MD_CONTEXT_MIPS_REG_S1] = 0x1;
5425f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    expected.iregs[MD_CONTEXT_MIPS_REG_S2] = 0x2;
5435f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    expected.iregs[MD_CONTEXT_MIPS_REG_S3] = 0x3;
5445f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    expected.iregs[MD_CONTEXT_MIPS_REG_S4] = 0x4;
5455f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    expected.iregs[MD_CONTEXT_MIPS_REG_S5] = 0x5;
5465f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    expected.iregs[MD_CONTEXT_MIPS_REG_S6] = 0x6;
5475f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    expected.iregs[MD_CONTEXT_MIPS_REG_S7] = 0x7;
5485f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    expected.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000;
5495f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    expected.iregs[MD_CONTEXT_MIPS_REG_FP] = 0x80000000;
5505f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    expected.iregs[MD_CONTEXT_MIPS_REG_RA] = 0x00405510;
5515f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
5525f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    // Expect CFI to recover all callee-save registers. Since CFI is the
5535f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    // only stack frame construction technique we have, aside from the
5545f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    // context frame itself, there's no way for us to have a set of valid
5555f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    // registers smaller than this.
5565f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    expected_validity = (StackFrameMIPS::CONTEXT_VALID_PC |
5575f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                         StackFrameMIPS::CONTEXT_VALID_S0 |
5585f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                         StackFrameMIPS::CONTEXT_VALID_S1 |
5595f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                         StackFrameMIPS::CONTEXT_VALID_S2 |
5605f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                         StackFrameMIPS::CONTEXT_VALID_S3 |
5615f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                         StackFrameMIPS::CONTEXT_VALID_S4 |
5625f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                         StackFrameMIPS::CONTEXT_VALID_S5 |
5635f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                         StackFrameMIPS::CONTEXT_VALID_S6 |
5645f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                         StackFrameMIPS::CONTEXT_VALID_S7 |
5655f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                         StackFrameMIPS::CONTEXT_VALID_SP |
5665f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                         StackFrameMIPS::CONTEXT_VALID_FP |
5675f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                         StackFrameMIPS::CONTEXT_VALID_RA);
5685f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
5695f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    // By default, context frames provide all registers, as normal.
5705f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    context_frame_validity = StackFrameMIPS::CONTEXT_VALID_ALL;
5715f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
5725f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    // By default, registers are unchanged.
5735f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    raw_context = expected;
5745f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  }
5755f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
5765f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // Walk the stack, using stack_section as the contents of the stack
5775f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // and raw_context as the current register values. (Set the stack
5785f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // pointer to the stack's starting address.) Expect two stack
5795f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // frames; in the older frame, expect the callee-saves registers to
5805f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // have values matching those in 'expected'.
5815f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  void CheckWalk() {
5825f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    RegionFromSection();
5835f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = stack_section.start().Value();
5845f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
5855f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
5865f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    StackwalkerMIPS walker(&system_info, &raw_context, &stack_region,
5875f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                           &modules, &frame_symbolizer);
5885f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    vector<const CodeModule*> modules_without_symbols;
5895f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    vector<const CodeModule*> modules_with_corrupt_symbols;
5905f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
5915f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                            &modules_with_corrupt_symbols));
5925f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    ASSERT_EQ(0U, modules_without_symbols.size());
5935f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
5945f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    frames = call_stack.frames();
5955f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    ASSERT_EQ(2U, frames->size());
5965f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
5975f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    StackFrameMIPS* frame0 = static_cast<StackFrameMIPS*>(frames->at(0));
5985f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
5995f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    ASSERT_EQ(StackFrameMIPS::CONTEXT_VALID_ALL, frame0->context_validity);
6005f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    EXPECT_EQ("enchiridion", frame0->function_name);
6015f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    EXPECT_EQ(0x00404000U, frame0->function_base);
6025f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
6035f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    StackFrameMIPS* frame1 = static_cast<StackFrameMIPS*>(frames->at(1));
6045f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
6055f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    ASSERT_EQ(expected_validity, frame1->context_validity);
6065f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_S0],
6075f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com              frame1->context.iregs[MD_CONTEXT_MIPS_REG_S0]);
6085f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_S1],
6095f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com              frame1->context.iregs[MD_CONTEXT_MIPS_REG_S1]);
6105f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_S2],
6115f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com              frame1->context.iregs[MD_CONTEXT_MIPS_REG_S2]);
6125f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_S3],
6135f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com              frame1->context.iregs[MD_CONTEXT_MIPS_REG_S3]);
6145f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_S4],
6155f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com              frame1->context.iregs[MD_CONTEXT_MIPS_REG_S4]);
6165f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_S5],
6175f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com              frame1->context.iregs[MD_CONTEXT_MIPS_REG_S5]);
6185f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_S6],
6195f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com              frame1->context.iregs[MD_CONTEXT_MIPS_REG_S6]);
6205f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_S7],
6215f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com              frame1->context.iregs[MD_CONTEXT_MIPS_REG_S7]);
6225f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_FP],
6235f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com              frame1->context.iregs[MD_CONTEXT_MIPS_REG_FP]);
6245f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_RA],
6255f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com              frame1->context.iregs[MD_CONTEXT_MIPS_REG_RA]);
6265f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_SP],
6275f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com              frame1->context.iregs[MD_CONTEXT_MIPS_REG_SP]);
6285f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    EXPECT_EQ(expected.epc, frame1->context.epc);
6295f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    EXPECT_EQ(expected.epc, frame1->instruction);
6305f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    EXPECT_EQ("epictetus", frame1->function_name);
6315f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    EXPECT_EQ(0x00405000U, frame1->function_base);
6325f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  }
6335f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
6345f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // The values we expect to find for the caller's registers.
6355f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  MDRawContextMIPS expected;
6365f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
6375f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // The validity mask for expected.
6385f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  int expected_validity;
6395f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
6405f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  // The validity mask to impose on the context frame.
6415f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  int context_frame_validity;
6425f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com};
6435f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
6445f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comclass CFI: public CFIFixture, public Test { };
6455f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
6465f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// TODO(gordanac): add CFI tests
6475f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
6485f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comTEST_F(CFI, At4004) {
6495f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  Label frame1_sp = expected.iregs[MD_CONTEXT_MIPS_REG_SP];
6505f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  stack_section
6515f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    // frame0
6525f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .Append(24, 0)               // space
6535f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(frame1_sp)              // stack pointer
6545f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .D32(0x00405510)             // return address
6555f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com    .Mark(&frame1_sp);           // This effectively sets stack_section.start().
6565f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  raw_context.epc = 0x00404004;
6575f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  CheckWalk();
6585f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com}
6595f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
6605f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// Check that we reject rules that would cause the stack pointer to
6615f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// move in the wrong direction.
6625f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comTEST_F(CFI, RejectBackwards) {
6635f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  raw_context.epc = 0x40005000;
6645f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000;
6655f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  raw_context.iregs[MD_CONTEXT_MIPS_REG_RA] = 0x00405510;
6665f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
6675f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
6685f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules,
6695f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                         &frame_symbolizer);
6705f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  vector<const CodeModule*> modules_without_symbols;
6715f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  vector<const CodeModule*> modules_with_corrupt_symbols;
6725f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
6735f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                          &modules_with_corrupt_symbols));
6745f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ(0U, modules_without_symbols.size());
6755f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
6765f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  frames = call_stack.frames();
6775f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ(1U, frames->size());
6785f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com}
6795f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
6805f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com// Check that we reject rules whose expressions' evaluation fails.
6815f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comTEST_F(CFI, RejectBadExpressions) {
6825f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  raw_context.epc = 0x00407000;
6835f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000;
6845f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  raw_context.iregs[MD_CONTEXT_MIPS_REG_RA] = 0x00405510;
6855f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com
6865f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
6875f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules,
6885f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                         &frame_symbolizer);
6895f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  vector<const CodeModule*> modules_without_symbols;
6905f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  vector<const CodeModule*> modules_with_corrupt_symbols;
6915f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
6925f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com                          &modules_with_corrupt_symbols));
6935f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ(0U, modules_without_symbols.size());
6945f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
6955f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  frames = call_stack.frames();
6965f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com  ASSERT_EQ(1U, frames->size());
6975f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com}
698