OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. |
3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
5 */ | 5 */ |
6 | 6 |
7 #include <stdio.h> | 7 #include <stdio.h> |
8 #include <stdlib.h> | 8 #include <stdlib.h> |
9 | 9 |
10 /* Prototypes to disable inlining. */ | 10 /* Prototypes to disable inlining. */ |
11 int inner(const char *, const char *) __attribute__((noinline)); | 11 int inner(const char *, const char *) __attribute__((noinline)); |
12 int middle(const char *) __attribute__((noinline)); | 12 int middle(const char *) __attribute__((noinline)); |
13 int outer(char *) __attribute__((noinline)); | 13 int outer(char *) __attribute__((noinline)); |
14 int alloca_size(void) __attribute__((noinline)); | 14 int alloca_size(void) __attribute__((noinline)); |
15 | 15 |
16 | 16 |
17 int inner(const char *outer_local, const char *middle_frame) { | 17 int inner(const char *outer_local, const char *middle_frame) { |
18 const char local = 0; | 18 const char local = 0; |
19 | 19 |
20 fprintf(stderr, | 20 fprintf(stderr, |
21 "inner: outer_local = %p, &local = %p, " | 21 "inner: outer_local = %p, &local = %p, " |
22 "middle_frame = %p\n", | 22 "middle_frame = %p\n", |
23 outer_local, &local, middle_frame); | 23 (void *)outer_local, (void *)&local, (void *)middle_frame); |
24 if (outer_local >= &local) { | 24 if (outer_local >= &local) { |
25 int inner_below_middle = middle_frame >= &local; | 25 int inner_below_middle = middle_frame >= &local; |
26 int middle_below_outer = outer_local >= middle_frame; | 26 int middle_below_outer = outer_local >= middle_frame; |
27 fprintf(stderr, "inner: stack grows downwards, " | 27 fprintf(stderr, "inner: stack grows downwards, " |
28 " middle_below_outer %d, inner_below_middle %d\n", | 28 " middle_below_outer %d, inner_below_middle %d\n", |
29 middle_below_outer, inner_below_middle); | 29 middle_below_outer, inner_below_middle); |
30 return middle_below_outer && inner_below_middle; | 30 return middle_below_outer && inner_below_middle; |
31 } | 31 } |
32 else { | 32 else { |
33 int inner_above_middle = middle_frame <= &local; | 33 int inner_above_middle = middle_frame <= &local; |
34 int middle_above_outer = outer_local <= middle_frame; | 34 int middle_above_outer = outer_local <= middle_frame; |
35 fprintf(stderr, "inner: stack grows upwards, " | 35 fprintf(stderr, "inner: stack grows upwards, " |
36 " middle_above_outer %d, inner_above_middle %d\n", | 36 " middle_above_outer %d, inner_above_middle %d\n", |
37 middle_above_outer, inner_above_middle); | 37 middle_above_outer, inner_above_middle); |
38 return middle_above_outer && inner_above_middle; | 38 return middle_above_outer && inner_above_middle; |
39 } | 39 } |
40 } | 40 } |
41 | 41 |
42 int middle(const char *outer_local) { | 42 int middle(const char *outer_local) { |
43 const char *frame = __builtin_frame_address (0); | 43 const char *frame = __builtin_frame_address (0); |
44 int retval; | 44 int retval; |
45 | 45 |
46 fprintf(stderr, "middle: outer_local = %p, frame = %p\n", outer_local, frame); | 46 fprintf(stderr, "middle: outer_local = %p, frame = %p\n", |
| 47 (void *)outer_local, (void *)frame); |
47 retval = inner(outer_local, frame); | 48 retval = inner(outer_local, frame); |
48 /* fprintf also disables tail call optimization. */ | 49 /* fprintf also disables tail call optimization. */ |
49 fprintf(stderr, "middle: inner returned %d\n", retval); | 50 fprintf(stderr, "middle: inner returned %d\n", retval); |
50 return retval != 0; | 51 return retval != 0; |
51 } | 52 } |
52 | 53 |
53 int outer(char *dummy) { | 54 int outer(char *dummy) { |
54 const char local = 0; | 55 const char local = 0; |
55 int retval; | 56 int retval; |
56 | 57 |
57 fprintf(stderr, "outer: &local = %p\n", &local); | 58 fprintf(stderr, "outer: &local = %p\n", (void *)&local); |
58 retval = middle(&local); | 59 retval = middle(&local); |
59 /* fprintf also disables tail call optimization. */ | 60 /* fprintf also disables tail call optimization. */ |
60 fprintf(stderr, "outer: middle returned %d\n", retval); | 61 fprintf(stderr, "outer: middle returned %d\n", retval); |
61 return retval != 0; | 62 return retval != 0; |
62 } | 63 } |
63 | 64 |
64 int alloca_size(void) { | 65 int alloca_size(void) { |
65 return 8; | 66 return 8; |
66 } | 67 } |
67 | 68 |
68 int main (void) { | 69 int main (void) { |
69 char *dummy = __builtin_alloca(alloca_size()); | 70 char *dummy = __builtin_alloca(alloca_size()); |
70 int retval; | 71 int retval; |
71 | 72 |
72 fprintf(stderr, "main: dummy = %p\n", dummy); | 73 fprintf(stderr, "main: dummy = %p\n", (void *)dummy); |
73 retval = outer(dummy); | 74 retval = outer(dummy); |
74 fprintf(stderr, "main: outer returned %d\n", retval); | 75 fprintf(stderr, "main: outer returned %d\n", retval); |
75 if (retval == 0) | 76 if (retval == 0) |
76 abort(); | 77 abort(); |
77 return 0; | 78 return 0; |
78 } | 79 } |
OLD | NEW |