libk  Diff

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]

To Artifact [c8ccec879e]:


15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
..
57
58
59
60
61
62
63




64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98

#include <error_table.h>

/* we define all our platform functions here, whether or not
 * they're for the correct platform - only the ones that are
 * called by the preprocessed form of the code will actually
 * be linked, linker errors are our friend here! */
extern void* kmem_platform_mmap(void* addr,
		unsigned long sz, unsigned long prot, unsigned long flags,
		unsigned long fd, unsigned long off);

kmcond kmheapa(void** where, sz len) {
	/* allocate an object on the heap and return
	 * a pointer, or NULL if the allocation failed. */
	union {
		void* raw;
		ubyte* byte;
................................................................................

		k_platform_syscall_arg args[] = {
			null, region_size, 
			posix_prot_read | posix_prot_write,
			posix_flag_anonymous | posix_map_shared,
			-1, 0
		};





		struct k_platform_syscall_answer r = k_platform_syscall
			(k_platform_syscall_mmap, Kmsz(args), args);

		if (r.error == 0) region.byte = (ubyte*)r.ret; else {
			switch (r.error) {
				case k_platform_error_EAGAIN: return kmcond_bad_lock;
				case k_platform_error_EINVAL: return kmcond_bad_size;
				case k_platform_error_EMFILE: return kmcond_too_many;
				case k_platform_error_ENOMEM: return kmcond_no_room;
				default: return kmcond_fail_assert;
			}
		}

		/* region.byte = kmem_platform_mmap(null, region_size, */
		/* 		posix_prot_read | posix_prot_write, */
		/* 		posix_flag_anonymous | posix_map_shared, -1, 0); */

		/* impl note: while per manpage fd is "ignored"
		 * for MAP_ANONYMOUS, "some implementations" require
		 * a value of -1 */

#	else
 	   Knoimpl(kmheapa,KVos);
#		error missing implementation
#	endif
	
	void* const object = (region.byte + sizeof (kmbox));

	region.header -> kind = kmkind_heap;
	region.header -> size = len;

	*where = object;
	return kmcond_ok;
}







<
<
<







 







>
>
>
>













<
<
<
<
<
<
<
<
<













15
16
17
18
19
20
21



22
23
24
25
26
27
28
..
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77









78
79
80
81
82
83
84
85
86
87
88
89
90

#include <error_table.h>

/* we define all our platform functions here, whether or not
 * they're for the correct platform - only the ones that are
 * called by the preprocessed form of the code will actually
 * be linked, linker errors are our friend here! */




kmcond kmheapa(void** where, sz len) {
	/* allocate an object on the heap and return
	 * a pointer, or NULL if the allocation failed. */
	union {
		void* raw;
		ubyte* byte;
................................................................................

		k_platform_syscall_arg args[] = {
			null, region_size, 
			posix_prot_read | posix_prot_write,
			posix_flag_anonymous | posix_map_shared,
			-1, 0
		};

		/* impl note: while per manpage fd is "ignored"
		 * for MAP_ANONYMOUS, "some implementations" require
		 * a value of -1 */

		struct k_platform_syscall_answer r = k_platform_syscall
			(k_platform_syscall_mmap, Kmsz(args), args);

		if (r.error == 0) region.byte = (ubyte*)r.ret; else {
			switch (r.error) {
				case k_platform_error_EAGAIN: return kmcond_bad_lock;
				case k_platform_error_EINVAL: return kmcond_bad_size;
				case k_platform_error_EMFILE: return kmcond_too_many;
				case k_platform_error_ENOMEM: return kmcond_no_room;
				default: return kmcond_fail_assert;
			}
		}









#	else
 	   Knoimpl(kmheapa,KVos);
#		error missing implementation
#	endif
	
	void* const object = (region.byte + sizeof (kmbox));

	region.header -> kind = kmkind_heap;
	region.header -> size = len;

	*where = object;
	return kmcond_ok;
}