OLD | NEW |
1 // Copyright (c) 2013, Google Inc. | 1 // Copyright (c) 2013, Google Inc. |
2 // All rights reserved. | 2 // All rights reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
11 // copyright notice, this list of conditions and the following disclaimer | 11 // copyright notice, this list of conditions and the following disclaimer |
12 // in the documentation and/or other materials provided with the | 12 // in the documentation and/or other materials provided with the |
13 // distribution. | 13 // distribution. |
14 // * Neither the name of Google Inc. nor the names of its | 14 // * Neither the name of Google Inc. nor the names of its |
15 // contributors may be used to endorse or promote products derived from | 15 // contributors may be used to endorse or promote products derived from |
16 // this software without specific prior written permission. | 16 // this software without specific prior written permission. |
17 // | 17 // |
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 | 29 |
30 // Original author: Gordana Cmiljanovic <gordana.cmiljanovic@imgtec.com> | 30 // Original author: Veljko Mihailovic <veljko.mihailovic@imgtec.com> |
31 | 31 |
32 // stackwalker_mips_unittest.cc: Unit tests for StackwalkerMIPS class. | 32 // stackwalker_mips64_unittest.cc: Unit tests for StackwalkerMIPS class for |
| 33 // mips64 platforms. |
33 | 34 |
34 #include <string.h> | 35 #include <string.h> |
35 #include <string> | 36 #include <string> |
36 #include <vector> | 37 #include <vector> |
37 | 38 |
38 #include "breakpad_googletest_includes.h" | 39 #include "breakpad_googletest_includes.h" |
39 #include "common/test_assembler.h" | 40 #include "common/test_assembler.h" |
40 #include "common/using_std_string.h" | 41 #include "common/using_std_string.h" |
41 #include "google_breakpad/common/minidump_format.h" | 42 #include "google_breakpad/common/minidump_format.h" |
42 #include "google_breakpad/processor/basic_source_line_resolver.h" | 43 #include "google_breakpad/processor/basic_source_line_resolver.h" |
(...skipping 30 matching lines...) Expand all Loading... |
73 StackwalkerMIPSFixture() | 74 StackwalkerMIPSFixture() |
74 : stack_section(kLittleEndian), | 75 : stack_section(kLittleEndian), |
75 // Give the two modules reasonable standard locations and names | 76 // Give the two modules reasonable standard locations and names |
76 // for tests to play with. | 77 // for tests to play with. |
77 module1(0x00400000, 0x10000, "module1", "version1"), | 78 module1(0x00400000, 0x10000, "module1", "version1"), |
78 module2(0x00500000, 0x10000, "module2", "version2") { | 79 module2(0x00500000, 0x10000, "module2", "version2") { |
79 // Identify the system as a Linux system. | 80 // Identify the system as a Linux system. |
80 system_info.os = "Linux"; | 81 system_info.os = "Linux"; |
81 system_info.os_short = "linux"; | 82 system_info.os_short = "linux"; |
82 system_info.os_version = "Observant Opossum"; // Jealous Jellyfish | 83 system_info.os_version = "Observant Opossum"; // Jealous Jellyfish |
83 system_info.cpu = "mips"; | 84 system_info.cpu = "mips64"; |
84 system_info.cpu_info = ""; | 85 system_info.cpu_info = ""; |
85 | 86 |
86 // Put distinctive values in the raw CPU context. | 87 // Put distinctive values in the raw CPU context. |
87 BrandContext(&raw_context); | 88 BrandContext(&raw_context); |
88 | 89 |
89 // Create some modules with some stock debugging information. | 90 // Create some modules with some stock debugging information. |
90 modules.Add(&module1); | 91 modules.Add(&module1); |
91 modules.Add(&module2); | 92 modules.Add(&module2); |
92 | 93 |
93 // By default, none of the modules have symbol info; call | 94 // By default, none of the modules have symbol info; call |
94 // SetModuleSymbols to override this. | 95 // SetModuleSymbols to override this. |
95 EXPECT_CALL(supplier, GetCStringSymbolData(_, _, _, _, _)) | 96 EXPECT_CALL(supplier, GetCStringSymbolData(_, _, _, _, _)) |
96 .WillRepeatedly(Return(MockSymbolSupplier::NOT_FOUND)); | 97 .WillRepeatedly(Return(MockSymbolSupplier::NOT_FOUND)); |
97 | 98 |
98 // Avoid GMOCK WARNING "Uninteresting mock function call - returning | 99 // Avoid GMOCK WARNING "Uninteresting mock function call - returning |
99 // directly" for FreeSymbolData(). | 100 // directly" for FreeSymbolData(). |
100 EXPECT_CALL(supplier, FreeSymbolData(_)).Times(AnyNumber()); | 101 EXPECT_CALL(supplier, FreeSymbolData(_)).Times(AnyNumber()); |
101 | 102 |
102 // Reset max_frames_scanned since it's static. | 103 // Reset max_frames_scanned since it's static. |
103 Stackwalker::set_max_frames_scanned(1024); | 104 Stackwalker::set_max_frames_scanned(1024); |
104 } | 105 } |
105 | 106 |
106 // Set the Breakpad symbol information that supplier should return for | 107 // Set the Breakpad symbol information that supplier should return for |
107 // MODULE to INFO. | 108 // MODULE to INFO. |
108 void SetModuleSymbols(MockCodeModule* module, const string& info) { | 109 void SetModuleSymbols(MockCodeModule* module, const string& info) { |
109 size_t buffer_size; | 110 size_t buffer_size; |
110 char* buffer = supplier.CopySymbolDataAndOwnTheCopy(info, &buffer_size); | 111 char* buffer = supplier.CopySymbolDataAndOwnTheCopy(info, &buffer_size); |
111 EXPECT_CALL(supplier, GetCStringSymbolData(module, &system_info, _, _, _)) | 112 EXPECT_CALL(supplier, GetCStringSymbolData(module, &system_info, _, _, _)) |
112 .WillRepeatedly(DoAll(SetArgumentPointee<3>(buffer), | 113 .WillRepeatedly(DoAll(SetArgumentPointee<3>(buffer), |
113 SetArgumentPointee<4>(buffer_size), | 114 SetArgumentPointee<4>(buffer_size), |
(...skipping 24 matching lines...) Expand all Loading... |
138 MockCodeModules modules; | 139 MockCodeModules modules; |
139 MockSymbolSupplier supplier; | 140 MockSymbolSupplier supplier; |
140 BasicSourceLineResolver resolver; | 141 BasicSourceLineResolver resolver; |
141 CallStack call_stack; | 142 CallStack call_stack; |
142 const vector<StackFrame*>* frames; | 143 const vector<StackFrame*>* frames; |
143 }; | 144 }; |
144 | 145 |
145 class SanityCheck: public StackwalkerMIPSFixture, public Test { }; | 146 class SanityCheck: public StackwalkerMIPSFixture, public Test { }; |
146 | 147 |
147 TEST_F(SanityCheck, NoResolver) { | 148 TEST_F(SanityCheck, NoResolver) { |
| 149 raw_context.context_flags = |
| 150 raw_context.context_flags | MD_CONTEXT_MIPS64_FULL; |
148 stack_section.start() = 0x80000000; | 151 stack_section.start() = 0x80000000; |
149 stack_section.D32(0).D32(0x0); | 152 stack_section.D64(0).D64(0x0); |
150 RegionFromSection(); | 153 RegionFromSection(); |
151 raw_context.epc = 0x00400020; | 154 raw_context.epc = 0x00400020; |
152 raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000; | 155 raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000; |
153 | 156 |
154 StackFrameSymbolizer frame_symbolizer(NULL, NULL); | 157 StackFrameSymbolizer frame_symbolizer(NULL, NULL); |
155 StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, | 158 StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, |
156 &frame_symbolizer); | 159 &frame_symbolizer); |
157 // This should succeed, even without a resolver or supplier. | 160 // This should succeed, even without a resolver or supplier. |
158 vector<const CodeModule*> modules_without_symbols; | 161 vector<const CodeModule*> modules_without_symbols; |
159 vector<const CodeModule*> modules_with_corrupt_symbols; | 162 vector<const CodeModule*> modules_with_corrupt_symbols; |
160 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, | 163 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, |
161 &modules_with_corrupt_symbols)); | 164 &modules_with_corrupt_symbols)); |
162 ASSERT_EQ(1U, modules_without_symbols.size()); | 165 ASSERT_EQ(1U, modules_without_symbols.size()); |
163 ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); | 166 ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); |
164 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); | 167 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); |
165 frames = call_stack.frames(); | 168 frames = call_stack.frames(); |
166 ASSERT_EQ(1U, frames->size()); | 169 ASSERT_EQ(1U, frames->size()); |
167 StackFrameMIPS* frame = static_cast<StackFrameMIPS*>(frames->at(0)); | 170 StackFrameMIPS* frame = static_cast<StackFrameMIPS*>(frames->at(0)); |
168 // Check that the values from the original raw context made it | 171 // Check that the values from the original raw context made it |
169 // through to the context in the stack frame. | 172 // through to the context in the stack frame. |
170 EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); | 173 EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); |
171 } | 174 } |
172 | 175 |
173 class GetContextFrame: public StackwalkerMIPSFixture, public Test { }; | 176 class GetContextFrame: public StackwalkerMIPSFixture, public Test { }; |
174 | 177 |
175 TEST_F(GetContextFrame, Simple) { | 178 TEST_F(GetContextFrame, Simple) { |
| 179 raw_context.context_flags = |
| 180 raw_context.context_flags | MD_CONTEXT_MIPS64_FULL; |
176 stack_section.start() = 0x80000000; | 181 stack_section.start() = 0x80000000; |
177 stack_section.D32(0).D32(0x0); | 182 stack_section.D64(0).D64(0x0); |
178 RegionFromSection(); | 183 RegionFromSection(); |
179 raw_context.epc = 0x00400020; | 184 raw_context.epc = 0x00400020; |
180 raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000; | 185 raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000; |
181 | 186 |
182 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); | 187 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); |
183 StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, | 188 StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, |
184 &frame_symbolizer); | 189 &frame_symbolizer); |
185 vector<const CodeModule*> modules_without_symbols; | 190 vector<const CodeModule*> modules_without_symbols; |
186 vector<const CodeModule*> modules_with_corrupt_symbols; | 191 vector<const CodeModule*> modules_with_corrupt_symbols; |
187 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, | 192 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, |
188 &modules_with_corrupt_symbols)); | 193 &modules_with_corrupt_symbols)); |
189 ASSERT_EQ(1U, modules_without_symbols.size()); | 194 ASSERT_EQ(1U, modules_without_symbols.size()); |
190 ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); | 195 ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); |
191 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); | 196 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); |
192 frames = call_stack.frames(); | 197 frames = call_stack.frames(); |
193 StackFrameMIPS* frame = static_cast<StackFrameMIPS*>(frames->at(0)); | 198 StackFrameMIPS* frame = static_cast<StackFrameMIPS*>(frames->at(0)); |
194 // Check that the values from the original raw context made it | 199 // Check that the values from the original raw context made it |
195 // through to the context in the stack frame. | 200 // through to the context in the stack frame. |
196 EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); | 201 EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); |
197 } | 202 } |
198 | 203 |
199 // The stackwalker should be able to produce the context frame even | 204 // The stackwalker should be able to produce the context frame even |
200 // without stack memory present. | 205 // without stack memory present. |
201 TEST_F(GetContextFrame, NoStackMemory) { | 206 TEST_F(GetContextFrame, NoStackMemory) { |
| 207 raw_context.context_flags = |
| 208 raw_context.context_flags | MD_CONTEXT_MIPS64_FULL; |
202 raw_context.epc = 0x00400020; | 209 raw_context.epc = 0x00400020; |
203 raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000; | 210 raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000; |
204 | 211 |
205 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); | 212 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); |
206 StackwalkerMIPS walker(&system_info, &raw_context, NULL, &modules, | 213 StackwalkerMIPS walker(&system_info, &raw_context, NULL, &modules, |
207 &frame_symbolizer); | 214 &frame_symbolizer); |
208 vector<const CodeModule*> modules_without_symbols; | 215 vector<const CodeModule*> modules_without_symbols; |
209 vector<const CodeModule*> modules_with_corrupt_symbols; | 216 vector<const CodeModule*> modules_with_corrupt_symbols; |
210 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, | 217 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, |
211 &modules_with_corrupt_symbols)); | 218 &modules_with_corrupt_symbols)); |
212 ASSERT_EQ(1U, modules_without_symbols.size()); | 219 ASSERT_EQ(1U, modules_without_symbols.size()); |
213 ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); | 220 ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); |
214 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); | 221 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); |
215 frames = call_stack.frames(); | 222 frames = call_stack.frames(); |
216 StackFrameMIPS* frame = static_cast<StackFrameMIPS*>(frames->at(0)); | 223 StackFrameMIPS* frame = static_cast<StackFrameMIPS*>(frames->at(0)); |
217 // Check that the values from the original raw context made it | 224 // Check that the values from the original raw context made it |
218 // through to the context in the stack frame. | 225 // through to the context in the stack frame. |
219 EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); | 226 EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); |
220 } | 227 } |
221 | 228 |
222 class GetCallerFrame: public StackwalkerMIPSFixture, public Test { }; | 229 class GetCallerFrame: public StackwalkerMIPSFixture, public Test { }; |
223 | 230 |
224 TEST_F(GetCallerFrame, ScanWithoutSymbols) { | 231 TEST_F(GetCallerFrame, ScanWithoutSymbols) { |
| 232 raw_context.context_flags = |
| 233 raw_context.context_flags | MD_CONTEXT_MIPS64_FULL; |
225 // When the stack walker resorts to scanning the stack, | 234 // When the stack walker resorts to scanning the stack, |
226 // only addresses located within loaded modules are | 235 // only addresses located within loaded modules are |
227 // considered valid return addresses. | 236 // considered valid return addresses. |
228 // Force scanning through three frames to ensure that the | 237 // Force scanning through three frames to ensure that the |
229 // stack pointer is set properly in scan-recovered frames. | 238 // stack pointer is set properly in scan-recovered frames. |
230 stack_section.start() = 0x80000000; | 239 stack_section.start() = 0x80000000; |
231 uint32_t return_address1 = 0x00400100; | 240 uint64_t return_address1 = 0x00400100; |
232 uint32_t return_address2 = 0x00400900; | 241 uint64_t return_address2 = 0x00400900; |
233 Label frame1_sp, frame2_sp; | 242 Label frame1_sp, frame2_sp; |
234 stack_section | 243 stack_section |
235 // frame 0 | 244 // frame 0 |
236 .Append(16, 0) // space | 245 .Append(32, 0) // space |
237 | 246 |
238 .D32(0x00490000) // junk that's not | 247 .D64(0x00490000) // junk that's not |
239 .D32(0x00600000) // a return address | 248 .D64(0x00600000) // a return address |
240 | 249 |
241 .D32(frame1_sp) // stack pointer | 250 .D64(frame1_sp) // stack pointer |
242 .D32(return_address1) // actual return address | 251 .D64(return_address1) // actual return address |
243 // frame 1 | 252 // frame 1 |
244 .Mark(&frame1_sp) | 253 .Mark(&frame1_sp) |
245 .Append(16, 0) // space | 254 .Append(32, 0) // space |
246 | 255 |
247 .D32(0xF0000000) // more junk | 256 .D64(0xF0000000) // more junk |
248 .D32(0x0000000D) | 257 .D64(0x0000000D) |
249 | 258 |
250 .D32(frame2_sp) // stack pointer | 259 .D64(frame2_sp) // stack pointer |
251 .D32(return_address2) // actual return address | 260 .D64(return_address2) // actual return address |
252 // frame 2 | 261 // frame 2 |
253 .Mark(&frame2_sp) | 262 .Mark(&frame2_sp) |
254 .Append(32, 0); // end of stack | 263 .Append(64, 0); // end of stack |
255 RegionFromSection(); | 264 RegionFromSection(); |
256 | 265 |
257 raw_context.epc = 0x00405510; | 266 raw_context.epc = 0x00405510; |
258 raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = stack_section.start().Value(); | 267 raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = stack_section.start().Value(); |
259 raw_context.iregs[MD_CONTEXT_MIPS_REG_RA] = return_address1; | 268 raw_context.iregs[MD_CONTEXT_MIPS_REG_RA] = return_address1; |
260 | 269 |
261 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); | 270 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); |
262 StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, | 271 StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, |
263 &frame_symbolizer); | 272 &frame_symbolizer); |
264 vector<const CodeModule*> modules_without_symbols; | 273 vector<const CodeModule*> modules_without_symbols; |
(...skipping 26 matching lines...) Expand all Loading... |
291 ASSERT_EQ((StackFrameMIPS::CONTEXT_VALID_PC | | 300 ASSERT_EQ((StackFrameMIPS::CONTEXT_VALID_PC | |
292 StackFrameMIPS::CONTEXT_VALID_SP | | 301 StackFrameMIPS::CONTEXT_VALID_SP | |
293 StackFrameMIPS::CONTEXT_VALID_FP | | 302 StackFrameMIPS::CONTEXT_VALID_FP | |
294 StackFrameMIPS::CONTEXT_VALID_RA), | 303 StackFrameMIPS::CONTEXT_VALID_RA), |
295 frame2->context_validity); | 304 frame2->context_validity); |
296 EXPECT_EQ(return_address2 - 2 * sizeof(return_address2), frame2->context.epc); | 305 EXPECT_EQ(return_address2 - 2 * sizeof(return_address2), frame2->context.epc); |
297 EXPECT_EQ(frame2_sp.Value(), frame2->context.iregs[MD_CONTEXT_MIPS_REG_SP]); | 306 EXPECT_EQ(frame2_sp.Value(), frame2->context.iregs[MD_CONTEXT_MIPS_REG_SP]); |
298 } | 307 } |
299 | 308 |
300 TEST_F(GetCallerFrame, ScanWithFunctionSymbols) { | 309 TEST_F(GetCallerFrame, ScanWithFunctionSymbols) { |
| 310 raw_context.context_flags = |
| 311 raw_context.context_flags | MD_CONTEXT_MIPS64_FULL; |
301 // During stack scanning, if a potential return address | 312 // During stack scanning, if a potential return address |
302 // is located within a loaded module that has symbols, | 313 // is located within a loaded module that has symbols, |
303 // it is only considered a valid return address if it | 314 // it is only considered a valid return address if it |
304 // lies within a function's bounds. | 315 // lies within a function's bounds. |
305 stack_section.start() = 0x80000000; | 316 stack_section.start() = 0x80000000; |
306 uint32_t return_address = 0x00500200; | 317 uint64_t return_address = 0x00500200; |
307 Label frame1_sp; | 318 Label frame1_sp; |
308 stack_section | 319 stack_section |
309 // frame 0 | 320 // frame 0 |
310 .Append(16, 0) // space | 321 .Append(16, 0) // space |
311 | 322 |
312 .D32(0x00490000) // junk that's not | 323 .D64(0x00490000) // junk that's not |
313 .D32(0x00600000) // a return address | 324 .D64(0x00600000) // a return address |
314 | |
315 .D32(0x00401000) // a couple of plausible addresses | |
316 .D32(0x0050F000) // that are not within functions | |
317 | 325 |
318 .D32(frame1_sp) // stack pointer | 326 .D64(0x00401000) // a couple of plausible addresses |
319 .D32(return_address) // actual return address | 327 .D64(0x0050F000) // that are not within functions |
| 328 |
| 329 .D64(frame1_sp) // stack pointer |
| 330 .D64(return_address) // actual return address |
320 // frame 1 | 331 // frame 1 |
321 .Mark(&frame1_sp) | 332 .Mark(&frame1_sp) |
322 .Append(32, 0); // end of stack | 333 .Append(64, 0); // end of stack |
323 RegionFromSection(); | 334 RegionFromSection(); |
324 | 335 |
325 raw_context.epc = 0x00400200; | 336 raw_context.epc = 0x00400200; |
326 raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = stack_section.start().Value(); | 337 raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = stack_section.start().Value(); |
327 raw_context.iregs[MD_CONTEXT_MIPS_REG_RA] = return_address; | 338 raw_context.iregs[MD_CONTEXT_MIPS_REG_RA] = return_address; |
328 | 339 |
329 SetModuleSymbols(&module1, | 340 SetModuleSymbols(&module1, |
330 // The youngest frame's function. | 341 // The youngest frame's function. |
331 "FUNC 100 400 10 monotreme\n"); | 342 "FUNC 100 400 10 monotreme\n"); |
332 SetModuleSymbols(&module2, | 343 SetModuleSymbols(&module2, |
(...skipping 26 matching lines...) Expand all Loading... |
359 StackFrameMIPS::CONTEXT_VALID_FP | | 370 StackFrameMIPS::CONTEXT_VALID_FP | |
360 StackFrameMIPS::CONTEXT_VALID_RA), | 371 StackFrameMIPS::CONTEXT_VALID_RA), |
361 frame1->context_validity); | 372 frame1->context_validity); |
362 EXPECT_EQ(return_address - 2 * sizeof(return_address), frame1->context.epc); | 373 EXPECT_EQ(return_address - 2 * sizeof(return_address), frame1->context.epc); |
363 EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_MIPS_REG_SP]); | 374 EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_MIPS_REG_SP]); |
364 EXPECT_EQ("marsupial", frame1->function_name); | 375 EXPECT_EQ("marsupial", frame1->function_name); |
365 EXPECT_EQ(0x00500100U, frame1->function_base); | 376 EXPECT_EQ(0x00500100U, frame1->function_base); |
366 } | 377 } |
367 | 378 |
368 TEST_F(GetCallerFrame, CheckStackFrameSizeLimit) { | 379 TEST_F(GetCallerFrame, CheckStackFrameSizeLimit) { |
| 380 raw_context.context_flags = |
| 381 raw_context.context_flags | MD_CONTEXT_MIPS64_FULL; |
369 // If the stackwalker resorts to stack scanning, it will scan only | 382 // If the stackwalker resorts to stack scanning, it will scan only |
370 // 1024 bytes of stack which correspondes to maximum size of stack frame. | 383 // 1024 bytes of stack which correspondes to maximum size of stack frame. |
371 stack_section.start() = 0x80000000; | 384 stack_section.start() = 0x80000000; |
372 uint32_t return_address1 = 0x00500100; | 385 uint64_t return_address1 = 0x00500100; |
373 uint32_t return_address2 = 0x00500900; | 386 uint64_t return_address2 = 0x00500900; |
374 Label frame1_sp, frame2_sp; | 387 Label frame1_sp, frame2_sp; |
375 stack_section | 388 stack_section |
376 // frame 0 | 389 // frame 0 |
377 .Append(32, 0) // space | 390 .Append(32, 0) // space |
378 | 391 |
379 .D32(0x00490000) // junk that's not | 392 .D64(0x00490000) // junk that's not |
380 .D32(0x00600000) // a return address | 393 .D64(0x00600000) // a return address |
381 | 394 |
382 .Append(96, 0) // more space | 395 .Append(96, 0) // more space |
383 | 396 |
384 .D32(frame1_sp) // stack pointer | 397 .D64(frame1_sp) // stack pointer |
385 .D32(return_address1) // actual return address | 398 .D64(return_address1) // actual return address |
386 // frame 1 | 399 // frame 1 |
387 .Mark(&frame1_sp) | 400 .Mark(&frame1_sp) |
388 .Append(128 * 4, 0) // space | 401 .Append(128 * 4, 0) // space |
389 | 402 |
390 .D32(0x00F00000) // more junk | 403 .D64(0x00F00000) // more junk |
391 .D32(0x0000000D) | 404 .D64(0x0000000D) |
392 | 405 |
393 .Append(128 * 4, 0) // more space | 406 .Append(128 * 4, 0) // more space |
394 | 407 |
395 .D32(frame2_sp) // stack pointer | 408 .D64(frame2_sp) // stack pointer |
396 .D32(return_address2) // actual return address | 409 .D64(return_address2) // actual return address |
397 // (won't be found) | 410 // (won't be found) |
398 // frame 2 | 411 // frame 2 |
399 .Mark(&frame2_sp) | 412 .Mark(&frame2_sp) |
400 .Append(32, 0); // end of stack | 413 .Append(64, 0); // end of stack |
401 RegionFromSection(); | 414 RegionFromSection(); |
402 | 415 |
403 raw_context.epc = 0x00405510; | 416 raw_context.epc = 0x00405510; |
404 raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = stack_section.start().Value(); | 417 raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = stack_section.start().Value(); |
405 raw_context.iregs[MD_CONTEXT_MIPS_REG_RA] = return_address1; | 418 raw_context.iregs[MD_CONTEXT_MIPS_REG_RA] = return_address1; |
406 | 419 |
407 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); | 420 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); |
408 StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, | 421 StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, |
409 &frame_symbolizer); | 422 &frame_symbolizer); |
410 vector<const CodeModule*> modules_without_symbols; | 423 vector<const CodeModule*> modules_without_symbols; |
(...skipping 19 matching lines...) Expand all Loading... |
430 StackFrameMIPS::CONTEXT_VALID_FP | | 443 StackFrameMIPS::CONTEXT_VALID_FP | |
431 StackFrameMIPS::CONTEXT_VALID_RA), | 444 StackFrameMIPS::CONTEXT_VALID_RA), |
432 frame1->context_validity); | 445 frame1->context_validity); |
433 EXPECT_EQ(return_address1 - 2 * sizeof(return_address1), frame1->context.epc); | 446 EXPECT_EQ(return_address1 - 2 * sizeof(return_address1), frame1->context.epc); |
434 EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_MIPS_REG_SP]); | 447 EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_MIPS_REG_SP]); |
435 } | 448 } |
436 | 449 |
437 // Test that set_max_frames_scanned prevents using stack scanning | 450 // Test that set_max_frames_scanned prevents using stack scanning |
438 // to find caller frames. | 451 // to find caller frames. |
439 TEST_F(GetCallerFrame, ScanningNotAllowed) { | 452 TEST_F(GetCallerFrame, ScanningNotAllowed) { |
| 453 raw_context.context_flags = |
| 454 raw_context.context_flags | MD_CONTEXT_MIPS64_FULL; |
440 // When the stack walker resorts to scanning the stack, | 455 // When the stack walker resorts to scanning the stack, |
441 // only fixed number of frames are allowed to be scanned out from stack | 456 // only fixed number of frames are allowed to be scanned out from stack |
442 stack_section.start() = 0x80000000; | 457 stack_section.start() = 0x80000000; |
443 uint32_t return_address1 = 0x00500100; | 458 uint64_t return_address1 = 0x00500100; |
444 uint32_t return_address2 = 0x00500900; | 459 uint64_t return_address2 = 0x00500900; |
445 Label frame1_sp, frame2_sp; | 460 Label frame1_sp, frame2_sp; |
446 stack_section | 461 stack_section |
447 // frame 0 | 462 // frame 0 |
448 .Append(32, 0) // space | 463 .Append(32, 0) // space |
449 | 464 |
450 .D32(0x00490000) // junk that's not | 465 .D64(0x00490000) // junk that's not |
451 .D32(0x00600000) // a return address | 466 .D64(0x00600000) // a return address |
452 | 467 |
453 .Append(96, 0) // more space | 468 .Append(96, 0) // more space |
454 | 469 |
455 .D32(frame1_sp) // stack pointer | 470 .D64(frame1_sp) // stack pointer |
456 .D32(return_address1) // actual return address | 471 .D64(return_address1) // actual return address |
457 // frame 1 | 472 // frame 1 |
458 .Mark(&frame1_sp) | 473 .Mark(&frame1_sp) |
459 .Append(128 * 4, 0) // space | 474 .Append(128 * 4, 0) // space |
460 | 475 |
461 .D32(0x00F00000) // more junk | 476 .D64(0x00F00000) // more junk |
462 .D32(0x0000000D) | 477 .D64(0x0000000D) |
463 | 478 |
464 .Append(128 * 4, 0) // more space | 479 .Append(128 * 4, 0) // more space |
465 | 480 |
466 .D32(frame2_sp) // stack pointer | 481 .D64(frame2_sp) // stack pointer |
467 .D32(return_address2) // actual return address | 482 .D64(return_address2) // actual return address |
468 // (won't be found) | 483 // (won't be found) |
469 // frame 2 | 484 // frame 2 |
470 .Mark(&frame2_sp) | 485 .Mark(&frame2_sp) |
471 .Append(32, 0); // end of stack | 486 .Append(64, 0); // end of stack |
472 RegionFromSection(); | 487 RegionFromSection(); |
473 | 488 |
474 raw_context.epc = 0x00405510; | 489 raw_context.epc = 0x00405510; |
475 raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = stack_section.start().Value(); | 490 raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = stack_section.start().Value(); |
476 raw_context.iregs[MD_CONTEXT_MIPS_REG_RA] = return_address1; | 491 raw_context.iregs[MD_CONTEXT_MIPS_REG_RA] = return_address1; |
477 | 492 |
478 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); | 493 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); |
479 StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, | 494 StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, |
480 &frame_symbolizer); | 495 &frame_symbolizer); |
481 Stackwalker::set_max_frames_scanned(0); | 496 Stackwalker::set_max_frames_scanned(0); |
482 | 497 |
483 vector<const CodeModule*> modules_without_symbols; | 498 vector<const CodeModule*> modules_without_symbols; |
484 vector<const CodeModule*> modules_with_corrupt_symbols; | 499 vector<const CodeModule*> modules_with_corrupt_symbols; |
485 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, | 500 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, |
486 &modules_with_corrupt_symbols)); | 501 &modules_with_corrupt_symbols)); |
487 ASSERT_EQ(1U, modules_without_symbols.size()); | 502 ASSERT_EQ(1U, modules_without_symbols.size()); |
488 ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); | 503 ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); |
489 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); | 504 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); |
490 frames = call_stack.frames(); | 505 frames = call_stack.frames(); |
491 ASSERT_EQ(1U, frames->size()); | 506 ASSERT_EQ(1U, frames->size()); |
492 | 507 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 "FUNC 6000 1000 20 palinal\n" | 544 "FUNC 6000 1000 20 palinal\n" |
530 "STACK CFI INIT 6000 1000 .cfa: $sp 4 - .ra: $ra\n" | 545 "STACK CFI INIT 6000 1000 .cfa: $sp 4 - .ra: $ra\n" |
531 | 546 |
532 // A function with CFI expressions that can't be | 547 // A function with CFI expressions that can't be |
533 // evaluated. | 548 // evaluated. |
534 "FUNC 7000 1000 20 rhetorical\n" | 549 "FUNC 7000 1000 20 rhetorical\n" |
535 "STACK CFI INIT 7000 1000 .cfa: moot .ra: ambiguous\n" | 550 "STACK CFI INIT 7000 1000 .cfa: moot .ra: ambiguous\n" |
536 ); | 551 ); |
537 | 552 |
538 // Provide some distinctive values for the caller's registers. | 553 // Provide some distinctive values for the caller's registers. |
539 expected.epc = 0x00405508; | 554 expected.epc = 0x00405500; |
540 expected.iregs[MD_CONTEXT_MIPS_REG_S0] = 0x0; | 555 expected.iregs[MD_CONTEXT_MIPS_REG_S0] = 0x0; |
541 expected.iregs[MD_CONTEXT_MIPS_REG_S1] = 0x1; | 556 expected.iregs[MD_CONTEXT_MIPS_REG_S1] = 0x1; |
542 expected.iregs[MD_CONTEXT_MIPS_REG_S2] = 0x2; | 557 expected.iregs[MD_CONTEXT_MIPS_REG_S2] = 0x2; |
543 expected.iregs[MD_CONTEXT_MIPS_REG_S3] = 0x3; | 558 expected.iregs[MD_CONTEXT_MIPS_REG_S3] = 0x3; |
544 expected.iregs[MD_CONTEXT_MIPS_REG_S4] = 0x4; | 559 expected.iregs[MD_CONTEXT_MIPS_REG_S4] = 0x4; |
545 expected.iregs[MD_CONTEXT_MIPS_REG_S5] = 0x5; | 560 expected.iregs[MD_CONTEXT_MIPS_REG_S5] = 0x5; |
546 expected.iregs[MD_CONTEXT_MIPS_REG_S6] = 0x6; | 561 expected.iregs[MD_CONTEXT_MIPS_REG_S6] = 0x6; |
547 expected.iregs[MD_CONTEXT_MIPS_REG_S7] = 0x7; | 562 expected.iregs[MD_CONTEXT_MIPS_REG_S7] = 0x7; |
548 expected.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000; | 563 expected.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000; |
549 expected.iregs[MD_CONTEXT_MIPS_REG_FP] = 0x80000000; | 564 expected.iregs[MD_CONTEXT_MIPS_REG_FP] = 0x80000000; |
550 expected.iregs[MD_CONTEXT_MIPS_REG_RA] = 0x00405510; | 565 expected.iregs[MD_CONTEXT_MIPS_REG_RA] = 0x00405510; |
551 | 566 |
552 // Expect CFI to recover all callee-save registers. Since CFI is the | 567 // Expect CFI to recover all callee-save registers. Since CFI is the |
553 // only stack frame construction technique we have, aside from the | 568 // only stack frame construction technique we have, aside from the |
554 // context frame itself, there's no way for us to have a set of valid | 569 // context frame itself, there's no way for us to have a set of valid |
555 // registers smaller than this. | 570 // registers smaller than this. |
556 expected_validity = (StackFrameMIPS::CONTEXT_VALID_PC | | 571 expected_validity = (StackFrameMIPS::CONTEXT_VALID_PC | |
557 StackFrameMIPS::CONTEXT_VALID_S0 | | 572 StackFrameMIPS::CONTEXT_VALID_S0 | |
558 StackFrameMIPS::CONTEXT_VALID_S1 | | 573 StackFrameMIPS::CONTEXT_VALID_S1 | |
559 StackFrameMIPS::CONTEXT_VALID_S2 | | 574 StackFrameMIPS::CONTEXT_VALID_S2 | |
560 StackFrameMIPS::CONTEXT_VALID_S3 | | 575 StackFrameMIPS::CONTEXT_VALID_S3 | |
561 StackFrameMIPS::CONTEXT_VALID_S4 | | 576 StackFrameMIPS::CONTEXT_VALID_S4 | |
562 StackFrameMIPS::CONTEXT_VALID_S5 | | 577 StackFrameMIPS::CONTEXT_VALID_S5 | |
563 StackFrameMIPS::CONTEXT_VALID_S6 | | 578 StackFrameMIPS::CONTEXT_VALID_S6 | |
564 StackFrameMIPS::CONTEXT_VALID_S7 | | 579 StackFrameMIPS::CONTEXT_VALID_S7 | |
565 StackFrameMIPS::CONTEXT_VALID_SP | | 580 StackFrameMIPS::CONTEXT_VALID_SP | |
566 StackFrameMIPS::CONTEXT_VALID_FP | | 581 StackFrameMIPS::CONTEXT_VALID_FP | |
| 582 StackFrameMIPS::CONTEXT_VALID_GP | |
567 StackFrameMIPS::CONTEXT_VALID_RA); | 583 StackFrameMIPS::CONTEXT_VALID_RA); |
568 | 584 |
569 // By default, context frames provide all registers, as normal. | 585 // By default, context frames provide all registers, as normal. |
570 context_frame_validity = StackFrameMIPS::CONTEXT_VALID_ALL; | 586 context_frame_validity = StackFrameMIPS::CONTEXT_VALID_ALL; |
571 | 587 |
572 // By default, registers are unchanged. | 588 // By default, registers are unchanged. |
573 raw_context = expected; | 589 raw_context = expected; |
574 } | 590 } |
575 | 591 |
576 // Walk the stack, using stack_section as the contents of the stack | 592 // Walk the stack, using stack_section as the contents of the stack |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
621 frame1->context.iregs[MD_CONTEXT_MIPS_REG_S7]); | 637 frame1->context.iregs[MD_CONTEXT_MIPS_REG_S7]); |
622 EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_FP], | 638 EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_FP], |
623 frame1->context.iregs[MD_CONTEXT_MIPS_REG_FP]); | 639 frame1->context.iregs[MD_CONTEXT_MIPS_REG_FP]); |
624 EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_RA], | 640 EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_RA], |
625 frame1->context.iregs[MD_CONTEXT_MIPS_REG_RA]); | 641 frame1->context.iregs[MD_CONTEXT_MIPS_REG_RA]); |
626 EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_SP], | 642 EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_SP], |
627 frame1->context.iregs[MD_CONTEXT_MIPS_REG_SP]); | 643 frame1->context.iregs[MD_CONTEXT_MIPS_REG_SP]); |
628 EXPECT_EQ(expected.epc, frame1->context.epc); | 644 EXPECT_EQ(expected.epc, frame1->context.epc); |
629 EXPECT_EQ(expected.epc, frame1->instruction); | 645 EXPECT_EQ(expected.epc, frame1->instruction); |
630 EXPECT_EQ("epictetus", frame1->function_name); | 646 EXPECT_EQ("epictetus", frame1->function_name); |
631 EXPECT_EQ(0x00405000U, frame1->function_base); | 647 EXPECT_EQ(0x00405000U, frame1->function_base); |
632 } | 648 } |
633 | 649 |
634 // The values we expect to find for the caller's registers. | 650 // The values we expect to find for the caller's registers. |
635 MDRawContextMIPS expected; | 651 MDRawContextMIPS expected; |
636 | 652 |
637 // The validity mask for expected. | 653 // The validity mask for expected. |
638 int expected_validity; | 654 int expected_validity; |
639 | 655 |
640 // The validity mask to impose on the context frame. | 656 // The validity mask to impose on the context frame. |
641 int context_frame_validity; | 657 int context_frame_validity; |
642 }; | 658 }; |
643 | 659 |
644 class CFI: public CFIFixture, public Test { }; | 660 class CFI: public CFIFixture, public Test { }; |
645 | 661 |
646 // TODO(gordanac): add CFI tests | 662 // TODO(gordanac): add CFI tests |
647 | 663 |
648 TEST_F(CFI, At4004) { | 664 TEST_F(CFI, At4004) { |
| 665 raw_context.context_flags = |
| 666 raw_context.context_flags | MD_CONTEXT_MIPS64_FULL; |
649 Label frame1_sp = expected.iregs[MD_CONTEXT_MIPS_REG_SP]; | 667 Label frame1_sp = expected.iregs[MD_CONTEXT_MIPS_REG_SP]; |
650 stack_section | 668 stack_section |
651 // frame0 | 669 // frame0 |
652 .Append(24, 0) // space | 670 .Append(16, 0) // space |
653 .D32(frame1_sp) // stack pointer | 671 .D64(frame1_sp) // stack pointer |
654 .D32(0x00405510) // return address | 672 .D64(0x00405510) // return address |
655 .Mark(&frame1_sp); // This effectively sets stack_section.start(). | 673 .Mark(&frame1_sp); // This effectively sets stack_section.start(). |
656 raw_context.epc = 0x00404004; | 674 raw_context.epc = 0x00404004; |
657 CheckWalk(); | 675 CheckWalk(); |
658 } | 676 } |
659 | 677 |
660 // Check that we reject rules that would cause the stack pointer to | 678 // Check that we reject rules that would cause the stack pointer to |
661 // move in the wrong direction. | 679 // move in the wrong direction. |
662 TEST_F(CFI, RejectBackwards) { | 680 TEST_F(CFI, RejectBackwards) { |
| 681 raw_context.context_flags = |
| 682 raw_context.context_flags | MD_CONTEXT_MIPS64_FULL; |
663 raw_context.epc = 0x40005000; | 683 raw_context.epc = 0x40005000; |
664 raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000; | 684 raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000; |
665 raw_context.iregs[MD_CONTEXT_MIPS_REG_RA] = 0x00405510; | 685 raw_context.iregs[MD_CONTEXT_MIPS_REG_RA] = 0x00405510; |
666 | 686 |
667 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); | 687 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); |
668 StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, | 688 StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, |
669 &frame_symbolizer); | 689 &frame_symbolizer); |
670 vector<const CodeModule*> modules_without_symbols; | 690 vector<const CodeModule*> modules_without_symbols; |
671 vector<const CodeModule*> modules_with_corrupt_symbols; | 691 vector<const CodeModule*> modules_with_corrupt_symbols; |
672 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, | 692 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, |
673 &modules_with_corrupt_symbols)); | 693 &modules_with_corrupt_symbols)); |
674 ASSERT_EQ(0U, modules_without_symbols.size()); | 694 ASSERT_EQ(0U, modules_without_symbols.size()); |
675 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); | 695 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); |
676 frames = call_stack.frames(); | 696 frames = call_stack.frames(); |
677 ASSERT_EQ(1U, frames->size()); | 697 ASSERT_EQ(1U, frames->size()); |
678 } | 698 } |
679 | 699 |
680 // Check that we reject rules whose expressions' evaluation fails. | 700 // Check that we reject rules whose expressions' evaluation fails. |
681 TEST_F(CFI, RejectBadExpressions) { | 701 TEST_F(CFI, RejectBadExpressions) { |
| 702 raw_context.context_flags = |
| 703 raw_context.context_flags | MD_CONTEXT_MIPS64_FULL; |
682 raw_context.epc = 0x00407000; | 704 raw_context.epc = 0x00407000; |
683 raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000; | 705 raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000; |
684 raw_context.iregs[MD_CONTEXT_MIPS_REG_RA] = 0x00405510; | 706 raw_context.iregs[MD_CONTEXT_MIPS_REG_RA] = 0x00405510; |
685 | 707 |
686 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); | 708 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); |
687 StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, | 709 StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, |
688 &frame_symbolizer); | 710 &frame_symbolizer); |
689 vector<const CodeModule*> modules_without_symbols; | 711 vector<const CodeModule*> modules_without_symbols; |
690 vector<const CodeModule*> modules_with_corrupt_symbols; | 712 vector<const CodeModule*> modules_with_corrupt_symbols; |
691 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, | 713 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, |
692 &modules_with_corrupt_symbols)); | 714 &modules_with_corrupt_symbols)); |
693 ASSERT_EQ(0U, modules_without_symbols.size()); | 715 ASSERT_EQ(0U, modules_without_symbols.size()); |
694 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); | 716 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); |
695 frames = call_stack.frames(); | 717 frames = call_stack.frames(); |
696 ASSERT_EQ(1U, frames->size()); | 718 ASSERT_EQ(1U, frames->size()); |
697 } | 719 } |
OLD | NEW |