return (eflags & ~0x3000U) | 0x200U;
}
+/* Signal mask logic from kernel/scheduler.c and kernel/syscall.c */
+#define SIGKILL 9
+#define SIGSTOP 19
+#define PROCESS_MAX_SIG 32
+
+static uint32_t sig_valid_mask(void) {
+ /* SIGKILL and SIGSTOP cannot be blocked */
+ uint32_t all = 0;
+ for (int i = 1; i < PROCESS_MAX_SIG; i++) {
+ if (i != SIGKILL && i != SIGSTOP)
+ all |= (1U << (uint32_t)i);
+ }
+ return all;
+}
+
+static uint32_t sig_pending_and_blocked(uint32_t pending, uint32_t blocked) {
+ /* sigpending returns: pending & blocked */
+ return pending & blocked;
+}
+
+static int sig_is_deliverable(uint32_t sig, uint32_t blocked) {
+ /* Signal is deliverable if not blocked (except KILL/STOP always deliverable) */
+ if (sig == (uint32_t)SIGKILL || sig == (uint32_t)SIGSTOP) return 1;
+ return (blocked & (1U << sig)) == 0;
+}
+
+/* chmod symbolic mode parsing from user/cmds/chmod/chmod.c */
+static unsigned int parse_symbolic(const char* mode, unsigned int old) {
+ unsigned int result = old;
+ const char* p = mode;
+ while (*p) {
+ unsigned int who_bits = 0;
+ int has_u = 0, has_g = 0, has_o = 0;
+ while (*p == 'u' || *p == 'g' || *p == 'o' || *p == 'a') {
+ switch (*p) {
+ case 'u': has_u = 1; break;
+ case 'g': has_g = 1; break;
+ case 'o': has_o = 1; break;
+ case 'a': has_u = has_g = has_o = 1; break;
+ }
+ p++;
+ }
+ if (!has_u && !has_g && !has_o) has_u = has_g = has_o = 1;
+
+ if (has_u) who_bits |= 04700;
+ if (has_g) who_bits |= 02070;
+ if (has_o) who_bits |= 00007;
+
+ while (*p) {
+ char op = *p;
+ if (op != '+' && op != '-' && op != '=') break;
+ p++;
+
+ unsigned int perm = 0;
+ while (*p == 'r' || *p == 'w' || *p == 'x' ||
+ *p == 's' || *p == 't') {
+ switch (*p) {
+ case 'r':
+ if (has_u) perm |= 0400;
+ if (has_g) perm |= 0040;
+ if (has_o) perm |= 0004;
+ break;
+ case 'w':
+ if (has_u) perm |= 0200;
+ if (has_g) perm |= 0020;
+ if (has_o) perm |= 0002;
+ break;
+ case 'x':
+ if (has_u) perm |= 0100;
+ if (has_g) perm |= 0010;
+ if (has_o) perm |= 0001;
+ break;
+ case 's':
+ if (has_u) perm |= 04000;
+ if (has_g) perm |= 02000;
+ break;
+ case 't':
+ perm |= 01000;
+ break;
+ }
+ p++;
+ }
+
+ if (op == '+') {
+ result |= perm;
+ } else if (op == '-') {
+ result &= ~perm;
+ } else {
+ result &= ~who_bits;
+ result |= perm;
+ }
+
+ if (*p == ',') { p++; break; }
+ }
+ }
+ return result & 07777;
+}
+
/* ======== user_range_ok TESTS ======== */
TEST(urange_null_ptr) {
ASSERT_EQ(clean & 0x3000, 0);
}
+/* ======== Signal mask TESTS ======== */
+
+TEST(sigmask_valid_excludes_kill) {
+ /* SIGKILL (bit 9) must not be in valid mask */
+ uint32_t mask = sig_valid_mask();
+ ASSERT_EQ(mask & (1U << SIGKILL), 0);
+}
+
+TEST(sigmask_valid_excludes_stop) {
+ /* SIGSTOP (bit 19) must not be in valid mask */
+ uint32_t mask = sig_valid_mask();
+ ASSERT_EQ(mask & (1U << SIGSTOP), 0);
+}
+
+TEST(sigmask_valid_includes_usr1) {
+ /* SIGUSR1 (bit 10) must be in valid mask */
+ uint32_t mask = sig_valid_mask();
+ ASSERT_TRUE(mask & (1U << 10));
+}
+
+TEST(sigmask_pending_and_blocked) {
+ /* sigpending = pending & blocked */
+ uint32_t pending = (1U << 10) | (1U << 12); /* SIGUSR1, SIGUSR2 */
+ uint32_t blocked = (1U << 10); /* only SIGUSR1 blocked */
+ uint32_t result = sig_pending_and_blocked(pending, blocked);
+ ASSERT_EQ(result, (1U << 10)); /* only SIGUSR1 pending+blocked */
+}
+
+TEST(sigmask_pending_not_blocked) {
+ /* Signal pending but not blocked → not in sigpending result */
+ uint32_t pending = (1U << 10);
+ uint32_t blocked = 0;
+ uint32_t result = sig_pending_and_blocked(pending, blocked);
+ ASSERT_EQ(result, 0);
+}
+
+TEST(sigmask_deliverable_normal) {
+ /* Normal signal not blocked → deliverable */
+ ASSERT_TRUE(sig_is_deliverable(10, 0));
+}
+
+TEST(sigmask_deliverable_blocked) {
+ /* Normal signal blocked → not deliverable */
+ ASSERT_FALSE(sig_is_deliverable(10, (1U << 10)));
+}
+
+TEST(sigmask_kill_always_deliverable) {
+ /* SIGKILL always deliverable even if blocked */
+ ASSERT_TRUE(sig_is_deliverable(SIGKILL, (1U << SIGKILL)));
+}
+
+TEST(sigmask_stop_always_deliverable) {
+ /* SIGSTOP always deliverable even if blocked */
+ ASSERT_TRUE(sig_is_deliverable(SIGSTOP, (1U << SIGSTOP)));
+}
+
+/* ======== chmod symbolic mode TESTS ======== */
+
+TEST(chmod_u_plus_x) {
+ /* u+x on 0644 → 0744 (only user gets execute) */
+ ASSERT_EQ(parse_symbolic("u+x", 0644), 0744);
+}
+
+TEST(chmod_go_minus_w) {
+ /* go-w on 0666 → 0644 */
+ ASSERT_EQ(parse_symbolic("go-w", 0666), 0644);
+}
+
+TEST(chmod_a_plus_x) {
+ /* a+x on 0644 → 0755 */
+ ASSERT_EQ(parse_symbolic("a+x", 0644), 0755);
+}
+
+TEST(chmod_a_eq_rw) {
+ /* a=rw on 0755 → 0666 */
+ ASSERT_EQ(parse_symbolic("a=rw", 0755), 0666);
+}
+
+TEST(chmod_u_plus_s) {
+ /* u+s on 0755 → 4755 (setuid) */
+ ASSERT_EQ(parse_symbolic("u+s", 0755), 04755);
+}
+
+TEST(chmod_g_plus_s) {
+ /* g+s on 0755 → 2755 (setgid) */
+ ASSERT_EQ(parse_symbolic("g+s", 0755), 02755);
+}
+
+TEST(chmod_plus_t) {
+ /* +t on 0777 → 1777 (sticky) */
+ ASSERT_EQ(parse_symbolic("+t", 0777), 01777);
+}
+
+TEST(chmod_o_minus_x) {
+ /* o-x on 0755 → 0754 */
+ ASSERT_EQ(parse_symbolic("o-x", 0755), 0754);
+}
+
+TEST(chmod_u_eq_rw_go_eq_r) {
+ /* u=rw,go=r on 0755 → 0644 */
+ ASSERT_EQ(parse_symbolic("u=rw,go=r", 0755), 0644);
+}
+
+TEST(chmod_no_change) {
+ /* u+r on already 0755 → 0755 */
+ ASSERT_EQ(parse_symbolic("u+r", 0755), 0755);
+}
+
/* ======== MAIN ======== */
int main(void) {
printf("\n=========================================\n");
RUN(eflags_preserves_other);
RUN(eflags_iopl1);
+ /* signal mask */
+ RUN(sigmask_valid_excludes_kill);
+ RUN(sigmask_valid_excludes_stop);
+ RUN(sigmask_valid_includes_usr1);
+ RUN(sigmask_pending_and_blocked);
+ RUN(sigmask_pending_not_blocked);
+ RUN(sigmask_deliverable_normal);
+ RUN(sigmask_deliverable_blocked);
+ RUN(sigmask_kill_always_deliverable);
+ RUN(sigmask_stop_always_deliverable);
+
+ /* chmod symbolic mode */
+ RUN(chmod_u_plus_x);
+ RUN(chmod_go_minus_w);
+ RUN(chmod_a_plus_x);
+ RUN(chmod_a_eq_rw);
+ RUN(chmod_u_plus_s);
+ RUN(chmod_g_plus_s);
+ RUN(chmod_plus_t);
+ RUN(chmod_o_minus_x);
+ RUN(chmod_u_eq_rw_go_eq_r);
+ RUN(chmod_no_change);
+
printf("\n %d/%d passed, %d failed\n", g_tests_passed, g_tests_run, g_tests_failed);
if (g_tests_failed > 0) {
return (value + align - 1) & ~(align - 1);
}
+/* From src/drivers/initrd.c — tar octal parsing */
+static uint32_t tar_parse_octal(const char* s, size_t n) {
+ uint32_t v = 0;
+ for (size_t i = 0; i < n; i++) {
+ if (s[i] == 0) break;
+ if (s[i] < '0' || s[i] > '7') continue;
+ v = (v << 3) + (uint32_t)(s[i] - '0');
+ }
+ return v;
+}
+
+/* From src/kernel/fs.c — mount point prefix check */
+static int path_is_mountpoint_prefix(const char* mp, const char* path) {
+ size_t mpl = strlen(mp);
+ if (mpl == 0) return 0;
+ if (strcmp(mp, "/") == 0) return 1;
+ if (strncmp(path, mp, mpl) != 0) return 0;
+ if (path[mpl] == 0) return 1;
+ if (path[mpl] == '/') return 1;
+ return 0;
+}
+
+/* From src/kernel/fs.c — mountpoint normalization */
+static void normalize_mountpoint(const char* in, char* out, size_t out_sz) {
+ if (!out || out_sz == 0) return;
+ out[0] = 0;
+ if (!in || in[0] == 0) {
+ strcpy(out, "/");
+ return;
+ }
+ size_t i = 0;
+ if (in[0] != '/') {
+ out[i++] = '/';
+ }
+ for (size_t j = 0; in[j] != 0 && i + 1 < out_sz; j++) {
+ out[i++] = in[j];
+ }
+ out[i] = 0;
+ size_t l = strlen(out);
+ while (l > 1 && out[l - 1] == '/') {
+ out[l - 1] = 0;
+ l--;
+ }
+}
+
+/* From src/kernel/syscall.c — permission check (simplified for host test) */
+#define EACCES 13
+static int vfs_check_permission(uint32_t mode, uint32_t euid, uint32_t egid,
+ uint32_t file_uid, uint32_t file_gid, int want) {
+ if (euid == 0) return 0; /* root — allow all */
+ if (mode == 0) return 0; /* mode not set — permissive */
+ uint32_t perm;
+ if (euid == file_uid) {
+ perm = (mode >> 6) & 7;
+ } else if (egid == file_gid) {
+ perm = (mode >> 3) & 7;
+ } else {
+ perm = mode & 7;
+ }
+ if (((uint32_t)want & perm) != (uint32_t)want) return -EACCES;
+ return 0;
+}
+
+/* From src/arch/x86/elf.c — ELF header validation (simplified for host) */
+#define ELF_MAGIC0 0x7F
+#define ELF_MAGIC1 'E'
+#define ELF_MAGIC2 'L'
+#define ELF_MAGIC3 'F'
+#define ELFCLASS32 1
+#define ELFDATA2LSB 1
+#define ET_EXEC 2
+#define ET_DYN 3
+#define EM_386 3
+#define EINVAL 22
+#define EFAULT 14
+
+typedef struct {
+ uint8_t e_ident[16];
+ uint16_t e_type;
+ uint16_t e_machine;
+ uint32_t e_version;
+ uint32_t e_entry;
+ uint32_t e_phoff;
+ uint32_t e_shoff;
+ uint32_t e_flags;
+ uint16_t e_ehsize;
+ uint16_t e_phentsize;
+ uint16_t e_phnum;
+ uint16_t e_shentsize;
+ uint16_t e_shnum;
+ uint16_t e_shstrndx;
+} test_elf32_ehdr_t;
+
+typedef struct {
+ uint32_t p_type;
+ uint32_t p_offset;
+ uint32_t p_vaddr;
+ uint32_t p_paddr;
+ uint32_t p_filesz;
+ uint32_t p_memsz;
+ uint32_t p_flags;
+ uint32_t p_align;
+} test_elf32_phdr_t;
+
+static int elf32_validate(const test_elf32_ehdr_t* eh, size_t file_len) {
+ if (!eh) return -EFAULT;
+ if (file_len < sizeof(*eh)) return -EINVAL;
+ if (eh->e_ident[0] != ELF_MAGIC0 ||
+ eh->e_ident[1] != ELF_MAGIC1 ||
+ eh->e_ident[2] != ELF_MAGIC2 ||
+ eh->e_ident[3] != ELF_MAGIC3)
+ return -EINVAL;
+ if (eh->e_ident[4] != ELFCLASS32) return -EINVAL;
+ if (eh->e_ident[5] != ELFDATA2LSB) return -EINVAL;
+ if (eh->e_type != ET_EXEC && eh->e_type != ET_DYN) return -EINVAL;
+ if (eh->e_machine != EM_386) return -EINVAL;
+ if (eh->e_phentsize != sizeof(test_elf32_phdr_t)) return -EINVAL;
+ if (eh->e_phnum == 0) return -EINVAL;
+ return 0;
+}
+
/* ======== TESTS ======== */
/* --- itoa tests --- */
ASSERT_EQ(align_up(0, 4096), 0);
}
+/* --- tar_parse_octal tests --- */
+TEST(tar_octal_zero) {
+ ASSERT_EQ(tar_parse_octal("0", 2), 0);
+}
+
+TEST(tar_octal_simple) {
+ ASSERT_EQ(tar_parse_octal("644", 4), 0644);
+}
+
+TEST(tar_octal_large) {
+ ASSERT_EQ(tar_parse_octal("100644", 7), 0100644);
+}
+
+TEST(tar_octal_empty) {
+ ASSERT_EQ(tar_parse_octal("", 1), 0);
+}
+
+TEST(tar_octal_null_term) {
+ /* Stops at NUL even if n is larger */
+ ASSERT_EQ(tar_parse_octal("755\0ignored", 10), 0755);
+}
+
+TEST(tar_octal_skips_non_octal) {
+ /* Space padding is common in tar headers */
+ ASSERT_EQ(tar_parse_octal(" 644 ", 6), 0644);
+}
+
+/* --- path_is_mountpoint_prefix tests --- */
+TEST(mountprefix_root) {
+ ASSERT_EQ(path_is_mountpoint_prefix("/", "/anything"), 1);
+}
+
+TEST(mountprefix_exact) {
+ ASSERT_EQ(path_is_mountpoint_prefix("/disk", "/disk"), 1);
+}
+
+TEST(mountprefix_child) {
+ ASSERT_EQ(path_is_mountpoint_prefix("/disk", "/disk/file"), 1);
+}
+
+TEST(mountprefix_no_match) {
+ ASSERT_EQ(path_is_mountpoint_prefix("/disk", "/other"), 0);
+}
+
+TEST(mountprefix_partial) {
+ /* /dis should not match /disk */
+ ASSERT_EQ(path_is_mountpoint_prefix("/dis", "/disk"), 0);
+}
+
+TEST(mountprefix_empty) {
+ ASSERT_EQ(path_is_mountpoint_prefix("", "/anything"), 0);
+}
+
+/* --- normalize_mountpoint tests --- */
+TEST(normmount_root) {
+ char out[128];
+ normalize_mountpoint("/", out, sizeof(out));
+ ASSERT_STR_EQ(out, "/");
+}
+
+TEST(normmount_simple) {
+ char out[128];
+ normalize_mountpoint("disk", out, sizeof(out));
+ ASSERT_STR_EQ(out, "/disk");
+}
+
+TEST(normmount_trailing_slash) {
+ char out[128];
+ normalize_mountpoint("/disk/", out, sizeof(out));
+ ASSERT_STR_EQ(out, "/disk");
+}
+
+TEST(normmount_empty) {
+ char out[128];
+ normalize_mountpoint("", out, sizeof(out));
+ ASSERT_STR_EQ(out, "/");
+}
+
+TEST(normmount_null) {
+ char out[128];
+ normalize_mountpoint(NULL, out, sizeof(out));
+ ASSERT_STR_EQ(out, "/");
+}
+
+TEST(normmount_already_normalized) {
+ char out[128];
+ normalize_mountpoint("/disk", out, sizeof(out));
+ ASSERT_STR_EQ(out, "/disk");
+}
+
+/* --- vfs_check_permission tests --- */
+TEST(perm_root_allows) {
+ /* Root can do anything */
+ ASSERT_EQ(vfs_check_permission(0100, 0, 0, 1000, 1000, 4), 0);
+}
+
+TEST(perm_owner_read) {
+ /* mode=0400, owner wants read → allowed */
+ ASSERT_EQ(vfs_check_permission(0400, 1000, 100, 1000, 100, 4), 0);
+}
+
+TEST(perm_owner_no_write) {
+ /* mode=0400, owner wants write → denied */
+ ASSERT_EQ(vfs_check_permission(0400, 1000, 100, 1000, 100, 2), -EACCES);
+}
+
+TEST(perm_group_read) {
+ /* mode=0040, group member wants read → allowed */
+ ASSERT_EQ(vfs_check_permission(0040, 2000, 100, 1000, 100, 4), 0);
+}
+
+TEST(perm_other_read) {
+ /* mode=0004, other wants read → allowed */
+ ASSERT_EQ(vfs_check_permission(0004, 3000, 200, 1000, 100, 4), 0);
+}
+
+TEST(perm_other_no_write) {
+ /* mode=0004, other wants write → denied */
+ ASSERT_EQ(vfs_check_permission(0004, 3000, 200, 1000, 100, 2), -EACCES);
+}
+
+TEST(perm_mode_zero_permissive) {
+ /* mode=0 → permissive (allow all) */
+ ASSERT_EQ(vfs_check_permission(0, 1000, 100, 1000, 100, 7), 0);
+}
+
+TEST(perm_rw_file) {
+ /* mode=0644: owner rw, group/other read */
+ ASSERT_EQ(vfs_check_permission(0644, 1000, 100, 1000, 100, 6), 0); /* owner rw */
+ ASSERT_EQ(vfs_check_permission(0644, 2000, 100, 1000, 100, 4), 0); /* group read */
+ ASSERT_EQ(vfs_check_permission(0644, 2000, 100, 1000, 100, 2), -EACCES); /* group no write */
+ ASSERT_EQ(vfs_check_permission(0644, 3000, 200, 1000, 100, 4), 0); /* other read */
+ ASSERT_EQ(vfs_check_permission(0644, 3000, 200, 1000, 100, 2), -EACCES); /* other no write */
+}
+
+/* --- elf32_validate tests --- */
+TEST(elf_valid_exec) {
+ test_elf32_ehdr_t eh;
+ memset(&eh, 0, sizeof(eh));
+ eh.e_ident[0] = 0x7F;
+ eh.e_ident[1] = 'E';
+ eh.e_ident[2] = 'L';
+ eh.e_ident[3] = 'F';
+ eh.e_ident[4] = ELFCLASS32;
+ eh.e_ident[5] = ELFDATA2LSB;
+ eh.e_type = ET_EXEC;
+ eh.e_machine = EM_386;
+ eh.e_phentsize = sizeof(test_elf32_phdr_t);
+ eh.e_phnum = 1;
+ ASSERT_EQ(elf32_validate(&eh, sizeof(eh)), 0);
+}
+
+TEST(elf_valid_dyn) {
+ test_elf32_ehdr_t eh;
+ memset(&eh, 0, sizeof(eh));
+ eh.e_ident[0] = 0x7F;
+ eh.e_ident[1] = 'E';
+ eh.e_ident[2] = 'L';
+ eh.e_ident[3] = 'F';
+ eh.e_ident[4] = ELFCLASS32;
+ eh.e_ident[5] = ELFDATA2LSB;
+ eh.e_type = ET_DYN;
+ eh.e_machine = EM_386;
+ eh.e_phentsize = sizeof(test_elf32_phdr_t);
+ eh.e_phnum = 1;
+ ASSERT_EQ(elf32_validate(&eh, sizeof(eh)), 0);
+}
+
+TEST(elf_bad_magic) {
+ test_elf32_ehdr_t eh;
+ memset(&eh, 0, sizeof(eh));
+ eh.e_ident[0] = 'X';
+ ASSERT_EQ(elf32_validate(&eh, sizeof(eh)), -EINVAL);
+}
+
+TEST(elf_bad_class) {
+ test_elf32_ehdr_t eh;
+ memset(&eh, 0, sizeof(eh));
+ eh.e_ident[0] = 0x7F;
+ eh.e_ident[1] = 'E';
+ eh.e_ident[2] = 'L';
+ eh.e_ident[3] = 'F';
+ eh.e_ident[4] = 2; /* ELFCLASS64 */
+ eh.e_ident[5] = ELFDATA2LSB;
+ eh.e_type = ET_EXEC;
+ eh.e_machine = EM_386;
+ eh.e_phentsize = sizeof(test_elf32_phdr_t);
+ eh.e_phnum = 1;
+ ASSERT_EQ(elf32_validate(&eh, sizeof(eh)), -EINVAL);
+}
+
+TEST(elf_bad_type) {
+ test_elf32_ehdr_t eh;
+ memset(&eh, 0, sizeof(eh));
+ eh.e_ident[0] = 0x7F;
+ eh.e_ident[1] = 'E';
+ eh.e_ident[2] = 'L';
+ eh.e_ident[3] = 'F';
+ eh.e_ident[4] = ELFCLASS32;
+ eh.e_ident[5] = ELFDATA2LSB;
+ eh.e_type = 0; /* ET_NONE */
+ eh.e_machine = EM_386;
+ eh.e_phentsize = sizeof(test_elf32_phdr_t);
+ eh.e_phnum = 1;
+ ASSERT_EQ(elf32_validate(&eh, sizeof(eh)), -EINVAL);
+}
+
+TEST(elf_bad_machine) {
+ test_elf32_ehdr_t eh;
+ memset(&eh, 0, sizeof(eh));
+ eh.e_ident[0] = 0x7F;
+ eh.e_ident[1] = 'E';
+ eh.e_ident[2] = 'L';
+ eh.e_ident[3] = 'F';
+ eh.e_ident[4] = ELFCLASS32;
+ eh.e_ident[5] = ELFDATA2LSB;
+ eh.e_type = ET_EXEC;
+ eh.e_machine = 0x3E; /* EM_X86_64 */
+ eh.e_phentsize = sizeof(test_elf32_phdr_t);
+ eh.e_phnum = 1;
+ ASSERT_EQ(elf32_validate(&eh, sizeof(eh)), -EINVAL);
+}
+
+TEST(elf_no_phnum) {
+ test_elf32_ehdr_t eh;
+ memset(&eh, 0, sizeof(eh));
+ eh.e_ident[0] = 0x7F;
+ eh.e_ident[1] = 'E';
+ eh.e_ident[2] = 'L';
+ eh.e_ident[3] = 'F';
+ eh.e_ident[4] = ELFCLASS32;
+ eh.e_ident[5] = ELFDATA2LSB;
+ eh.e_type = ET_EXEC;
+ eh.e_machine = EM_386;
+ eh.e_phentsize = sizeof(test_elf32_phdr_t);
+ eh.e_phnum = 0;
+ ASSERT_EQ(elf32_validate(&eh, sizeof(eh)), -EINVAL);
+}
+
+TEST(elf_truncated) {
+ test_elf32_ehdr_t eh;
+ memset(&eh, 0, sizeof(eh));
+ ASSERT_EQ(elf32_validate(&eh, 10), -EINVAL);
+}
+
+TEST(elf_null) {
+ ASSERT_EQ(elf32_validate(NULL, 100), -EFAULT);
+}
+
/* ======== MAIN ======== */
int main(void) {
printf("\n=========================================\n");
RUN(align_up_exact);
RUN(align_up_zero);
+ /* tar_parse_octal */
+ RUN(tar_octal_zero);
+ RUN(tar_octal_simple);
+ RUN(tar_octal_large);
+ RUN(tar_octal_empty);
+ RUN(tar_octal_null_term);
+ RUN(tar_octal_skips_non_octal);
+
+ /* path_is_mountpoint_prefix */
+ RUN(mountprefix_root);
+ RUN(mountprefix_exact);
+ RUN(mountprefix_child);
+ RUN(mountprefix_no_match);
+ RUN(mountprefix_partial);
+ RUN(mountprefix_empty);
+
+ /* normalize_mountpoint */
+ RUN(normmount_root);
+ RUN(normmount_simple);
+ RUN(normmount_trailing_slash);
+ RUN(normmount_empty);
+ RUN(normmount_null);
+ RUN(normmount_already_normalized);
+
+ /* vfs_check_permission */
+ RUN(perm_root_allows);
+ RUN(perm_owner_read);
+ RUN(perm_owner_no_write);
+ RUN(perm_group_read);
+ RUN(perm_other_read);
+ RUN(perm_other_no_write);
+ RUN(perm_mode_zero_permissive);
+ RUN(perm_rw_file);
+
+ /* elf32_validate */
+ RUN(elf_valid_exec);
+ RUN(elf_valid_dyn);
+ RUN(elf_bad_magic);
+ RUN(elf_bad_class);
+ RUN(elf_bad_type);
+ RUN(elf_bad_machine);
+ RUN(elf_no_phnum);
+ RUN(elf_truncated);
+ RUN(elf_null);
+
printf("\n %d/%d passed, %d failed\n", g_tests_passed, g_tests_run, g_tests_failed);
if (g_tests_failed > 0) {