/thirdparty/breakpad/processor/stackwalker_arm_unittest.cc

http://github.com/tomahawk-player/tomahawk · C++ · 764 lines · 545 code · 94 blank · 125 comment · 10 complexity · c25d3f7e4b22e4b6f363d56bf066c4ce MD5 · raw file

  1. // Copyright (c) 2010, Google Inc.
  2. // All rights reserved.
  3. //
  4. // Redistribution and use in source and binary forms, with or without
  5. // modification, are permitted provided that the following conditions are
  6. // met:
  7. //
  8. // * Redistributions of source code must retain the above copyright
  9. // notice, this list of conditions and the following disclaimer.
  10. // * Redistributions in binary form must reproduce the above
  11. // copyright notice, this list of conditions and the following disclaimer
  12. // in the documentation and/or other materials provided with the
  13. // distribution.
  14. // * Neither the name of Google Inc. nor the names of its
  15. // contributors may be used to endorse or promote products derived from
  16. // this software without specific prior written permission.
  17. //
  18. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  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.
  29. // Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
  30. // stackwalker_arm_unittest.cc: Unit tests for StackwalkerARM class.
  31. #include <string>
  32. #include <string.h>
  33. #include <vector>
  34. #include "breakpad_googletest_includes.h"
  35. #include "common/test_assembler.h"
  36. #include "google_breakpad/common/minidump_format.h"
  37. #include "google_breakpad/processor/basic_source_line_resolver.h"
  38. #include "google_breakpad/processor/call_stack.h"
  39. #include "google_breakpad/processor/source_line_resolver_interface.h"
  40. #include "google_breakpad/processor/stack_frame_cpu.h"
  41. #include "processor/stackwalker_unittest_utils.h"
  42. #include "processor/stackwalker_arm.h"
  43. #include "processor/windows_frame_info.h"
  44. using google_breakpad::BasicSourceLineResolver;
  45. using google_breakpad::CallStack;
  46. using google_breakpad::StackFrame;
  47. using google_breakpad::StackFrameARM;
  48. using google_breakpad::StackwalkerARM;
  49. using google_breakpad::SystemInfo;
  50. using google_breakpad::WindowsFrameInfo;
  51. using google_breakpad::test_assembler::kLittleEndian;
  52. using google_breakpad::test_assembler::Label;
  53. using google_breakpad::test_assembler::Section;
  54. using std::string;
  55. using std::vector;
  56. using testing::_;
  57. using testing::Return;
  58. using testing::SetArgumentPointee;
  59. using testing::Test;
  60. class StackwalkerARMFixture {
  61. public:
  62. StackwalkerARMFixture()
  63. : stack_section(kLittleEndian),
  64. // Give the two modules reasonable standard locations and names
  65. // for tests to play with.
  66. module1(0x40000000, 0x10000, "module1", "version1"),
  67. module2(0x50000000, 0x10000, "module2", "version2") {
  68. // Identify the system as a Linux system.
  69. system_info.os = "Linux";
  70. system_info.os_short = "linux";
  71. system_info.os_version = "Lugubrious Labrador";
  72. system_info.cpu = "arm";
  73. system_info.cpu_info = "";
  74. // Put distinctive values in the raw CPU context.
  75. BrandContext(&raw_context);
  76. // Create some modules with some stock debugging information.
  77. modules.Add(&module1);
  78. modules.Add(&module2);
  79. // By default, none of the modules have symbol info; call
  80. // SetModuleSymbols to override this.
  81. EXPECT_CALL(supplier, GetCStringSymbolData(_, _, _, _))
  82. .WillRepeatedly(Return(MockSymbolSupplier::NOT_FOUND));
  83. }
  84. // Set the Breakpad symbol information that supplier should return for
  85. // MODULE to INFO.
  86. void SetModuleSymbols(MockCodeModule *module, const string &info) {
  87. unsigned int buffer_size = info.size() + 1;
  88. char *buffer = reinterpret_cast<char*>(operator new(buffer_size));
  89. strcpy(buffer, info.c_str());
  90. EXPECT_CALL(supplier, GetCStringSymbolData(module, &system_info, _, _))
  91. .WillRepeatedly(DoAll(SetArgumentPointee<3>(buffer),
  92. Return(MockSymbolSupplier::FOUND)));
  93. }
  94. // Populate stack_region with the contents of stack_section. Use
  95. // stack_section.start() as the region's starting address.
  96. void RegionFromSection() {
  97. string contents;
  98. ASSERT_TRUE(stack_section.GetContents(&contents));
  99. stack_region.Init(stack_section.start().Value(), contents);
  100. }
  101. // Fill RAW_CONTEXT with pseudo-random data, for round-trip checking.
  102. void BrandContext(MDRawContextARM *raw_context) {
  103. u_int8_t x = 173;
  104. for (size_t i = 0; i < sizeof(*raw_context); i++)
  105. reinterpret_cast<u_int8_t *>(raw_context)[i] = (x += 17);
  106. }
  107. SystemInfo system_info;
  108. MDRawContextARM raw_context;
  109. Section stack_section;
  110. MockMemoryRegion stack_region;
  111. MockCodeModule module1;
  112. MockCodeModule module2;
  113. MockCodeModules modules;
  114. MockSymbolSupplier supplier;
  115. BasicSourceLineResolver resolver;
  116. CallStack call_stack;
  117. const vector<StackFrame *> *frames;
  118. };
  119. class SanityCheck: public StackwalkerARMFixture, public Test { };
  120. TEST_F(SanityCheck, NoResolver) {
  121. // Since we have no call frame information, and all unwinding
  122. // requires call frame information, the stack walk will end after
  123. // the first frame.
  124. StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
  125. NULL, NULL);
  126. // This should succeed even without a resolver or supplier.
  127. ASSERT_TRUE(walker.Walk(&call_stack));
  128. frames = call_stack.frames();
  129. ASSERT_EQ(1U, frames->size());
  130. StackFrameARM *frame = static_cast<StackFrameARM *>(frames->at(0));
  131. // Check that the values from the original raw context made it
  132. // through to the context in the stack frame.
  133. EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context)));
  134. }
  135. class GetContextFrame: public StackwalkerARMFixture, public Test { };
  136. TEST_F(GetContextFrame, Simple) {
  137. // Since we have no call frame information, and all unwinding
  138. // requires call frame information, the stack walk will end after
  139. // the first frame.
  140. StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
  141. &supplier, &resolver);
  142. ASSERT_TRUE(walker.Walk(&call_stack));
  143. frames = call_stack.frames();
  144. ASSERT_EQ(1U, frames->size());
  145. StackFrameARM *frame = static_cast<StackFrameARM *>(frames->at(0));
  146. // Check that the values from the original raw context made it
  147. // through to the context in the stack frame.
  148. EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context)));
  149. }
  150. class GetCallerFrame: public StackwalkerARMFixture, public Test { };
  151. TEST_F(GetCallerFrame, ScanWithoutSymbols) {
  152. // When the stack walker resorts to scanning the stack,
  153. // only addresses located within loaded modules are
  154. // considered valid return addresses.
  155. // Force scanning through three frames to ensure that the
  156. // stack pointer is set properly in scan-recovered frames.
  157. stack_section.start() = 0x80000000;
  158. u_int32_t return_address1 = 0x50000100;
  159. u_int32_t return_address2 = 0x50000900;
  160. Label frame1_sp, frame2_sp;
  161. stack_section
  162. // frame 0
  163. .Append(16, 0) // space
  164. .D32(0x40090000) // junk that's not
  165. .D32(0x60000000) // a return address
  166. .D32(return_address1) // actual return address
  167. // frame 1
  168. .Mark(&frame1_sp)
  169. .Append(16, 0) // space
  170. .D32(0xF0000000) // more junk
  171. .D32(0x0000000D)
  172. .D32(return_address2) // actual return address
  173. // frame 2
  174. .Mark(&frame2_sp)
  175. .Append(32, 0); // end of stack
  176. RegionFromSection();
  177. raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40005510;
  178. raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value();
  179. StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
  180. &supplier, &resolver);
  181. ASSERT_TRUE(walker.Walk(&call_stack));
  182. frames = call_stack.frames();
  183. ASSERT_EQ(3U, frames->size());
  184. StackFrameARM *frame0 = static_cast<StackFrameARM *>(frames->at(0));
  185. EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
  186. ASSERT_EQ(StackFrameARM::CONTEXT_VALID_ALL, frame0->context_validity);
  187. EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
  188. StackFrameARM *frame1 = static_cast<StackFrameARM *>(frames->at(1));
  189. EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
  190. ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC |
  191. StackFrameARM::CONTEXT_VALID_SP),
  192. frame1->context_validity);
  193. EXPECT_EQ(return_address1, frame1->context.iregs[MD_CONTEXT_ARM_REG_PC]);
  194. EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]);
  195. StackFrameARM *frame2 = static_cast<StackFrameARM *>(frames->at(2));
  196. EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame2->trust);
  197. ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC |
  198. StackFrameARM::CONTEXT_VALID_SP),
  199. frame2->context_validity);
  200. EXPECT_EQ(return_address2, frame2->context.iregs[MD_CONTEXT_ARM_REG_PC]);
  201. EXPECT_EQ(frame2_sp.Value(), frame2->context.iregs[MD_CONTEXT_ARM_REG_SP]);
  202. }
  203. TEST_F(GetCallerFrame, ScanWithFunctionSymbols) {
  204. // During stack scanning, if a potential return address
  205. // is located within a loaded module that has symbols,
  206. // it is only considered a valid return address if it
  207. // lies within a function's bounds.
  208. stack_section.start() = 0x80000000;
  209. u_int32_t return_address = 0x50000200;
  210. Label frame1_sp;
  211. stack_section
  212. // frame 0
  213. .Append(16, 0) // space
  214. .D32(0x40090000) // junk that's not
  215. .D32(0x60000000) // a return address
  216. .D32(0x40001000) // a couple of plausible addresses
  217. .D32(0x5000F000) // that are not within functions
  218. .D32(return_address) // actual return address
  219. // frame 1
  220. .Mark(&frame1_sp)
  221. .Append(32, 0); // end of stack
  222. RegionFromSection();
  223. raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40000200;
  224. raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value();
  225. SetModuleSymbols(&module1,
  226. // The youngest frame's function.
  227. "FUNC 100 400 10 monotreme\n");
  228. SetModuleSymbols(&module2,
  229. // The calling frame's function.
  230. "FUNC 100 400 10 marsupial\n");
  231. StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
  232. &supplier, &resolver);
  233. ASSERT_TRUE(walker.Walk(&call_stack));
  234. frames = call_stack.frames();
  235. ASSERT_EQ(2U, frames->size());
  236. StackFrameARM *frame0 = static_cast<StackFrameARM *>(frames->at(0));
  237. EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
  238. ASSERT_EQ(StackFrameARM::CONTEXT_VALID_ALL, frame0->context_validity);
  239. EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
  240. EXPECT_EQ("monotreme", frame0->function_name);
  241. EXPECT_EQ(0x40000100, frame0->function_base);
  242. StackFrameARM *frame1 = static_cast<StackFrameARM *>(frames->at(1));
  243. EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
  244. ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC |
  245. StackFrameARM::CONTEXT_VALID_SP),
  246. frame1->context_validity);
  247. EXPECT_EQ(return_address, frame1->context.iregs[MD_CONTEXT_ARM_REG_PC]);
  248. EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]);
  249. EXPECT_EQ("marsupial", frame1->function_name);
  250. EXPECT_EQ(0x50000100, frame1->function_base);
  251. }
  252. struct CFIFixture: public StackwalkerARMFixture {
  253. CFIFixture() {
  254. // Provide a bunch of STACK CFI records; we'll walk to the caller
  255. // from every point in this series, expecting to find the same set
  256. // of register values.
  257. SetModuleSymbols(&module1,
  258. // The youngest frame's function.
  259. "FUNC 4000 1000 10 enchiridion\n"
  260. // Initially, nothing has been pushed on the stack,
  261. // and the return address is still in the link register.
  262. "STACK CFI INIT 4000 100 .cfa: sp .ra: lr\n"
  263. // Push r4, the frame pointer, and the link register.
  264. "STACK CFI 4001 .cfa: sp 12 + r4: .cfa 12 - ^"
  265. " r11: .cfa 8 - ^ .ra: .cfa 4 - ^\n"
  266. // Save r4..r7 in r0..r3: verify that we populate
  267. // the youngest frame with all the values we have.
  268. "STACK CFI 4002 r4: r0 r5: r1 r6: r2 r7: r3\n"
  269. // Restore r4..r7. Save the non-callee-saves register r1.
  270. "STACK CFI 4003 .cfa: sp 16 + r1: .cfa 16 - ^"
  271. " r4: r4 r5: r5 r6: r6 r7: r7\n"
  272. // Move the .cfa back four bytes, to point at the return
  273. // address, and restore the sp explicitly.
  274. "STACK CFI 4005 .cfa: sp 12 + r1: .cfa 12 - ^"
  275. " r11: .cfa 4 - ^ .ra: .cfa ^ sp: .cfa 4 +\n"
  276. // Recover the PC explicitly from a new stack slot;
  277. // provide garbage for the .ra.
  278. "STACK CFI 4006 .cfa: sp 16 + pc: .cfa 16 - ^\n"
  279. // The calling function.
  280. "FUNC 5000 1000 10 epictetus\n"
  281. // Mark it as end of stack.
  282. "STACK CFI INIT 5000 1000 .cfa: 0 .ra: 0\n"
  283. // A function whose CFI makes the stack pointer
  284. // go backwards.
  285. "FUNC 6000 1000 20 palinal\n"
  286. "STACK CFI INIT 6000 1000 .cfa: sp 4 - .ra: lr\n"
  287. // A function with CFI expressions that can't be
  288. // evaluated.
  289. "FUNC 7000 1000 20 rhetorical\n"
  290. "STACK CFI INIT 7000 1000 .cfa: moot .ra: ambiguous\n");
  291. // Provide some distinctive values for the caller's registers.
  292. expected.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40005510;
  293. expected.iregs[MD_CONTEXT_ARM_REG_SP] = 0x80000000;
  294. expected.iregs[4] = 0xb5d55e68;
  295. expected.iregs[5] = 0xebd134f3;
  296. expected.iregs[6] = 0xa31e74bc;
  297. expected.iregs[7] = 0x2dcb16b3;
  298. expected.iregs[8] = 0x2ada2137;
  299. expected.iregs[9] = 0xbbbb557d;
  300. expected.iregs[10] = 0x48bf8ca7;
  301. expected.iregs[MD_CONTEXT_ARM_REG_FP] = 0x8112e110;
  302. // Expect CFI to recover all callee-saves registers. Since CFI is the
  303. // only stack frame construction technique we have, aside from the
  304. // context frame itself, there's no way for us to have a set of valid
  305. // registers smaller than this.
  306. expected_validity = (StackFrameARM::CONTEXT_VALID_PC |
  307. StackFrameARM::CONTEXT_VALID_SP |
  308. StackFrameARM::CONTEXT_VALID_R4 |
  309. StackFrameARM::CONTEXT_VALID_R5 |
  310. StackFrameARM::CONTEXT_VALID_R6 |
  311. StackFrameARM::CONTEXT_VALID_R7 |
  312. StackFrameARM::CONTEXT_VALID_R8 |
  313. StackFrameARM::CONTEXT_VALID_R9 |
  314. StackFrameARM::CONTEXT_VALID_R10 |
  315. StackFrameARM::CONTEXT_VALID_FP);
  316. // By default, context frames provide all registers, as normal.
  317. context_frame_validity = StackFrameARM::CONTEXT_VALID_ALL;
  318. // By default, registers are unchanged.
  319. raw_context = expected;
  320. }
  321. // Walk the stack, using stack_section as the contents of the stack
  322. // and raw_context as the current register values. (Set the stack
  323. // pointer to the stack's starting address.) Expect two stack
  324. // frames; in the older frame, expect the callee-saves registers to
  325. // have values matching those in 'expected'.
  326. void CheckWalk() {
  327. RegionFromSection();
  328. raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value();
  329. StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region,
  330. &modules, &supplier, &resolver);
  331. walker.SetContextFrameValidity(context_frame_validity);
  332. ASSERT_TRUE(walker.Walk(&call_stack));
  333. frames = call_stack.frames();
  334. ASSERT_EQ(2U, frames->size());
  335. StackFrameARM *frame0 = static_cast<StackFrameARM *>(frames->at(0));
  336. EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
  337. ASSERT_EQ(context_frame_validity, frame0->context_validity);
  338. EXPECT_EQ("enchiridion", frame0->function_name);
  339. EXPECT_EQ(0x40004000U, frame0->function_base);
  340. StackFrameARM *frame1 = static_cast<StackFrameARM *>(frames->at(1));
  341. EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
  342. ASSERT_EQ(expected_validity, frame1->context_validity);
  343. if (expected_validity & StackFrameARM::CONTEXT_VALID_R1)
  344. EXPECT_EQ(expected.iregs[1], frame1->context.iregs[1]);
  345. if (expected_validity & StackFrameARM::CONTEXT_VALID_R4)
  346. EXPECT_EQ(expected.iregs[4], frame1->context.iregs[4]);
  347. if (expected_validity & StackFrameARM::CONTEXT_VALID_R5)
  348. EXPECT_EQ(expected.iregs[5], frame1->context.iregs[5]);
  349. if (expected_validity & StackFrameARM::CONTEXT_VALID_R6)
  350. EXPECT_EQ(expected.iregs[6], frame1->context.iregs[6]);
  351. if (expected_validity & StackFrameARM::CONTEXT_VALID_R7)
  352. EXPECT_EQ(expected.iregs[7], frame1->context.iregs[7]);
  353. if (expected_validity & StackFrameARM::CONTEXT_VALID_R8)
  354. EXPECT_EQ(expected.iregs[8], frame1->context.iregs[8]);
  355. if (expected_validity & StackFrameARM::CONTEXT_VALID_R9)
  356. EXPECT_EQ(expected.iregs[9], frame1->context.iregs[9]);
  357. if (expected_validity & StackFrameARM::CONTEXT_VALID_R10)
  358. EXPECT_EQ(expected.iregs[10], frame1->context.iregs[10]);
  359. if (expected_validity & StackFrameARM::CONTEXT_VALID_FP)
  360. EXPECT_EQ(expected.iregs[MD_CONTEXT_ARM_REG_FP],
  361. frame1->context.iregs[MD_CONTEXT_ARM_REG_FP]);
  362. // We would never have gotten a frame in the first place if the SP
  363. // and PC weren't valid or ->instruction weren't set.
  364. EXPECT_EQ(expected.iregs[MD_CONTEXT_ARM_REG_SP],
  365. frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]);
  366. EXPECT_EQ(expected.iregs[MD_CONTEXT_ARM_REG_PC],
  367. frame1->context.iregs[MD_CONTEXT_ARM_REG_PC]);
  368. EXPECT_EQ(expected.iregs[MD_CONTEXT_ARM_REG_PC],
  369. frame1->instruction + 2);
  370. EXPECT_EQ("epictetus", frame1->function_name);
  371. }
  372. // The values we expect to find for the caller's registers.
  373. MDRawContextARM expected;
  374. // The validity mask for expected.
  375. int expected_validity;
  376. // The validity mask to impose on the context frame.
  377. int context_frame_validity;
  378. };
  379. class CFI: public CFIFixture, public Test { };
  380. TEST_F(CFI, At4000) {
  381. stack_section.start() = expected.iregs[MD_CONTEXT_ARM_REG_SP];
  382. raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004000;
  383. raw_context.iregs[MD_CONTEXT_ARM_REG_LR] = 0x40005510;
  384. CheckWalk();
  385. }
  386. TEST_F(CFI, At4001) {
  387. Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP];
  388. stack_section
  389. .D32(0xb5d55e68) // saved r4
  390. .D32(0x8112e110) // saved fp
  391. .D32(0x40005510) // return address
  392. .Mark(&frame1_sp); // This effectively sets stack_section.start().
  393. raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004001;
  394. raw_context.iregs[4] = 0x635adc9f; // distinct callee r4
  395. raw_context.iregs[MD_CONTEXT_ARM_REG_FP] = 0xbe145fc4; // distinct callee fp
  396. CheckWalk();
  397. }
  398. // As above, but unwind from a context that has only the PC and SP.
  399. TEST_F(CFI, At4001LimitedValidity) {
  400. context_frame_validity =
  401. StackFrameARM::CONTEXT_VALID_PC | StackFrameARM::CONTEXT_VALID_SP;
  402. raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004001;
  403. raw_context.iregs[MD_CONTEXT_ARM_REG_FP] = 0xbe145fc4; // distinct callee fp
  404. Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP];
  405. stack_section
  406. .D32(0xb5d55e68) // saved r4
  407. .D32(0x8112e110) // saved fp
  408. .D32(0x40005510) // return address
  409. .Mark(&frame1_sp); // This effectively sets stack_section.start().
  410. expected_validity = (StackFrameARM::CONTEXT_VALID_PC
  411. | StackFrameARM::CONTEXT_VALID_SP
  412. | StackFrameARM::CONTEXT_VALID_FP
  413. | StackFrameARM::CONTEXT_VALID_R4);
  414. CheckWalk();
  415. }
  416. TEST_F(CFI, At4002) {
  417. Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP];
  418. stack_section
  419. .D32(0xfb81ff3d) // no longer saved r4
  420. .D32(0x8112e110) // saved fp
  421. .D32(0x40005510) // return address
  422. .Mark(&frame1_sp); // This effectively sets stack_section.start().
  423. raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004002;
  424. raw_context.iregs[0] = 0xb5d55e68; // saved r4
  425. raw_context.iregs[1] = 0xebd134f3; // saved r5
  426. raw_context.iregs[2] = 0xa31e74bc; // saved r6
  427. raw_context.iregs[3] = 0x2dcb16b3; // saved r7
  428. raw_context.iregs[4] = 0xfdd35466; // distinct callee r4
  429. raw_context.iregs[5] = 0xf18c946c; // distinct callee r5
  430. raw_context.iregs[6] = 0xac2079e8; // distinct callee r6
  431. raw_context.iregs[7] = 0xa449829f; // distinct callee r7
  432. raw_context.iregs[MD_CONTEXT_ARM_REG_FP] = 0xbe145fc4; // distinct callee fp
  433. CheckWalk();
  434. }
  435. TEST_F(CFI, At4003) {
  436. Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP];
  437. stack_section
  438. .D32(0x48c8dd5a) // saved r1 (even though it's not callee-saves)
  439. .D32(0xcb78040e) // no longer saved r4
  440. .D32(0x8112e110) // saved fp
  441. .D32(0x40005510) // return address
  442. .Mark(&frame1_sp); // This effectively sets stack_section.start().
  443. raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004003;
  444. raw_context.iregs[1] = 0xfb756319; // distinct callee r1
  445. raw_context.iregs[MD_CONTEXT_ARM_REG_FP] = 0x0a2857ea; // distinct callee fp
  446. expected.iregs[1] = 0x48c8dd5a; // caller's r1
  447. expected_validity |= StackFrameARM::CONTEXT_VALID_R1;
  448. CheckWalk();
  449. }
  450. // We have no new rule at module offset 0x4004, so the results here should
  451. // be the same as those at module offset 0x4003.
  452. TEST_F(CFI, At4004) {
  453. Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP];
  454. stack_section
  455. .D32(0x48c8dd5a) // saved r1 (even though it's not callee-saves)
  456. .D32(0xcb78040e) // no longer saved r4
  457. .D32(0x8112e110) // saved fp
  458. .D32(0x40005510) // return address
  459. .Mark(&frame1_sp); // This effectively sets stack_section.start().
  460. raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004004;
  461. raw_context.iregs[1] = 0xfb756319; // distinct callee r1
  462. expected.iregs[1] = 0x48c8dd5a; // caller's r1
  463. expected_validity |= StackFrameARM::CONTEXT_VALID_R1;
  464. CheckWalk();
  465. }
  466. // Here we move the .cfa, but provide an explicit rule to recover the SP,
  467. // so again there should be no change in the registers recovered.
  468. TEST_F(CFI, At4005) {
  469. Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP];
  470. stack_section
  471. .D32(0x48c8dd5a) // saved r1 (even though it's not callee-saves)
  472. .D32(0xf013f841) // no longer saved r4
  473. .D32(0x8112e110) // saved fp
  474. .D32(0x40005510) // return address
  475. .Mark(&frame1_sp); // This effectively sets stack_section.start().
  476. raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004005;
  477. raw_context.iregs[1] = 0xfb756319; // distinct callee r1
  478. expected.iregs[1] = 0x48c8dd5a; // caller's r1
  479. expected_validity |= StackFrameARM::CONTEXT_VALID_R1;
  480. CheckWalk();
  481. }
  482. // Here we provide an explicit rule for the PC, and have the saved .ra be
  483. // bogus.
  484. TEST_F(CFI, At4006) {
  485. Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP];
  486. stack_section
  487. .D32(0x40005510) // saved pc
  488. .D32(0x48c8dd5a) // saved r1 (even though it's not callee-saves)
  489. .D32(0xf013f841) // no longer saved r4
  490. .D32(0x8112e110) // saved fp
  491. .D32(0xf8d15783) // .ra rule recovers this, which is garbage
  492. .Mark(&frame1_sp); // This effectively sets stack_section.start().
  493. raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004006;
  494. raw_context.iregs[1] = 0xfb756319; // callee's r1, different from caller's
  495. expected.iregs[1] = 0x48c8dd5a; // caller's r1
  496. expected_validity |= StackFrameARM::CONTEXT_VALID_R1;
  497. CheckWalk();
  498. }
  499. // Check that we reject rules that would cause the stack pointer to
  500. // move in the wrong direction.
  501. TEST_F(CFI, RejectBackwards) {
  502. raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40006000;
  503. raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = 0x80000000;
  504. raw_context.iregs[MD_CONTEXT_ARM_REG_LR] = 0x40005510;
  505. StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
  506. &supplier, &resolver);
  507. ASSERT_TRUE(walker.Walk(&call_stack));
  508. frames = call_stack.frames();
  509. ASSERT_EQ(1U, frames->size());
  510. }
  511. // Check that we reject rules whose expressions' evaluation fails.
  512. TEST_F(CFI, RejectBadExpressions) {
  513. raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40007000;
  514. raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = 0x80000000;
  515. StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
  516. &supplier, &resolver);
  517. ASSERT_TRUE(walker.Walk(&call_stack));
  518. frames = call_stack.frames();
  519. ASSERT_EQ(1U, frames->size());
  520. }
  521. class StackwalkerARMFixtureIOS : public StackwalkerARMFixture {
  522. public:
  523. StackwalkerARMFixtureIOS() {
  524. system_info.os = "iOS";
  525. system_info.os_short = "ios";
  526. }
  527. };
  528. class GetFramesByFramePointer: public StackwalkerARMFixtureIOS, public Test { };
  529. TEST_F(GetFramesByFramePointer, OnlyFramePointer) {
  530. stack_section.start() = 0x80000000;
  531. u_int32_t return_address1 = 0x50000100;
  532. u_int32_t return_address2 = 0x50000900;
  533. Label frame1_sp, frame2_sp;
  534. Label frame1_fp, frame2_fp;
  535. stack_section
  536. // frame 0
  537. .Append(32, 0) // Whatever values on the stack.
  538. .D32(0x0000000D) // junk that's not
  539. .D32(0xF0000000) // a return address.
  540. .Mark(&frame1_fp) // Next fp will point to the next value.
  541. .D32(frame2_fp) // Save current frame pointer.
  542. .D32(return_address2) // Save current link register.
  543. .Mark(&frame1_sp)
  544. // frame 1
  545. .Append(32, 0) // Whatever values on the stack.
  546. .D32(0x0000000D) // junk that's not
  547. .D32(0xF0000000) // a return address.
  548. .Mark(&frame2_fp)
  549. .D32(0)
  550. .D32(0)
  551. .Mark(&frame2_sp)
  552. // frame 2
  553. .Append(32, 0) // Whatever values on the stack.
  554. .D32(0x0000000D) // junk that's not
  555. .D32(0xF0000000); // a return address.
  556. RegionFromSection();
  557. raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40005510;
  558. raw_context.iregs[MD_CONTEXT_ARM_REG_LR] = return_address1;
  559. raw_context.iregs[MD_CONTEXT_ARM_REG_IOS_FP] = frame1_fp.Value();
  560. raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value();
  561. StackwalkerARM walker(&system_info, &raw_context, MD_CONTEXT_ARM_REG_IOS_FP,
  562. &stack_region, &modules, &supplier, &resolver);
  563. ASSERT_TRUE(walker.Walk(&call_stack));
  564. frames = call_stack.frames();
  565. ASSERT_EQ(3U, frames->size());
  566. StackFrameARM *frame0 = static_cast<StackFrameARM *>(frames->at(0));
  567. EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
  568. ASSERT_EQ(StackFrameARM::CONTEXT_VALID_ALL, frame0->context_validity);
  569. EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
  570. StackFrameARM *frame1 = static_cast<StackFrameARM *>(frames->at(1));
  571. EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust);
  572. ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC |
  573. StackFrameARM::CONTEXT_VALID_LR |
  574. StackFrameARM::RegisterValidFlag(MD_CONTEXT_ARM_REG_IOS_FP) |
  575. StackFrameARM::CONTEXT_VALID_SP),
  576. frame1->context_validity);
  577. EXPECT_EQ(return_address1, frame1->context.iregs[MD_CONTEXT_ARM_REG_PC]);
  578. EXPECT_EQ(return_address2, frame1->context.iregs[MD_CONTEXT_ARM_REG_LR]);
  579. EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]);
  580. EXPECT_EQ(frame2_fp.Value(),
  581. frame1->context.iregs[MD_CONTEXT_ARM_REG_IOS_FP]);
  582. StackFrameARM *frame2 = static_cast<StackFrameARM *>(frames->at(2));
  583. EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame2->trust);
  584. ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC |
  585. StackFrameARM::CONTEXT_VALID_LR |
  586. StackFrameARM::RegisterValidFlag(MD_CONTEXT_ARM_REG_IOS_FP) |
  587. StackFrameARM::CONTEXT_VALID_SP),
  588. frame2->context_validity);
  589. EXPECT_EQ(return_address2, frame2->context.iregs[MD_CONTEXT_ARM_REG_PC]);
  590. EXPECT_EQ(0, frame2->context.iregs[MD_CONTEXT_ARM_REG_LR]);
  591. EXPECT_EQ(frame2_sp.Value(), frame2->context.iregs[MD_CONTEXT_ARM_REG_SP]);
  592. EXPECT_EQ(0, frame2->context.iregs[MD_CONTEXT_ARM_REG_IOS_FP]);
  593. }
  594. TEST_F(GetFramesByFramePointer, FramePointerAndCFI) {
  595. // Provide the standatd STACK CFI records that is obtained when exmining an
  596. // executable produced by XCode.
  597. SetModuleSymbols(&module1,
  598. // Adding a function in CFI.
  599. "FUNC 4000 1000 10 enchiridion\n"
  600. "STACK CFI INIT 4000 100 .cfa: sp 0 + .ra: lr\n"
  601. "STACK CFI 4001 .cfa: sp 8 + .ra: .cfa -4 + ^"
  602. " r7: .cfa -8 + ^\n"
  603. "STACK CFI 4002 .cfa: r7 8 +\n"
  604. );
  605. stack_section.start() = 0x80000000;
  606. u_int32_t return_address1 = 0x40004010;
  607. u_int32_t return_address2 = 0x50000900;
  608. Label frame1_sp, frame2_sp;
  609. Label frame1_fp, frame2_fp;
  610. stack_section
  611. // frame 0
  612. .Append(32, 0) // Whatever values on the stack.
  613. .D32(0x0000000D) // junk that's not
  614. .D32(0xF0000000) // a return address.
  615. .Mark(&frame1_fp) // Next fp will point to the next value.
  616. .D32(frame2_fp) // Save current frame pointer.
  617. .D32(return_address2) // Save current link register.
  618. .Mark(&frame1_sp)
  619. // frame 1
  620. .Append(32, 0) // Whatever values on the stack.
  621. .D32(0x0000000D) // junk that's not
  622. .D32(0xF0000000) // a return address.
  623. .Mark(&frame2_fp)
  624. .D32(0)
  625. .D32(0)
  626. .Mark(&frame2_sp)
  627. // frame 2
  628. .Append(32, 0) // Whatever values on the stack.
  629. .D32(0x0000000D) // junk that's not
  630. .D32(0xF0000000); // a return address.
  631. RegionFromSection();
  632. raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x50000400;
  633. raw_context.iregs[MD_CONTEXT_ARM_REG_LR] = return_address1;
  634. raw_context.iregs[MD_CONTEXT_ARM_REG_IOS_FP] = frame1_fp.Value();
  635. raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value();
  636. StackwalkerARM walker(&system_info, &raw_context, MD_CONTEXT_ARM_REG_IOS_FP,
  637. &stack_region, &modules, &supplier, &resolver);
  638. ASSERT_TRUE(walker.Walk(&call_stack));
  639. frames = call_stack.frames();
  640. ASSERT_EQ(3U, frames->size());
  641. StackFrameARM *frame0 = static_cast<StackFrameARM *>(frames->at(0));
  642. EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
  643. ASSERT_EQ(StackFrameARM::CONTEXT_VALID_ALL, frame0->context_validity);
  644. EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
  645. StackFrameARM *frame1 = static_cast<StackFrameARM *>(frames->at(1));
  646. EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust);
  647. ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC |
  648. StackFrameARM::CONTEXT_VALID_LR |
  649. StackFrameARM::RegisterValidFlag(MD_CONTEXT_ARM_REG_IOS_FP) |
  650. StackFrameARM::CONTEXT_VALID_SP),
  651. frame1->context_validity);
  652. EXPECT_EQ(return_address1, frame1->context.iregs[MD_CONTEXT_ARM_REG_PC]);
  653. EXPECT_EQ(return_address2, frame1->context.iregs[MD_CONTEXT_ARM_REG_LR]);
  654. EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]);
  655. EXPECT_EQ(frame2_fp.Value(),
  656. frame1->context.iregs[MD_CONTEXT_ARM_REG_IOS_FP]);
  657. EXPECT_EQ("enchiridion", frame1->function_name);
  658. EXPECT_EQ(0x40004000U, frame1->function_base);
  659. StackFrameARM *frame2 = static_cast<StackFrameARM *>(frames->at(2));
  660. EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame2->trust);
  661. ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC |
  662. StackFrameARM::CONTEXT_VALID_LR |
  663. StackFrameARM::RegisterValidFlag(MD_CONTEXT_ARM_REG_IOS_FP) |
  664. StackFrameARM::CONTEXT_VALID_SP),
  665. frame2->context_validity);
  666. EXPECT_EQ(return_address2, frame2->context.iregs[MD_CONTEXT_ARM_REG_PC]);
  667. EXPECT_EQ(0, frame2->context.iregs[MD_CONTEXT_ARM_REG_LR]);
  668. EXPECT_EQ(frame2_sp.Value(), frame2->context.iregs[MD_CONTEXT_ARM_REG_SP]);
  669. EXPECT_EQ(0, frame2->context.iregs[MD_CONTEXT_ARM_REG_IOS_FP]);
  670. }