Differences From
Artifact [e093792a2c]:
- File
mod/kmem/heapa.fn.c
— part of check-in
[e50a476efe]
at
2019-08-22 02:52:20
on branch trunk
— removed sneaky segfault in x86-64 syscall fn where %r8 (the register that contains the pointer to the syscall arguments from the C syscall wrapper, which need to be copied into the correct registers before the kernel is invoked) gets overwritten if the syscall valency > 5, because of overlapping ccall and syscall ABI argument registers - r8 is clobbered by argument 5 and any further attempts to use it as a ptr segfault at best. also modified the report function so that it immediate cancels compilation if a sub-process reports failure. changed allocator function signatures so they can return a condition code if the kernel reports an error; updated example code so it compiles and runs without fault.
(user:
lexi,
size: 3183)
[annotate]
[blame]
[check-ins using]
15 15
16 16 #include <error_table.h>
17 17
18 18 /* we define all our platform functions here, whether or not
19 19 * they're for the correct platform - only the ones that are
20 20 * called by the preprocessed form of the code will actually
21 21 * be linked, linker errors are our friend here! */
22 -extern void* kmem_platform_mmap(void* addr,
23 - unsigned long sz, unsigned long prot, unsigned long flags,
24 - unsigned long fd, unsigned long off);
25 22
26 23 kmcond kmheapa(void** where, sz len) {
27 24 /* allocate an object on the heap and return
28 25 * a pointer, or NULL if the allocation failed. */
29 26 union {
30 27 void* raw;
31 28 ubyte* byte;
................................................................................
57 54
58 55 k_platform_syscall_arg args[] = {
59 56 null, region_size,
60 57 posix_prot_read | posix_prot_write,
61 58 posix_flag_anonymous | posix_map_shared,
62 59 -1, 0
63 60 };
61 +
62 + /* impl note: while per manpage fd is "ignored"
63 + * for MAP_ANONYMOUS, "some implementations" require
64 + * a value of -1 */
64 65
65 66 struct k_platform_syscall_answer r = k_platform_syscall
66 67 (k_platform_syscall_mmap, Kmsz(args), args);
67 68
68 69 if (r.error == 0) region.byte = (ubyte*)r.ret; else {
69 70 switch (r.error) {
70 71 case k_platform_error_EAGAIN: return kmcond_bad_lock;
71 72 case k_platform_error_EINVAL: return kmcond_bad_size;
72 73 case k_platform_error_EMFILE: return kmcond_too_many;
73 74 case k_platform_error_ENOMEM: return kmcond_no_room;
74 75 default: return kmcond_fail_assert;
75 76 }
76 77 }
77 -
78 - /* region.byte = kmem_platform_mmap(null, region_size, */
79 - /* posix_prot_read | posix_prot_write, */
80 - /* posix_flag_anonymous | posix_map_shared, -1, 0); */
81 -
82 - /* impl note: while per manpage fd is "ignored"
83 - * for MAP_ANONYMOUS, "some implementations" require
84 - * a value of -1 */
85 -
86 78 # else
87 79 Knoimpl(kmheapa,KVos);
88 80 # error missing implementation
89 81 # endif
90 82
91 83 void* const object = (region.byte + sizeof (kmbox));
92 84
93 85 region.header -> kind = kmkind_heap;
94 86 region.header -> size = len;
95 87
96 88 *where = object;
97 89 return kmcond_ok;
98 90 }