1/* SPDX-License-Identifier: GPL-2.0 */
2
3#define _GNU_SOURCE
4#define _LARGEFILE64_SOURCE
5
6/* libc-specific include files
7 * The program may be built in 3 ways:
8 *   $(CC) -nostdlib -include /path/to/nolibc.h => NOLIBC already defined
9 *   $(CC) -nostdlib -I/path/to/nolibc/sysroot  => _NOLIBC_* guards are present
10 *   $(CC) with default libc                    => NOLIBC* never defined
11 */
12#ifndef NOLIBC
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#ifndef _NOLIBC_STDIO_H
17/* standard libcs need more includes */
18#include <sys/auxv.h>
19#include <sys/io.h>
20#include <sys/ioctl.h>
21#include <sys/mman.h>
22#include <sys/mount.h>
23#include <sys/prctl.h>
24#include <sys/reboot.h>
25#include <sys/stat.h>
26#include <sys/syscall.h>
27#include <sys/sysmacros.h>
28#include <sys/time.h>
29#include <sys/wait.h>
30#include <dirent.h>
31#include <errno.h>
32#include <fcntl.h>
33#include <poll.h>
34#include <sched.h>
35#include <signal.h>
36#include <stdarg.h>
37#include <stddef.h>
38#include <stdint.h>
39#include <unistd.h>
40#include <limits.h>
41#endif
42#endif
43
44/* for the type of int_fast16_t and int_fast32_t, musl differs from glibc and nolibc */
45#define SINT_MAX_OF_TYPE(type) (((type)1 << (sizeof(type) * 8 - 2)) - (type)1 + ((type)1 << (sizeof(type) * 8 - 2)))
46#define SINT_MIN_OF_TYPE(type) (-SINT_MAX_OF_TYPE(type) - 1)
47
48/* will be used to test initialization of environ */
49static char **test_envp;
50
51/* will be used to test initialization of argv */
52static char **test_argv;
53
54/* will be used to test initialization of argc */
55static int test_argc;
56
57/* will be used by some test cases as readable file, please don't write it */
58static const char *argv0;
59
60/* definition of a series of tests */
61struct test {
62	const char *name;              /* test name */
63	int (*func)(int min, int max); /* handler */
64};
65
66#ifndef _NOLIBC_STDLIB_H
67char *itoa(int i)
68{
69	static char buf[12];
70	int ret;
71
72	ret = snprintf(buf, sizeof(buf), "%d", i);
73	return (ret >= 0 && ret < sizeof(buf)) ? buf : "#err";
74}
75#endif
76
77#define CASE_ERR(err) \
78	case err: return #err
79
80/* returns the error name (e.g. "ENOENT") for common errors, "SUCCESS" for 0,
81 * or the decimal value for less common ones.
82 */
83static const char *errorname(int err)
84{
85	switch (err) {
86	case 0: return "SUCCESS";
87	CASE_ERR(EPERM);
88	CASE_ERR(ENOENT);
89	CASE_ERR(ESRCH);
90	CASE_ERR(EINTR);
91	CASE_ERR(EIO);
92	CASE_ERR(ENXIO);
93	CASE_ERR(E2BIG);
94	CASE_ERR(ENOEXEC);
95	CASE_ERR(EBADF);
96	CASE_ERR(ECHILD);
97	CASE_ERR(EAGAIN);
98	CASE_ERR(ENOMEM);
99	CASE_ERR(EACCES);
100	CASE_ERR(EFAULT);
101	CASE_ERR(ENOTBLK);
102	CASE_ERR(EBUSY);
103	CASE_ERR(EEXIST);
104	CASE_ERR(EXDEV);
105	CASE_ERR(ENODEV);
106	CASE_ERR(ENOTDIR);
107	CASE_ERR(EISDIR);
108	CASE_ERR(EINVAL);
109	CASE_ERR(ENFILE);
110	CASE_ERR(EMFILE);
111	CASE_ERR(ENOTTY);
112	CASE_ERR(ETXTBSY);
113	CASE_ERR(EFBIG);
114	CASE_ERR(ENOSPC);
115	CASE_ERR(ESPIPE);
116	CASE_ERR(EROFS);
117	CASE_ERR(EMLINK);
118	CASE_ERR(EPIPE);
119	CASE_ERR(EDOM);
120	CASE_ERR(ERANGE);
121	CASE_ERR(ENOSYS);
122	CASE_ERR(EOVERFLOW);
123	default:
124		return itoa(err);
125	}
126}
127
128static void putcharn(char c, size_t n)
129{
130	char buf[64];
131
132	memset(buf, c, n);
133	buf[n] = '\0';
134	fputs(buf, stdout);
135}
136
137enum RESULT {
138	OK,
139	FAIL,
140	SKIPPED,
141};
142
143static void result(int llen, enum RESULT r)
144{
145	const char *msg;
146
147	if (r == OK)
148		msg = "  [OK]";
149	else if (r == SKIPPED)
150		msg = "[SKIPPED]";
151	else
152		msg = " [FAIL]";
153
154	if (llen < 64)
155		putcharn(' ', 64 - llen);
156	puts(msg);
157}
158
159/* The tests below are intended to be used by the macroes, which evaluate
160 * expression <expr>, print the status to stdout, and update the "ret"
161 * variable to count failures. The functions themselves return the number
162 * of failures, thus either 0 or 1.
163 */
164
165#define EXPECT_ZR(cond, expr)				\
166	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_zr(expr, llen); } while (0)
167
168static __attribute__((unused))
169int expect_zr(int expr, int llen)
170{
171	int ret = !(expr == 0);
172
173	llen += printf(" = %d ", expr);
174	result(llen, ret ? FAIL : OK);
175	return ret;
176}
177
178
179#define EXPECT_NZ(cond, expr, val)			\
180	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_nz(expr, llen; } while (0)
181
182static __attribute__((unused))
183int expect_nz(int expr, int llen)
184{
185	int ret = !(expr != 0);
186
187	llen += printf(" = %d ", expr);
188	result(llen, ret ? FAIL : OK);
189	return ret;
190}
191
192
193#define EXPECT_EQ(cond, expr, val)				\
194	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_eq(expr, llen, val); } while (0)
195
196static __attribute__((unused))
197int expect_eq(uint64_t expr, int llen, uint64_t val)
198{
199	int ret = !(expr == val);
200
201	llen += printf(" = %lld ", (long long)expr);
202	result(llen, ret ? FAIL : OK);
203	return ret;
204}
205
206
207#define EXPECT_NE(cond, expr, val)				\
208	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ne(expr, llen, val); } while (0)
209
210static __attribute__((unused))
211int expect_ne(int expr, int llen, int val)
212{
213	int ret = !(expr != val);
214
215	llen += printf(" = %d ", expr);
216	result(llen, ret ? FAIL : OK);
217	return ret;
218}
219
220
221#define EXPECT_GE(cond, expr, val)				\
222	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ge(expr, llen, val); } while (0)
223
224static __attribute__((unused))
225int expect_ge(int expr, int llen, int val)
226{
227	int ret = !(expr >= val);
228
229	llen += printf(" = %d ", expr);
230	result(llen, ret ? FAIL : OK);
231	return ret;
232}
233
234
235#define EXPECT_GT(cond, expr, val)				\
236	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_gt(expr, llen, val); } while (0)
237
238static __attribute__((unused))
239int expect_gt(int expr, int llen, int val)
240{
241	int ret = !(expr > val);
242
243	llen += printf(" = %d ", expr);
244	result(llen, ret ? FAIL : OK);
245	return ret;
246}
247
248
249#define EXPECT_LE(cond, expr, val)				\
250	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_le(expr, llen, val); } while (0)
251
252static __attribute__((unused))
253int expect_le(int expr, int llen, int val)
254{
255	int ret = !(expr <= val);
256
257	llen += printf(" = %d ", expr);
258	result(llen, ret ? FAIL : OK);
259	return ret;
260}
261
262
263#define EXPECT_LT(cond, expr, val)				\
264	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_lt(expr, llen, val); } while (0)
265
266static __attribute__((unused))
267int expect_lt(int expr, int llen, int val)
268{
269	int ret = !(expr < val);
270
271	llen += printf(" = %d ", expr);
272	result(llen, ret ? FAIL : OK);
273	return ret;
274}
275
276
277#define EXPECT_SYSZR(cond, expr)				\
278	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_syszr(expr, llen); } while (0)
279
280static __attribute__((unused))
281int expect_syszr(int expr, int llen)
282{
283	int ret = 0;
284
285	if (expr) {
286		ret = 1;
287		llen += printf(" = %d %s ", expr, errorname(errno));
288		result(llen, FAIL);
289	} else {
290		llen += printf(" = %d ", expr);
291		result(llen, OK);
292	}
293	return ret;
294}
295
296
297#define EXPECT_SYSEQ(cond, expr, val)				\
298	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_syseq(expr, llen, val); } while (0)
299
300static __attribute__((unused))
301int expect_syseq(int expr, int llen, int val)
302{
303	int ret = 0;
304
305	if (expr != val) {
306		ret = 1;
307		llen += printf(" = %d %s ", expr, errorname(errno));
308		result(llen, FAIL);
309	} else {
310		llen += printf(" = %d ", expr);
311		result(llen, OK);
312	}
313	return ret;
314}
315
316
317#define EXPECT_SYSNE(cond, expr, val)				\
318	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_sysne(expr, llen, val); } while (0)
319
320static __attribute__((unused))
321int expect_sysne(int expr, int llen, int val)
322{
323	int ret = 0;
324
325	if (expr == val) {
326		ret = 1;
327		llen += printf(" = %d %s ", expr, errorname(errno));
328		result(llen, FAIL);
329	} else {
330		llen += printf(" = %d ", expr);
331		result(llen, OK);
332	}
333	return ret;
334}
335
336
337#define EXPECT_SYSER2(cond, expr, expret, experr1, experr2)		\
338	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_syserr2(expr, expret, experr1, experr2, llen); } while (0)
339
340#define EXPECT_SYSER(cond, expr, expret, experr)			\
341	EXPECT_SYSER2(cond, expr, expret, experr, 0)
342
343static __attribute__((unused))
344int expect_syserr2(int expr, int expret, int experr1, int experr2, int llen)
345{
346	int ret = 0;
347	int _errno = errno;
348
349	llen += printf(" = %d %s ", expr, errorname(_errno));
350	if (expr != expret || (_errno != experr1 && _errno != experr2)) {
351		ret = 1;
352		if (experr2 == 0)
353			llen += printf(" != (%d %s) ", expret, errorname(experr1));
354		else
355			llen += printf(" != (%d %s %s) ", expret, errorname(experr1), errorname(experr2));
356		result(llen, FAIL);
357	} else {
358		result(llen, OK);
359	}
360	return ret;
361}
362
363
364#define EXPECT_PTRZR(cond, expr)				\
365	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrzr(expr, llen); } while (0)
366
367static __attribute__((unused))
368int expect_ptrzr(const void *expr, int llen)
369{
370	int ret = 0;
371
372	llen += printf(" = <%p> ", expr);
373	if (expr) {
374		ret = 1;
375		result(llen, FAIL);
376	} else {
377		result(llen, OK);
378	}
379	return ret;
380}
381
382
383#define EXPECT_PTRNZ(cond, expr)				\
384	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrnz(expr, llen); } while (0)
385
386static __attribute__((unused))
387int expect_ptrnz(const void *expr, int llen)
388{
389	int ret = 0;
390
391	llen += printf(" = <%p> ", expr);
392	if (!expr) {
393		ret = 1;
394		result(llen, FAIL);
395	} else {
396		result(llen, OK);
397	}
398	return ret;
399}
400
401#define EXPECT_PTREQ(cond, expr, cmp)				\
402	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptreq(expr, llen, cmp); } while (0)
403
404static __attribute__((unused))
405int expect_ptreq(const void *expr, int llen, const void *cmp)
406{
407	int ret = 0;
408
409	llen += printf(" = <%p> ", expr);
410	if (expr != cmp) {
411		ret = 1;
412		result(llen, FAIL);
413	} else {
414		result(llen, OK);
415	}
416	return ret;
417}
418
419#define EXPECT_PTRNE(cond, expr, cmp)				\
420	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrne(expr, llen, cmp); } while (0)
421
422static __attribute__((unused))
423int expect_ptrne(const void *expr, int llen, const void *cmp)
424{
425	int ret = 0;
426
427	llen += printf(" = <%p> ", expr);
428	if (expr == cmp) {
429		ret = 1;
430		result(llen, FAIL);
431	} else {
432		result(llen, OK);
433	}
434	return ret;
435}
436
437#define EXPECT_PTRGE(cond, expr, cmp)				\
438	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrge(expr, llen, cmp); } while (0)
439
440static __attribute__((unused))
441int expect_ptrge(const void *expr, int llen, const void *cmp)
442{
443	int ret = !(expr >= cmp);
444
445	llen += printf(" = <%p> ", expr);
446	result(llen, ret ? FAIL : OK);
447	return ret;
448}
449
450#define EXPECT_PTRGT(cond, expr, cmp)				\
451	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrgt(expr, llen, cmp); } while (0)
452
453static __attribute__((unused))
454int expect_ptrgt(const void *expr, int llen, const void *cmp)
455{
456	int ret = !(expr > cmp);
457
458	llen += printf(" = <%p> ", expr);
459	result(llen, ret ? FAIL : OK);
460	return ret;
461}
462
463
464#define EXPECT_PTRLE(cond, expr, cmp)				\
465	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrle(expr, llen, cmp); } while (0)
466
467static __attribute__((unused))
468int expect_ptrle(const void *expr, int llen, const void *cmp)
469{
470	int ret = !(expr <= cmp);
471
472	llen += printf(" = <%p> ", expr);
473	result(llen, ret ? FAIL : OK);
474	return ret;
475}
476
477
478#define EXPECT_PTRLT(cond, expr, cmp)				\
479	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrlt(expr, llen, cmp); } while (0)
480
481static __attribute__((unused))
482int expect_ptrlt(const void *expr, int llen, const void *cmp)
483{
484	int ret = !(expr < cmp);
485
486	llen += printf(" = <%p> ", expr);
487	result(llen, ret ? FAIL : OK);
488	return ret;
489}
490
491#define EXPECT_PTRER2(cond, expr, expret, experr1, experr2)		\
492	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrerr2(expr, expret, experr1, experr2, llen); } while (0)
493
494#define EXPECT_PTRER(cond, expr, expret, experr)			\
495	EXPECT_PTRER2(cond, expr, expret, experr, 0)
496
497static __attribute__((unused))
498int expect_ptrerr2(const void *expr, const void *expret, int experr1, int experr2, int llen)
499{
500	int ret = 0;
501	int _errno = errno;
502
503	llen += printf(" = <%p> %s ", expr, errorname(_errno));
504	if (expr != expret || (_errno != experr1 && _errno != experr2)) {
505		ret = 1;
506		if (experr2 == 0)
507			llen += printf(" != (<%p> %s) ", expret, errorname(experr1));
508		else
509			llen += printf(" != (<%p> %s %s) ", expret, errorname(experr1), errorname(experr2));
510		result(llen, FAIL);
511	} else {
512		result(llen, OK);
513	}
514	return ret;
515}
516
517#define EXPECT_STRZR(cond, expr)				\
518	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_strzr(expr, llen); } while (0)
519
520static __attribute__((unused))
521int expect_strzr(const char *expr, int llen)
522{
523	int ret = 0;
524
525	llen += printf(" = <%s> ", expr);
526	if (expr) {
527		ret = 1;
528		result(llen, FAIL);
529	} else {
530		result(llen, OK);
531	}
532	return ret;
533}
534
535
536#define EXPECT_STRNZ(cond, expr)				\
537	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_strnz(expr, llen); } while (0)
538
539static __attribute__((unused))
540int expect_strnz(const char *expr, int llen)
541{
542	int ret = 0;
543
544	llen += printf(" = <%s> ", expr);
545	if (!expr) {
546		ret = 1;
547		result(llen, FAIL);
548	} else {
549		result(llen, OK);
550	}
551	return ret;
552}
553
554
555#define EXPECT_STREQ(cond, expr, cmp)				\
556	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_streq(expr, llen, cmp); } while (0)
557
558static __attribute__((unused))
559int expect_streq(const char *expr, int llen, const char *cmp)
560{
561	int ret = 0;
562
563	llen += printf(" = <%s> ", expr);
564	if (strcmp(expr, cmp) != 0) {
565		ret = 1;
566		result(llen, FAIL);
567	} else {
568		result(llen, OK);
569	}
570	return ret;
571}
572
573
574#define EXPECT_STRNE(cond, expr, cmp)				\
575	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_strne(expr, llen, cmp); } while (0)
576
577static __attribute__((unused))
578int expect_strne(const char *expr, int llen, const char *cmp)
579{
580	int ret = 0;
581
582	llen += printf(" = <%s> ", expr);
583	if (strcmp(expr, cmp) == 0) {
584		ret = 1;
585		result(llen, FAIL);
586	} else {
587		result(llen, OK);
588	}
589	return ret;
590}
591
592
593/* declare tests based on line numbers. There must be exactly one test per line. */
594#define CASE_TEST(name) \
595	case __LINE__: llen += printf("%d %s", test, #name);
596
597int run_startup(int min, int max)
598{
599	int test;
600	int ret = 0;
601	/* kernel at least passes HOME and TERM, shell passes more */
602	int env_total = 2;
603	/* checking NULL for argv/argv0, environ and _auxv is not enough, let's compare with sbrk(0) or &end */
604	extern char end;
605	char *brk = sbrk(0) != (void *)-1 ? sbrk(0) : &end;
606	/* differ from nolibc, both glibc and musl have no global _auxv */
607	const unsigned long *test_auxv = (void *)-1;
608#ifdef NOLIBC
609	test_auxv = _auxv;
610#endif
611
612	for (test = min; test >= 0 && test <= max; test++) {
613		int llen = 0; /* line length */
614
615		/* avoid leaving empty lines below, this will insert holes into
616		 * test numbers.
617		 */
618		switch (test + __LINE__ + 1) {
619		CASE_TEST(argc);             EXPECT_GE(1, test_argc, 1); break;
620		CASE_TEST(argv_addr);        EXPECT_PTRGT(1, test_argv, brk); break;
621		CASE_TEST(argv_environ);     EXPECT_PTRLT(1, test_argv, environ); break;
622		CASE_TEST(argv_total);       EXPECT_EQ(1, environ - test_argv - 1, test_argc ?: 1); break;
623		CASE_TEST(argv0_addr);       EXPECT_PTRGT(1, argv0, brk); break;
624		CASE_TEST(argv0_str);        EXPECT_STRNZ(1, argv0 > brk ? argv0 : NULL); break;
625		CASE_TEST(argv0_len);        EXPECT_GE(1,  argv0 > brk ? strlen(argv0) : 0, 1); break;
626		CASE_TEST(environ_addr);     EXPECT_PTRGT(1, environ, brk); break;
627		CASE_TEST(environ_envp);     EXPECT_PTREQ(1, environ, test_envp); break;
628		CASE_TEST(environ_auxv);     EXPECT_PTRLT(test_auxv != (void *)-1, environ, test_auxv); break;
629		CASE_TEST(environ_total);    EXPECT_GE(test_auxv != (void *)-1, (void *)test_auxv - (void *)environ - 1, env_total); break;
630		CASE_TEST(environ_HOME);     EXPECT_PTRNZ(1, getenv("HOME")); break;
631		CASE_TEST(auxv_addr);        EXPECT_PTRGT(test_auxv != (void *)-1, test_auxv, brk); break;
632		CASE_TEST(auxv_AT_UID);      EXPECT_EQ(1, getauxval(AT_UID), getuid()); break;
633		CASE_TEST(auxv_AT_PAGESZ);   EXPECT_GE(1, getauxval(AT_PAGESZ), 4096); break;
634		case __LINE__:
635			return ret; /* must be last */
636		/* note: do not set any defaults so as to permit holes above */
637		}
638	}
639	return ret;
640}
641
642
643/* used by some syscall tests below */
644int test_getdents64(const char *dir)
645{
646	char buffer[4096];
647	int fd, ret;
648	int err;
649
650	ret = fd = open(dir, O_RDONLY | O_DIRECTORY, 0);
651	if (ret < 0)
652		return ret;
653
654	ret = getdents64(fd, (void *)buffer, sizeof(buffer));
655	err = errno;
656	close(fd);
657
658	errno = err;
659	return ret;
660}
661
662int test_getpagesize(void)
663{
664	int x = getpagesize();
665	int c;
666
667	if (x < 0)
668		return x;
669
670#if defined(__x86_64__) || defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)
671	/*
672	 * x86 family is always 4K page.
673	 */
674	c = (x == 4096);
675#elif defined(__aarch64__)
676	/*
677	 * Linux aarch64 supports three values of page size: 4K, 16K, and 64K
678	 * which are selected at kernel compilation time.
679	 */
680	c = (x == 4096 || x == (16 * 1024) || x == (64 * 1024));
681#else
682	/*
683	 * Assuming other architectures must have at least 4K page.
684	 */
685	c = (x >= 4096);
686#endif
687
688	return !c;
689}
690
691int test_fork(void)
692{
693	int status;
694	pid_t pid;
695
696	/* flush the printf buffer to avoid child flush it */
697	fflush(stdout);
698	fflush(stderr);
699
700	pid = fork();
701
702	switch (pid) {
703	case -1:
704		return 1;
705
706	case 0:
707		exit(123);
708
709	default:
710		pid = waitpid(pid, &status, 0);
711
712		return pid == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 123;
713	}
714}
715
716int test_stat_timestamps(void)
717{
718	struct stat st;
719
720	if (sizeof(st.st_atim.tv_sec) != sizeof(st.st_atime))
721		return 1;
722
723	if (stat("/proc/self/", &st) && stat(argv0, &st) && stat("/", &st))
724		return 1;
725
726	if (st.st_atim.tv_sec != st.st_atime || st.st_atim.tv_nsec > 1000000000)
727		return 1;
728
729	if (st.st_mtim.tv_sec != st.st_mtime || st.st_mtim.tv_nsec > 1000000000)
730		return 1;
731
732	if (st.st_ctim.tv_sec != st.st_ctime || st.st_ctim.tv_nsec > 1000000000)
733		return 1;
734
735	return 0;
736}
737
738int test_mmap_munmap(void)
739{
740	int ret, fd, i, page_size;
741	void *mem;
742	size_t file_size, length;
743	off_t offset, pa_offset;
744	struct stat stat_buf;
745	const char * const files[] = {
746		"/dev/zero",
747		"/proc/1/exe", "/proc/self/exe",
748		argv0,
749		NULL
750	};
751
752	page_size = getpagesize();
753	if (page_size < 0)
754		return 1;
755
756	/* find a right file to mmap, existed and accessible */
757	for (i = 0; files[i] != NULL; i++) {
758		ret = fd = open(files[i], O_RDONLY);
759		if (ret == -1)
760			continue;
761		else
762			break;
763	}
764	if (ret == -1)
765		return 1;
766
767	ret = stat(files[i], &stat_buf);
768	if (ret == -1)
769		goto end;
770
771	/* file size of the special /dev/zero is 0, let's assign one manually */
772	if (i == 0)
773		file_size = 3*page_size;
774	else
775		file_size = stat_buf.st_size;
776
777	offset = file_size - 1;
778	if (offset < 0)
779		offset = 0;
780	length = file_size - offset;
781	pa_offset = offset & ~(page_size - 1);
782
783	mem = mmap(NULL, length + offset - pa_offset, PROT_READ, MAP_SHARED, fd, pa_offset);
784	if (mem == MAP_FAILED) {
785		ret = 1;
786		goto end;
787	}
788
789	ret = munmap(mem, length + offset - pa_offset);
790
791end:
792	close(fd);
793	return !!ret;
794}
795
796int test_pipe(void)
797{
798	const char *const msg = "hello, nolibc";
799	int pipefd[2];
800	char buf[32];
801	size_t len;
802
803	if (pipe(pipefd) == -1)
804		return 1;
805
806	write(pipefd[1], msg, strlen(msg));
807	close(pipefd[1]);
808	len = read(pipefd[0], buf, sizeof(buf));
809	close(pipefd[0]);
810
811	if (len != strlen(msg))
812		return 1;
813
814	return !!memcmp(buf, msg, len);
815}
816
817
818/* Run syscall tests between IDs <min> and <max>.
819 * Return 0 on success, non-zero on failure.
820 */
821int run_syscall(int min, int max)
822{
823	struct timeval tv;
824	struct timezone tz;
825	struct stat stat_buf;
826	int euid0;
827	int proc;
828	int test;
829	int tmp;
830	int ret = 0;
831	void *p1, *p2;
832	int has_gettid = 1;
833
834	/* <proc> indicates whether or not /proc is mounted */
835	proc = stat("/proc", &stat_buf) == 0;
836
837	/* this will be used to skip certain tests that can't be run unprivileged */
838	euid0 = geteuid() == 0;
839
840	/* from 2.30, glibc provides gettid() */
841#if defined(__GLIBC_MINOR__) && defined(__GLIBC__)
842	has_gettid = __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 30);
843#endif
844
845	for (test = min; test >= 0 && test <= max; test++) {
846		int llen = 0; /* line length */
847
848		/* avoid leaving empty lines below, this will insert holes into
849		 * test numbers.
850		 */
851		switch (test + __LINE__ + 1) {
852		CASE_TEST(getpid);            EXPECT_SYSNE(1, getpid(), -1); break;
853		CASE_TEST(getppid);           EXPECT_SYSNE(1, getppid(), -1); break;
854		CASE_TEST(gettid);            EXPECT_SYSNE(has_gettid, gettid(), -1); break;
855		CASE_TEST(getpgid_self);      EXPECT_SYSNE(1, getpgid(0), -1); break;
856		CASE_TEST(getpgid_bad);       EXPECT_SYSER(1, getpgid(-1), -1, ESRCH); break;
857		CASE_TEST(kill_0);            EXPECT_SYSZR(1, kill(getpid(), 0)); break;
858		CASE_TEST(kill_CONT);         EXPECT_SYSZR(1, kill(getpid(), 0)); break;
859		CASE_TEST(kill_BADPID);       EXPECT_SYSER(1, kill(INT_MAX, 0), -1, ESRCH); break;
860		CASE_TEST(sbrk_0);            EXPECT_PTRNE(1, sbrk(0), (void *)-1); break;
861		CASE_TEST(sbrk);              if ((p1 = p2 = sbrk(4096)) != (void *)-1) p2 = sbrk(-4096); EXPECT_SYSZR(1, (p2 == (void *)-1) || p2 == p1); break;
862		CASE_TEST(brk);               EXPECT_SYSZR(1, brk(sbrk(0))); break;
863		CASE_TEST(chdir_root);        EXPECT_SYSZR(1, chdir("/")); chdir(getenv("PWD")); break;
864		CASE_TEST(chdir_dot);         EXPECT_SYSZR(1, chdir(".")); break;
865		CASE_TEST(chdir_blah);        EXPECT_SYSER(1, chdir("/blah"), -1, ENOENT); break;
866		CASE_TEST(chmod_argv0);       EXPECT_SYSZR(1, chmod(argv0, 0555)); break;
867		CASE_TEST(chmod_self);        EXPECT_SYSER(proc, chmod("/proc/self", 0555), -1, EPERM); break;
868		CASE_TEST(chown_self);        EXPECT_SYSER(proc, chown("/proc/self", 0, 0), -1, EPERM); break;
869		CASE_TEST(chroot_root);       EXPECT_SYSZR(euid0, chroot("/")); break;
870		CASE_TEST(chroot_blah);       EXPECT_SYSER(1, chroot("/proc/self/blah"), -1, ENOENT); break;
871		CASE_TEST(chroot_exe);        EXPECT_SYSER(1, chroot(argv0), -1, ENOTDIR); break;
872		CASE_TEST(close_m1);          EXPECT_SYSER(1, close(-1), -1, EBADF); break;
873		CASE_TEST(close_dup);         EXPECT_SYSZR(1, close(dup(0))); break;
874		CASE_TEST(dup_0);             tmp = dup(0);  EXPECT_SYSNE(1, tmp, -1); close(tmp); break;
875		CASE_TEST(dup_m1);            tmp = dup(-1); EXPECT_SYSER(1, tmp, -1, EBADF); if (tmp != -1) close(tmp); break;
876		CASE_TEST(dup2_0);            tmp = dup2(0, 100);  EXPECT_SYSNE(1, tmp, -1); close(tmp); break;
877		CASE_TEST(dup2_m1);           tmp = dup2(-1, 100); EXPECT_SYSER(1, tmp, -1, EBADF); if (tmp != -1) close(tmp); break;
878		CASE_TEST(dup3_0);            tmp = dup3(0, 100, 0);  EXPECT_SYSNE(1, tmp, -1); close(tmp); break;
879		CASE_TEST(dup3_m1);           tmp = dup3(-1, 100, 0); EXPECT_SYSER(1, tmp, -1, EBADF); if (tmp != -1) close(tmp); break;
880		CASE_TEST(execve_root);       EXPECT_SYSER(1, execve("/", (char*[]){ [0] = "/", [1] = NULL }, NULL), -1, EACCES); break;
881		CASE_TEST(fork);              EXPECT_SYSZR(1, test_fork()); break;
882		CASE_TEST(getdents64_root);   EXPECT_SYSNE(1, test_getdents64("/"), -1); break;
883		CASE_TEST(getdents64_null);   EXPECT_SYSER(1, test_getdents64("/dev/null"), -1, ENOTDIR); break;
884		CASE_TEST(gettimeofday_tv);   EXPECT_SYSZR(1, gettimeofday(&tv, NULL)); break;
885		CASE_TEST(gettimeofday_tv_tz);EXPECT_SYSZR(1, gettimeofday(&tv, &tz)); break;
886		CASE_TEST(getpagesize);       EXPECT_SYSZR(1, test_getpagesize()); break;
887		CASE_TEST(ioctl_tiocinq);     EXPECT_SYSZR(1, ioctl(0, TIOCINQ, &tmp)); break;
888		CASE_TEST(ioctl_tiocinq);     EXPECT_SYSZR(1, ioctl(0, TIOCINQ, &tmp)); break;
889		CASE_TEST(link_root1);        EXPECT_SYSER(1, link("/", "/"), -1, EEXIST); break;
890		CASE_TEST(link_blah);         EXPECT_SYSER(1, link("/proc/self/blah", "/blah"), -1, ENOENT); break;
891		CASE_TEST(link_dir);          EXPECT_SYSER(euid0, link("/", "/blah"), -1, EPERM); break;
892		CASE_TEST(link_cross);        EXPECT_SYSER(proc, link("/proc/self/cmdline", "/blah"), -1, EXDEV); break;
893		CASE_TEST(lseek_m1);          EXPECT_SYSER(1, lseek(-1, 0, SEEK_SET), -1, EBADF); break;
894		CASE_TEST(lseek_0);           EXPECT_SYSER(1, lseek(0, 0, SEEK_SET), -1, ESPIPE); break;
895		CASE_TEST(mkdir_root);        EXPECT_SYSER(1, mkdir("/", 0755), -1, EEXIST); break;
896		CASE_TEST(mmap_bad);          EXPECT_PTRER(1, mmap(NULL, 0, PROT_READ, MAP_PRIVATE, 0, 0), MAP_FAILED, EINVAL); break;
897		CASE_TEST(munmap_bad);        EXPECT_SYSER(1, munmap((void *)1, 0), -1, EINVAL); break;
898		CASE_TEST(mmap_munmap_good);  EXPECT_SYSZR(1, test_mmap_munmap()); break;
899		CASE_TEST(open_tty);          EXPECT_SYSNE(1, tmp = open("/dev/null", 0), -1); if (tmp != -1) close(tmp); break;
900		CASE_TEST(open_blah);         EXPECT_SYSER(1, tmp = open("/proc/self/blah", 0), -1, ENOENT); if (tmp != -1) close(tmp); break;
901		CASE_TEST(pipe);              EXPECT_SYSZR(1, test_pipe()); break;
902		CASE_TEST(poll_null);         EXPECT_SYSZR(1, poll(NULL, 0, 0)); break;
903		CASE_TEST(poll_stdout);       EXPECT_SYSNE(1, ({ struct pollfd fds = { 1, POLLOUT, 0}; poll(&fds, 1, 0); }), -1); break;
904		CASE_TEST(poll_fault);        EXPECT_SYSER(1, poll((void *)1, 1, 0), -1, EFAULT); break;
905		CASE_TEST(prctl);             EXPECT_SYSER(1, prctl(PR_SET_NAME, (unsigned long)NULL, 0, 0, 0), -1, EFAULT); break;
906		CASE_TEST(read_badf);         EXPECT_SYSER(1, read(-1, &tmp, 1), -1, EBADF); break;
907		CASE_TEST(rmdir_blah);        EXPECT_SYSER(1, rmdir("/blah"), -1, ENOENT); break;
908		CASE_TEST(sched_yield);       EXPECT_SYSZR(1, sched_yield()); break;
909		CASE_TEST(select_null);       EXPECT_SYSZR(1, ({ struct timeval tv = { 0 }; select(0, NULL, NULL, NULL, &tv); })); break;
910		CASE_TEST(select_stdout);     EXPECT_SYSNE(1, ({ fd_set fds; FD_ZERO(&fds); FD_SET(1, &fds); select(2, NULL, &fds, NULL, NULL); }), -1); break;
911		CASE_TEST(select_fault);      EXPECT_SYSER(1, select(1, (void *)1, NULL, NULL, 0), -1, EFAULT); break;
912		CASE_TEST(stat_blah);         EXPECT_SYSER(1, stat("/proc/self/blah", &stat_buf), -1, ENOENT); break;
913		CASE_TEST(stat_fault);        EXPECT_SYSER(1, stat((void *)1, &stat_buf), -1, EFAULT); break;
914		CASE_TEST(stat_timestamps);   EXPECT_SYSZR(1, test_stat_timestamps()); break;
915		CASE_TEST(symlink_root);      EXPECT_SYSER(1, symlink("/", "/"), -1, EEXIST); break;
916		CASE_TEST(unlink_root);       EXPECT_SYSER(1, unlink("/"), -1, EISDIR); break;
917		CASE_TEST(unlink_blah);       EXPECT_SYSER(1, unlink("/proc/self/blah"), -1, ENOENT); break;
918		CASE_TEST(wait_child);        EXPECT_SYSER(1, wait(&tmp), -1, ECHILD); break;
919		CASE_TEST(waitpid_min);       EXPECT_SYSER(1, waitpid(INT_MIN, &tmp, WNOHANG), -1, ESRCH); break;
920		CASE_TEST(waitpid_child);     EXPECT_SYSER(1, waitpid(getpid(), &tmp, WNOHANG), -1, ECHILD); break;
921		CASE_TEST(write_badf);        EXPECT_SYSER(1, write(-1, &tmp, 1), -1, EBADF); break;
922		CASE_TEST(write_zero);        EXPECT_SYSZR(1, write(1, &tmp, 0)); break;
923		CASE_TEST(syscall_noargs);    EXPECT_SYSEQ(1, syscall(__NR_getpid), getpid()); break;
924		CASE_TEST(syscall_args);      EXPECT_SYSER(1, syscall(__NR_statx, 0, NULL, 0, 0, NULL), -1, EFAULT); break;
925		case __LINE__:
926			return ret; /* must be last */
927		/* note: do not set any defaults so as to permit holes above */
928		}
929	}
930	return ret;
931}
932
933int run_stdlib(int min, int max)
934{
935	int test;
936	int ret = 0;
937
938	for (test = min; test >= 0 && test <= max; test++) {
939		int llen = 0; /* line length */
940
941		/* avoid leaving empty lines below, this will insert holes into
942		 * test numbers.
943		 */
944		switch (test + __LINE__ + 1) {
945		CASE_TEST(getenv_TERM);        EXPECT_STRNZ(1, getenv("TERM")); break;
946		CASE_TEST(getenv_blah);        EXPECT_STRZR(1, getenv("blah")); break;
947		CASE_TEST(setcmp_blah_blah);   EXPECT_EQ(1, strcmp("blah", "blah"), 0); break;
948		CASE_TEST(setcmp_blah_blah2);  EXPECT_NE(1, strcmp("blah", "blah2"), 0); break;
949		CASE_TEST(setncmp_blah_blah);  EXPECT_EQ(1, strncmp("blah", "blah", 10), 0); break;
950		CASE_TEST(setncmp_blah_blah4); EXPECT_EQ(1, strncmp("blah", "blah4", 4), 0); break;
951		CASE_TEST(setncmp_blah_blah5); EXPECT_NE(1, strncmp("blah", "blah5", 5), 0); break;
952		CASE_TEST(setncmp_blah_blah6); EXPECT_NE(1, strncmp("blah", "blah6", 6), 0); break;
953		CASE_TEST(strchr_foobar_o);    EXPECT_STREQ(1, strchr("foobar", 'o'), "oobar"); break;
954		CASE_TEST(strchr_foobar_z);    EXPECT_STRZR(1, strchr("foobar", 'z')); break;
955		CASE_TEST(strrchr_foobar_o);   EXPECT_STREQ(1, strrchr("foobar", 'o'), "obar"); break;
956		CASE_TEST(strrchr_foobar_z);   EXPECT_STRZR(1, strrchr("foobar", 'z')); break;
957		CASE_TEST(memcmp_20_20);       EXPECT_EQ(1, memcmp("aaa\x20", "aaa\x20", 4), 0); break;
958		CASE_TEST(memcmp_20_60);       EXPECT_LT(1, memcmp("aaa\x20", "aaa\x60", 4), 0); break;
959		CASE_TEST(memcmp_60_20);       EXPECT_GT(1, memcmp("aaa\x60", "aaa\x20", 4), 0); break;
960		CASE_TEST(memcmp_20_e0);       EXPECT_LT(1, memcmp("aaa\x20", "aaa\xe0", 4), 0); break;
961		CASE_TEST(memcmp_e0_20);       EXPECT_GT(1, memcmp("aaa\xe0", "aaa\x20", 4), 0); break;
962		CASE_TEST(memcmp_80_e0);       EXPECT_LT(1, memcmp("aaa\x80", "aaa\xe0", 4), 0); break;
963		CASE_TEST(memcmp_e0_80);       EXPECT_GT(1, memcmp("aaa\xe0", "aaa\x80", 4), 0); break;
964		CASE_TEST(limit_int8_max);          EXPECT_EQ(1, INT8_MAX,         (int8_t)          0x7f); break;
965		CASE_TEST(limit_int8_min);          EXPECT_EQ(1, INT8_MIN,         (int8_t)          0x80); break;
966		CASE_TEST(limit_uint8_max);         EXPECT_EQ(1, UINT8_MAX,        (uint8_t)         0xff); break;
967		CASE_TEST(limit_int16_max);         EXPECT_EQ(1, INT16_MAX,        (int16_t)         0x7fff); break;
968		CASE_TEST(limit_int16_min);         EXPECT_EQ(1, INT16_MIN,        (int16_t)         0x8000); break;
969		CASE_TEST(limit_uint16_max);        EXPECT_EQ(1, UINT16_MAX,       (uint16_t)        0xffff); break;
970		CASE_TEST(limit_int32_max);         EXPECT_EQ(1, INT32_MAX,        (int32_t)         0x7fffffff); break;
971		CASE_TEST(limit_int32_min);         EXPECT_EQ(1, INT32_MIN,        (int32_t)         0x80000000); break;
972		CASE_TEST(limit_uint32_max);        EXPECT_EQ(1, UINT32_MAX,       (uint32_t)        0xffffffff); break;
973		CASE_TEST(limit_int64_max);         EXPECT_EQ(1, INT64_MAX,        (int64_t)         0x7fffffffffffffff); break;
974		CASE_TEST(limit_int64_min);         EXPECT_EQ(1, INT64_MIN,        (int64_t)         0x8000000000000000); break;
975		CASE_TEST(limit_uint64_max);        EXPECT_EQ(1, UINT64_MAX,       (uint64_t)        0xffffffffffffffff); break;
976		CASE_TEST(limit_int_least8_max);    EXPECT_EQ(1, INT_LEAST8_MAX,   (int_least8_t)    0x7f); break;
977		CASE_TEST(limit_int_least8_min);    EXPECT_EQ(1, INT_LEAST8_MIN,   (int_least8_t)    0x80); break;
978		CASE_TEST(limit_uint_least8_max);   EXPECT_EQ(1, UINT_LEAST8_MAX,  (uint_least8_t)   0xff); break;
979		CASE_TEST(limit_int_least16_max);   EXPECT_EQ(1, INT_LEAST16_MAX,  (int_least16_t)   0x7fff); break;
980		CASE_TEST(limit_int_least16_min);   EXPECT_EQ(1, INT_LEAST16_MIN,  (int_least16_t)   0x8000); break;
981		CASE_TEST(limit_uint_least16_max);  EXPECT_EQ(1, UINT_LEAST16_MAX, (uint_least16_t)  0xffff); break;
982		CASE_TEST(limit_int_least32_max);   EXPECT_EQ(1, INT_LEAST32_MAX,  (int_least32_t)   0x7fffffff); break;
983		CASE_TEST(limit_int_least32_min);   EXPECT_EQ(1, INT_LEAST32_MIN,  (int_least32_t)   0x80000000); break;
984		CASE_TEST(limit_uint_least32_max);  EXPECT_EQ(1, UINT_LEAST32_MAX, (uint_least32_t)  0xffffffffU); break;
985		CASE_TEST(limit_int_least64_min);   EXPECT_EQ(1, INT_LEAST64_MIN,  (int_least64_t)   0x8000000000000000LL); break;
986		CASE_TEST(limit_int_least64_max);   EXPECT_EQ(1, INT_LEAST64_MAX,  (int_least64_t)   0x7fffffffffffffffLL); break;
987		CASE_TEST(limit_uint_least64_max);  EXPECT_EQ(1, UINT_LEAST64_MAX, (uint_least64_t)  0xffffffffffffffffULL); break;
988		CASE_TEST(limit_int_fast8_max);     EXPECT_EQ(1, INT_FAST8_MAX,    (int_fast8_t)     0x7f); break;
989		CASE_TEST(limit_int_fast8_min);     EXPECT_EQ(1, INT_FAST8_MIN,    (int_fast8_t)     0x80); break;
990		CASE_TEST(limit_uint_fast8_max);    EXPECT_EQ(1, UINT_FAST8_MAX,   (uint_fast8_t)    0xff); break;
991		CASE_TEST(limit_int_fast16_min);    EXPECT_EQ(1, INT_FAST16_MIN,   (int_fast16_t)    SINT_MIN_OF_TYPE(int_fast16_t)); break;
992		CASE_TEST(limit_int_fast16_max);    EXPECT_EQ(1, INT_FAST16_MAX,   (int_fast16_t)    SINT_MAX_OF_TYPE(int_fast16_t)); break;
993		CASE_TEST(limit_uint_fast16_max);   EXPECT_EQ(1, UINT_FAST16_MAX,  (uint_fast16_t)   UINTPTR_MAX); break;
994		CASE_TEST(limit_int_fast32_min);    EXPECT_EQ(1, INT_FAST32_MIN,   (int_fast32_t)    SINT_MIN_OF_TYPE(int_fast32_t)); break;
995		CASE_TEST(limit_int_fast32_max);    EXPECT_EQ(1, INT_FAST32_MAX,   (int_fast32_t)    SINT_MAX_OF_TYPE(int_fast32_t)); break;
996		CASE_TEST(limit_uint_fast32_max);   EXPECT_EQ(1, UINT_FAST32_MAX,  (uint_fast32_t)   UINTPTR_MAX); break;
997		CASE_TEST(limit_int_fast64_min);    EXPECT_EQ(1, INT_FAST64_MIN,   (int_fast64_t)    INT64_MIN); break;
998		CASE_TEST(limit_int_fast64_max);    EXPECT_EQ(1, INT_FAST64_MAX,   (int_fast64_t)    INT64_MAX); break;
999		CASE_TEST(limit_uint_fast64_max);   EXPECT_EQ(1, UINT_FAST64_MAX,  (uint_fast64_t)   UINT64_MAX); break;
1000		CASE_TEST(sizeof_long_sane);        EXPECT_EQ(1, sizeof(long) == 8 || sizeof(long) == 4, 1); break;
1001		CASE_TEST(limit_intptr_min);        EXPECT_EQ(1, INTPTR_MIN,  sizeof(long) == 8 ? (intptr_t)  0x8000000000000000LL  : (intptr_t)  0x80000000); break;
1002		CASE_TEST(limit_intptr_max);        EXPECT_EQ(1, INTPTR_MAX,  sizeof(long) == 8 ? (intptr_t)  0x7fffffffffffffffLL  : (intptr_t)  0x7fffffff); break;
1003		CASE_TEST(limit_uintptr_max);       EXPECT_EQ(1, UINTPTR_MAX, sizeof(long) == 8 ? (uintptr_t) 0xffffffffffffffffULL : (uintptr_t) 0xffffffffU); break;
1004		CASE_TEST(limit_ptrdiff_min);       EXPECT_EQ(1, PTRDIFF_MIN, sizeof(long) == 8 ? (ptrdiff_t) 0x8000000000000000LL  : (ptrdiff_t) 0x80000000); break;
1005		CASE_TEST(limit_ptrdiff_max);       EXPECT_EQ(1, PTRDIFF_MAX, sizeof(long) == 8 ? (ptrdiff_t) 0x7fffffffffffffffLL  : (ptrdiff_t) 0x7fffffff); break;
1006		CASE_TEST(limit_size_max);          EXPECT_EQ(1, SIZE_MAX,    sizeof(long) == 8 ? (size_t)    0xffffffffffffffffULL : (size_t)    0xffffffffU); break;
1007
1008		case __LINE__:
1009			return ret; /* must be last */
1010		/* note: do not set any defaults so as to permit holes above */
1011		}
1012	}
1013	return ret;
1014}
1015
1016#define EXPECT_VFPRINTF(c, expected, fmt, ...)				\
1017	ret += expect_vfprintf(llen, c, expected, fmt, ##__VA_ARGS__)
1018
1019static int expect_vfprintf(int llen, int c, const char *expected, const char *fmt, ...)
1020{
1021	int ret, fd;
1022	ssize_t w, r;
1023	char buf[100];
1024	FILE *memfile;
1025	va_list args;
1026
1027	fd = open("/tmp", O_TMPFILE | O_EXCL | O_RDWR, 0600);
1028	if (fd == -1) {
1029		result(llen, SKIPPED);
1030		return 0;
1031	}
1032
1033	memfile = fdopen(fd, "w+");
1034	if (!memfile) {
1035		result(llen, FAIL);
1036		return 1;
1037	}
1038
1039	va_start(args, fmt);
1040	w = vfprintf(memfile, fmt, args);
1041	va_end(args);
1042
1043	if (w != c) {
1044		llen += printf(" written(%d) != %d", (int)w, c);
1045		result(llen, FAIL);
1046		return 1;
1047	}
1048
1049	fflush(memfile);
1050	lseek(fd, 0, SEEK_SET);
1051
1052	r = read(fd, buf, sizeof(buf) - 1);
1053
1054	fclose(memfile);
1055
1056	if (r != w) {
1057		llen += printf(" written(%d) != read(%d)", (int)w, (int)r);
1058		result(llen, FAIL);
1059		return 1;
1060	}
1061
1062	buf[r] = '\0';
1063	llen += printf(" \"%s\" = \"%s\"", expected, buf);
1064	ret = strncmp(expected, buf, c);
1065
1066	result(llen, ret ? FAIL : OK);
1067	return ret;
1068}
1069
1070static int run_vfprintf(int min, int max)
1071{
1072	int test;
1073	int ret = 0;
1074
1075	for (test = min; test >= 0 && test <= max; test++) {
1076		int llen = 0; /* line length */
1077
1078		/* avoid leaving empty lines below, this will insert holes into
1079		 * test numbers.
1080		 */
1081		switch (test + __LINE__ + 1) {
1082		CASE_TEST(empty);        EXPECT_VFPRINTF(0, "", ""); break;
1083		CASE_TEST(simple);       EXPECT_VFPRINTF(3, "foo", "foo"); break;
1084		CASE_TEST(string);       EXPECT_VFPRINTF(3, "foo", "%s", "foo"); break;
1085		CASE_TEST(number);       EXPECT_VFPRINTF(4, "1234", "%d", 1234); break;
1086		CASE_TEST(negnumber);    EXPECT_VFPRINTF(5, "-1234", "%d", -1234); break;
1087		CASE_TEST(unsigned);     EXPECT_VFPRINTF(5, "12345", "%u", 12345); break;
1088		CASE_TEST(char);         EXPECT_VFPRINTF(1, "c", "%c", 'c'); break;
1089		CASE_TEST(hex);          EXPECT_VFPRINTF(1, "f", "%x", 0xf); break;
1090		CASE_TEST(pointer);      EXPECT_VFPRINTF(3, "0x1", "%p", (void *) 0x1); break;
1091		case __LINE__:
1092			return ret; /* must be last */
1093		/* note: do not set any defaults so as to permit holes above */
1094		}
1095	}
1096	return ret;
1097}
1098
1099static int smash_stack(void)
1100{
1101	char buf[100];
1102	volatile char *ptr = buf;
1103	size_t i;
1104
1105	for (i = 0; i < 200; i++)
1106		ptr[i] = 'P';
1107
1108	return 1;
1109}
1110
1111static int run_protection(int min __attribute__((unused)),
1112			  int max __attribute__((unused)))
1113{
1114	pid_t pid;
1115	int llen = 0, status;
1116
1117	llen += printf("0 -fstackprotector ");
1118
1119#if !defined(_NOLIBC_STACKPROTECTOR)
1120	llen += printf("not supported");
1121	result(llen, SKIPPED);
1122	return 0;
1123#endif
1124
1125#if defined(_NOLIBC_STACKPROTECTOR)
1126	if (!__stack_chk_guard) {
1127		llen += printf("__stack_chk_guard not initialized");
1128		result(llen, FAIL);
1129		return 1;
1130	}
1131#endif
1132
1133	pid = -1;
1134	pid = fork();
1135
1136	switch (pid) {
1137	case -1:
1138		llen += printf("fork()");
1139		result(llen, FAIL);
1140		return 1;
1141
1142	case 0:
1143		close(STDOUT_FILENO);
1144		close(STDERR_FILENO);
1145
1146		prctl(PR_SET_DUMPABLE, 0, 0, 0, 0);
1147		smash_stack();
1148		return 1;
1149
1150	default:
1151		pid = waitpid(pid, &status, 0);
1152
1153		if (pid == -1 || !WIFSIGNALED(status) || WTERMSIG(status) != SIGABRT) {
1154			llen += printf("waitpid()");
1155			result(llen, FAIL);
1156			return 1;
1157		}
1158		result(llen, OK);
1159		return 0;
1160	}
1161}
1162
1163/* prepare what needs to be prepared for pid 1 (stdio, /dev, /proc, etc) */
1164int prepare(void)
1165{
1166	struct stat stat_buf;
1167
1168	/* It's possible that /dev doesn't even exist or was not mounted, so
1169	 * we'll try to create it, mount it, or create minimal entries into it.
1170	 * We want at least /dev/null and /dev/console.
1171	 */
1172	if (stat("/dev/.", &stat_buf) == 0 || mkdir("/dev", 0755) == 0) {
1173		if (stat("/dev/console", &stat_buf) != 0 ||
1174		    stat("/dev/null", &stat_buf) != 0 ||
1175		    stat("/dev/zero", &stat_buf) != 0) {
1176			/* try devtmpfs first, otherwise fall back to manual creation */
1177			if (mount("/dev", "/dev", "devtmpfs", 0, 0) != 0) {
1178				mknod("/dev/console", 0600 | S_IFCHR, makedev(5, 1));
1179				mknod("/dev/null",    0666 | S_IFCHR, makedev(1, 3));
1180				mknod("/dev/zero",    0666 | S_IFCHR, makedev(1, 5));
1181			}
1182		}
1183	}
1184
1185	/* If no /dev/console was found before calling init, stdio is closed so
1186	 * we need to reopen it from /dev/console. If it failed above, it will
1187	 * still fail here and we cannot emit a message anyway.
1188	 */
1189	if (close(dup(1)) == -1) {
1190		int fd = open("/dev/console", O_RDWR);
1191
1192		if (fd >= 0) {
1193			if (fd != 0)
1194				dup2(fd, 0);
1195			if (fd != 1)
1196				dup2(fd, 1);
1197			if (fd != 2)
1198				dup2(fd, 2);
1199			if (fd > 2)
1200				close(fd);
1201			puts("\nSuccessfully reopened /dev/console.");
1202		}
1203	}
1204
1205	/* try to mount /proc if not mounted. Silently fail otherwise */
1206	if (stat("/proc/.", &stat_buf) == 0 || mkdir("/proc", 0755) == 0) {
1207		if (stat("/proc/self", &stat_buf) != 0) {
1208			/* If not mountable, remove /proc completely to avoid misuse */
1209			if (mount("none", "/proc", "proc", 0, 0) != 0)
1210				rmdir("/proc");
1211		}
1212	}
1213
1214	/* some tests rely on a writable /tmp */
1215	mkdir("/tmp", 0755);
1216
1217	return 0;
1218}
1219
1220/* This is the definition of known test names, with their functions */
1221static const struct test test_names[] = {
1222	/* add new tests here */
1223	{ .name = "startup",    .func = run_startup    },
1224	{ .name = "syscall",    .func = run_syscall    },
1225	{ .name = "stdlib",     .func = run_stdlib     },
1226	{ .name = "vfprintf",   .func = run_vfprintf   },
1227	{ .name = "protection", .func = run_protection },
1228	{ 0 }
1229};
1230
1231static int is_setting_valid(char *test)
1232{
1233	int idx, len, test_len, valid = 0;
1234	char delimiter;
1235
1236	if (!test)
1237		return valid;
1238
1239	test_len = strlen(test);
1240
1241	for (idx = 0; test_names[idx].name; idx++) {
1242		len = strlen(test_names[idx].name);
1243		if (test_len < len)
1244			continue;
1245
1246		if (strncmp(test, test_names[idx].name, len) != 0)
1247			continue;
1248
1249		delimiter = test[len];
1250		if (delimiter != ':' && delimiter != ',' && delimiter != '\0')
1251			continue;
1252
1253		valid = 1;
1254		break;
1255	}
1256
1257	return valid;
1258}
1259
1260int main(int argc, char **argv, char **envp)
1261{
1262	int min = 0;
1263	int max = INT_MAX;
1264	int ret = 0;
1265	int err;
1266	int idx;
1267	char *test;
1268
1269	argv0 = argv[0];
1270	test_argc = argc;
1271	test_argv = argv;
1272	test_envp = envp;
1273
1274	/* when called as init, it's possible that no console was opened, for
1275	 * example if no /dev file system was provided. We'll check that fd#1
1276	 * was opened, and if not we'll attempt to create and open /dev/console
1277	 * and /dev/null that we'll use for later tests.
1278	 */
1279	if (getpid() == 1)
1280		prepare();
1281
1282	/* the definition of a series of tests comes from either argv[1] or the
1283	 * "NOLIBC_TEST" environment variable. It's made of a comma-delimited
1284	 * series of test names and optional ranges:
1285	 *    syscall:5-15[:.*],stdlib:8-10
1286	 */
1287	test = argv[1];
1288	if (!is_setting_valid(test))
1289		test = getenv("NOLIBC_TEST");
1290
1291	if (is_setting_valid(test)) {
1292		char *comma, *colon, *dash, *value;
1293
1294		do {
1295			comma = strchr(test, ',');
1296			if (comma)
1297				*(comma++) = '\0';
1298
1299			colon = strchr(test, ':');
1300			if (colon)
1301				*(colon++) = '\0';
1302
1303			for (idx = 0; test_names[idx].name; idx++) {
1304				if (strcmp(test, test_names[idx].name) == 0)
1305					break;
1306			}
1307
1308			if (test_names[idx].name) {
1309				/* The test was named, it will be called at least
1310				 * once. We may have an optional range at <colon>
1311				 * here, which defaults to the full range.
1312				 */
1313				do {
1314					min = 0; max = INT_MAX;
1315					value = colon;
1316					if (value && *value) {
1317						colon = strchr(value, ':');
1318						if (colon)
1319							*(colon++) = '\0';
1320
1321						dash = strchr(value, '-');
1322						if (dash)
1323							*(dash++) = '\0';
1324
1325						/* support :val: :min-max: :min-: :-max: */
1326						if (*value)
1327							min = atoi(value);
1328						if (!dash)
1329							max = min;
1330						else if (*dash)
1331							max = atoi(dash);
1332
1333						value = colon;
1334					}
1335
1336					/* now's time to call the test */
1337					printf("Running test '%s'\n", test_names[idx].name);
1338					err = test_names[idx].func(min, max);
1339					ret += err;
1340					printf("Errors during this test: %d\n\n", err);
1341				} while (colon && *colon);
1342			} else
1343				printf("Ignoring unknown test name '%s'\n", test);
1344
1345			test = comma;
1346		} while (test && *test);
1347	} else {
1348		/* no test mentioned, run everything */
1349		for (idx = 0; test_names[idx].name; idx++) {
1350			printf("Running test '%s'\n", test_names[idx].name);
1351			err = test_names[idx].func(min, max);
1352			ret += err;
1353			printf("Errors during this test: %d\n\n", err);
1354		}
1355	}
1356
1357	printf("Total number of errors: %d\n", ret);
1358
1359	if (getpid() == 1) {
1360		/* we're running as init, there's no other process on the
1361		 * system, thus likely started from a VM for a quick check.
1362		 * Exiting will provoke a kernel panic that may be reported
1363		 * as an error by Qemu or the hypervisor, while stopping
1364		 * cleanly will often be reported as a success. This allows
1365		 * to use the output of this program for bisecting kernels.
1366		 */
1367		printf("Leaving init with final status: %d\n", !!ret);
1368		if (ret == 0)
1369			reboot(RB_POWER_OFF);
1370#if defined(__x86_64__)
1371		/* QEMU started with "-device isa-debug-exit -no-reboot" will
1372		 * exit with status code 2N+1 when N is written to 0x501. We
1373		 * hard-code the syscall here as it's arch-dependent.
1374		 */
1375		else if (syscall(__NR_ioperm, 0x501, 1, 1) == 0)
1376			__asm__ volatile ("outb %%al, %%dx" :: "d"(0x501), "a"(0));
1377		/* if it does nothing, fall back to the regular panic */
1378#endif
1379	}
1380
1381	printf("Exiting with status %d\n", !!ret);
1382	return !!ret;
1383}
1384