| 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 |