1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2018 John H. Baldwin <jhb@FreeBSD.org> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include <sys/cdefs.h> 29 __FBSDID("$FreeBSD$"); 30 31 #include <atf-c.h> 32 #include <ucontext.h> 33 34 static char uc_stack[16 * 1024]; 35 36 static void 37 check_1(int arg1) 38 { 39 40 ATF_REQUIRE_EQ(arg1, 1); 41 } 42 43 ATF_TC_WITHOUT_HEAD(makecontext_arg1); 44 ATF_TC_BODY(makecontext_arg1, tc) 45 { 46 ucontext_t ctx[2]; 47 48 ATF_REQUIRE_EQ(getcontext(&ctx[1]), 0); 49 ctx[1].uc_stack.ss_sp = uc_stack; 50 ctx[1].uc_stack.ss_size = sizeof(uc_stack); 51 ctx[1].uc_link = &ctx[0]; 52 makecontext(&ctx[1], (void (*)(void))check_1, 1, 1); 53 54 ATF_REQUIRE_EQ(swapcontext(&ctx[0], &ctx[1]), 0); 55 } 56 57 static void 58 check_2(int arg1, int arg2) 59 { 60 61 ATF_REQUIRE_EQ(arg1, 1); 62 ATF_REQUIRE_EQ(arg2, 2); 63 } 64 65 ATF_TC_WITHOUT_HEAD(makecontext_arg2); 66 ATF_TC_BODY(makecontext_arg2, tc) 67 { 68 ucontext_t ctx[2]; 69 70 ATF_REQUIRE_EQ(getcontext(&ctx[1]), 0); 71 ctx[1].uc_stack.ss_sp = uc_stack; 72 ctx[1].uc_stack.ss_size = sizeof(uc_stack); 73 ctx[1].uc_link = &ctx[0]; 74 makecontext(&ctx[1], (void (*)(void))check_2, 2, 1, 2); 75 76 ATF_REQUIRE_EQ(swapcontext(&ctx[0], &ctx[1]), 0); 77 } 78 79 static void 80 check_3(int arg1, int arg2, int arg3) 81 { 82 83 ATF_REQUIRE_EQ(arg1, 1); 84 ATF_REQUIRE_EQ(arg2, 2); 85 ATF_REQUIRE_EQ(arg3, 3); 86 } 87 88 ATF_TC_WITHOUT_HEAD(makecontext_arg3); 89 ATF_TC_BODY(makecontext_arg3, tc) 90 { 91 ucontext_t ctx[2]; 92 93 ATF_REQUIRE_EQ(getcontext(&ctx[1]), 0); 94 ctx[1].uc_stack.ss_sp = uc_stack; 95 ctx[1].uc_stack.ss_size = sizeof(uc_stack); 96 ctx[1].uc_link = &ctx[0]; 97 makecontext(&ctx[1], (void (*)(void))check_3, 3, 1, 2, 3); 98 99 ATF_REQUIRE_EQ(swapcontext(&ctx[0], &ctx[1]), 0); 100 } 101 102 static void 103 check_4(int arg1, int arg2, int arg3, int arg4) 104 { 105 106 ATF_REQUIRE_EQ(arg1, 1); 107 ATF_REQUIRE_EQ(arg2, 2); 108 ATF_REQUIRE_EQ(arg3, 3); 109 ATF_REQUIRE_EQ(arg4, 4); 110 } 111 112 ATF_TC_WITHOUT_HEAD(makecontext_arg4); 113 ATF_TC_BODY(makecontext_arg4, tc) 114 { 115 ucontext_t ctx[2]; 116 117 ATF_REQUIRE_EQ(getcontext(&ctx[1]), 0); 118 ctx[1].uc_stack.ss_sp = uc_stack; 119 ctx[1].uc_stack.ss_size = sizeof(uc_stack); 120 ctx[1].uc_link = &ctx[0]; 121 makecontext(&ctx[1], (void (*)(void))check_4, 4, 1, 2, 3, 4); 122 123 ATF_REQUIRE_EQ(swapcontext(&ctx[0], &ctx[1]), 0); 124 } 125 126 static void 127 check_5(int arg1, int arg2, int arg3, int arg4, int arg5) 128 { 129 130 ATF_REQUIRE_EQ(arg1, 1); 131 ATF_REQUIRE_EQ(arg2, 2); 132 ATF_REQUIRE_EQ(arg3, 3); 133 ATF_REQUIRE_EQ(arg4, 4); 134 ATF_REQUIRE_EQ(arg5, 5); 135 } 136 137 ATF_TC_WITHOUT_HEAD(makecontext_arg5); 138 ATF_TC_BODY(makecontext_arg5, tc) 139 { 140 ucontext_t ctx[2]; 141 142 ATF_REQUIRE_EQ(getcontext(&ctx[1]), 0); 143 ctx[1].uc_stack.ss_sp = uc_stack; 144 ctx[1].uc_stack.ss_size = sizeof(uc_stack); 145 ctx[1].uc_link = &ctx[0]; 146 makecontext(&ctx[1], (void (*)(void))check_5, 5, 1, 2, 3, 4, 5); 147 148 ATF_REQUIRE_EQ(swapcontext(&ctx[0], &ctx[1]), 0); 149 } 150 151 static void 152 check_6(int arg1, int arg2, int arg3, int arg4, int arg5, int arg6) 153 { 154 155 ATF_REQUIRE_EQ(arg1, 1); 156 ATF_REQUIRE_EQ(arg2, 2); 157 ATF_REQUIRE_EQ(arg3, 3); 158 ATF_REQUIRE_EQ(arg4, 4); 159 ATF_REQUIRE_EQ(arg5, 5); 160 ATF_REQUIRE_EQ(arg6, 6); 161 } 162 163 ATF_TC_WITHOUT_HEAD(makecontext_arg6); 164 ATF_TC_BODY(makecontext_arg6, tc) 165 { 166 ucontext_t ctx[2]; 167 168 ATF_REQUIRE_EQ(getcontext(&ctx[1]), 0); 169 ctx[1].uc_stack.ss_sp = uc_stack; 170 ctx[1].uc_stack.ss_size = sizeof(uc_stack); 171 ctx[1].uc_link = &ctx[0]; 172 makecontext(&ctx[1], (void (*)(void))check_6, 6, 1, 2, 3, 4, 5, 6); 173 174 ATF_REQUIRE_EQ(swapcontext(&ctx[0], &ctx[1]), 0); 175 } 176 177 ATF_TP_ADD_TCS(tp) 178 { 179 180 ATF_TP_ADD_TC(tp, makecontext_arg1); 181 ATF_TP_ADD_TC(tp, makecontext_arg2); 182 ATF_TP_ADD_TC(tp, makecontext_arg3); 183 ATF_TP_ADD_TC(tp, makecontext_arg4); 184 ATF_TP_ADD_TC(tp, makecontext_arg5); 185 ATF_TP_ADD_TC(tp, makecontext_arg6); 186 187 return (atf_no_error()); 188 } 189