blob: 76421509ee995db8f42ba8dd539a2b83544bd4c3 [file] [log] [blame]
/*
* Copyright (c) 2012 The Native Client Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include <stdio.h>
#include <stdlib.h>
/* Prototypes to disable inlining. */
int inner(const char *, const char *) __attribute__((noinline));
int middle(const char *) __attribute__((noinline));
int outer(char *) __attribute__((noinline));
int alloca_size(void) __attribute__((noinline));
int inner(const char *outer_local, const char *middle_frame) {
const char local = 0;
fprintf(stderr,
"inner: outer_local = %p, &local = %p, "
"middle_frame = %p\n",
(void *) outer_local, (void *) &local, (void *) middle_frame);
if (outer_local >= &local) {
int inner_below_middle = middle_frame >= &local;
int middle_below_outer = outer_local >= middle_frame;
fprintf(stderr, "inner: stack grows downwards, "
" middle_below_outer %d, inner_below_middle %d\n",
middle_below_outer, inner_below_middle);
return middle_below_outer && inner_below_middle;
}
else {
int inner_above_middle = middle_frame <= &local;
int middle_above_outer = outer_local <= middle_frame;
fprintf(stderr, "inner: stack grows upwards, "
" middle_above_outer %d, inner_above_middle %d\n",
middle_above_outer, inner_above_middle);
return middle_above_outer && inner_above_middle;
}
}
int middle(const char *outer_local) {
const char *frame = __builtin_frame_address (0);
int retval;
fprintf(stderr, "middle: outer_local = %p, frame = %p\n",
(void *) outer_local, (void *) frame);
retval = inner(outer_local, frame);
/* fprintf also disables tail call optimization. */
fprintf(stderr, "middle: inner returned %d\n", retval);
return retval != 0;
}
int outer(char *dummy) {
const char local = 0;
int retval;
fprintf(stderr, "outer: &local = %p\n", (void *) &local);
retval = middle(&local);
/* fprintf also disables tail call optimization. */
fprintf(stderr, "outer: middle returned %d\n", retval);
return retval != 0;
}
int alloca_size(void) {
return 8;
}
int main (void) {
char *dummy = __builtin_alloca(alloca_size());
int retval;
fprintf(stderr, "main: dummy = %p\n", (void *) dummy);
retval = outer(dummy);
fprintf(stderr, "main: outer returned %d\n", retval);
if (retval == 0)
abort();
return 0;
}