• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <stdio.h>
2 #include <stdint.h>
3 #include <stdlib.h>
4 
5 #include <libunwind.h>
6 
7 static int verbose;
8 static int nerrors;
9 
10 #define panic(args...)							  \
11 	do { printf (args); ++nerrors; } while (0)
12 
13 // Assembly routine which sets up the stack for the test then calls another one
14 // which clobbers the stack, and which in turn calls recover_register below
15 extern int64_t DW_CFA_expression_testcase(int64_t regnum, int64_t height);
16 
17 // recover_register is called by the assembly routines. It returns the value of
18 // a register at a specified height from the inner-most frame. The return value
19 // is propagated back through the assembly routines to the testcase.
recover_register(int64_t regnum,int64_t height)20 extern int64_t recover_register(int64_t regnum, int64_t height)
21 {
22   // Initialize cursor to current frame
23   int rc, i;
24   unw_cursor_t cursor;
25   unw_context_t context;
26   unw_getcontext(&context);
27   unw_init_local(&cursor, &context);
28   // Unwind frames until required height from inner-most frame (i.e. this one)
29   for (i = 0; i < height; ++i)
30     {
31       rc = unw_step(&cursor);
32       if (rc < 0)
33         panic("%s: unw_step failed on step %d with return code %d", __FUNCTION__, i, rc);
34       else if (rc == 0)
35         panic("%s: unw_step failed to reach the end of the stack", __FUNCTION__);
36       unw_word_t pc;
37       rc = unw_get_reg(&cursor, UNW_REG_IP, &pc);
38       if (rc < 0 || pc == 0)
39         panic("%s: unw_get_reg failed to locate the program counter", __FUNCTION__);
40     }
41   // We're now at the required height, extract register
42   uint64_t value;
43   if ((rc = unw_get_reg(&cursor, (unw_regnum_t) regnum, &value)) != 0)
44     panic("%s: unw_get_reg failed to retrieve register %lu", __FUNCTION__, regnum);
45   return value;
46 }
47 
48 int
main(int argc,char ** argv)49 main (int argc, char **argv)
50 {
51   if (argc > 1)
52     verbose = 1;
53 
54   if (DW_CFA_expression_testcase(12, 1) != 0)
55     panic("r12 should be clobbered at height 1 (DW_CFA_expression_inner)");
56   if (DW_CFA_expression_testcase(12, 2) != 111222333)
57     panic("r12 should be restored at height 2 (DW_CFA_expression_testcase)");
58 
59   if (nerrors > 0)
60     {
61       fprintf (stderr, "FAILURE: detected %d errors\n", nerrors);
62       exit (-1);
63     }
64 
65   if (verbose)
66     printf ("SUCCESS.\n");
67   return 0;
68 }
69