1fb0e92637bf32a414114a6541d5436f462343a7fEdward O'Callaghan/* ===-- trampoline_setup_test.c - Test __trampoline_setup -----------------===
2fb0e92637bf32a414114a6541d5436f462343a7fEdward O'Callaghan *
3fb0e92637bf32a414114a6541d5436f462343a7fEdward O'Callaghan *                     The LLVM Compiler Infrastructure
4fb0e92637bf32a414114a6541d5436f462343a7fEdward O'Callaghan *
59ad441ffec97db647fee3725b3424284fb913e14Howard Hinnant * This file is dual licensed under the MIT and the University of Illinois Open
69ad441ffec97db647fee3725b3424284fb913e14Howard Hinnant * Source Licenses. See LICENSE.TXT for details.
7fb0e92637bf32a414114a6541d5436f462343a7fEdward O'Callaghan *
8fb0e92637bf32a414114a6541d5436f462343a7fEdward O'Callaghan * ===----------------------------------------------------------------------===
9fb0e92637bf32a414114a6541d5436f462343a7fEdward O'Callaghan */
10b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
11b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
12b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#include <stdio.h>
13b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#include <string.h>
14b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#include <stdint.h>
15b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#include <sys/mman.h>
16b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
17fb0e92637bf32a414114a6541d5436f462343a7fEdward O'Callaghan/*
18fb0e92637bf32a414114a6541d5436f462343a7fEdward O'Callaghan * Tests nested functions
19fb0e92637bf32a414114a6541d5436f462343a7fEdward O'Callaghan * The ppc compiler generates a call to __trampoline_setup
20fb0e92637bf32a414114a6541d5436f462343a7fEdward O'Callaghan * The i386 and x86_64 compilers generate a call to ___enable_execute_stack
21fb0e92637bf32a414114a6541d5436f462343a7fEdward O'Callaghan */
22fb0e92637bf32a414114a6541d5436f462343a7fEdward O'Callaghan
23fb0e92637bf32a414114a6541d5436f462343a7fEdward O'Callaghan/*
24fb0e92637bf32a414114a6541d5436f462343a7fEdward O'Callaghan * Note that, nested functions are not ISO C and are not supported in Clang.
25fb0e92637bf32a414114a6541d5436f462343a7fEdward O'Callaghan */
26fb0e92637bf32a414114a6541d5436f462343a7fEdward O'Callaghan
2726d53d047263ca5f5afd81b0c0ecc6d35acebf53Daniel Dunbar#if !defined(__clang__)
28b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
29b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbartypedef int (*nested_func_t)(int x);
30b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
31b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbarnested_func_t proc;
32b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
3326d53d047263ca5f5afd81b0c0ecc6d35acebf53Daniel Dunbarint main() {
34fb0e92637bf32a414114a6541d5436f462343a7fEdward O'Callaghan    /* Some locals */
35b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    int c = 10;
36b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    int d = 7;
37b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
38fb0e92637bf32a414114a6541d5436f462343a7fEdward O'Callaghan    /* Define a nested function: */
39b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    int bar(int x) { return x*5 + c*d; };
40b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
41fb0e92637bf32a414114a6541d5436f462343a7fEdward O'Callaghan    /* Assign global to point to nested function
42fb0e92637bf32a414114a6541d5436f462343a7fEdward O'Callaghan     * (really points to trampoline). */
43b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    proc = bar;
44b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
45fb0e92637bf32a414114a6541d5436f462343a7fEdward O'Callaghan    /* Invoke nested function: */
46b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    c = 4;
47b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    if ( (*proc)(3) != 43 )
48b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        return 1;
49b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    d = 5;
50b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    if ( (*proc)(4) != 40 )
51b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        return 1;
52b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
53fb0e92637bf32a414114a6541d5436f462343a7fEdward O'Callaghan    /* Success. */
54b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    return 0;
55b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar}
56fb0e92637bf32a414114a6541d5436f462343a7fEdward O'Callaghan
5726d53d047263ca5f5afd81b0c0ecc6d35acebf53Daniel Dunbar#else
5826d53d047263ca5f5afd81b0c0ecc6d35acebf53Daniel Dunbar
5926d53d047263ca5f5afd81b0c0ecc6d35acebf53Daniel Dunbarint main() {
607482815716cd9b87931d82dca7298fc3c707229fJoerg Sonnenberger    printf("skipped\n");
617482815716cd9b87931d82dca7298fc3c707229fJoerg Sonnenberger    return 0;
6226d53d047263ca5f5afd81b0c0ecc6d35acebf53Daniel Dunbar}
6326d53d047263ca5f5afd81b0c0ecc6d35acebf53Daniel Dunbar
6426d53d047263ca5f5afd81b0c0ecc6d35acebf53Daniel Dunbar#endif
65