libk  Diff

Differences From Artifact [641176b71f]:

To 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]

     8      8    * see also: kmheapf() "heap free"
     9      9    */
    10     10   
    11     11   /* arch specific headers */
    12     12   #ifdef KFenv_posix
    13     13   #	include <posix/posix.h>
    14     14   #endif
           15  +
           16  +#include <error_table.h>
    15     17   
    16     18   /* we define all our platform functions here, whether or not
    17     19    * they're for the correct platform - only the ones that are
    18     20    * called by the preprocessed form of the code will actually
    19     21    * be linked, linker errors are our friend here! */
    20     22   extern void* kmem_platform_mmap(void* addr,
    21     23   		unsigned long sz, unsigned long prot, unsigned long flags,
    22     24   		unsigned long fd, unsigned long off);
    23     25   
    24         -void* kmheapa(sz len) {
           26  +kmcond kmheapa(void** where, sz len) {
    25     27   	/* allocate an object on the heap and return
    26     28   	 * a pointer, or NULL if the allocation failed. */
    27     29   	union {
    28     30   		void* raw;
    29     31   		ubyte* byte;
    30     32   		kmbox* header;
    31     33   	} region;
................................................................................
    49     51   		/* because munmap needs to be informed of the size of
    50     52   		 * the region we are going to unmap, we need to store
    51     53   		 * that information in the region that we are mapping.
    52     54   		 * the user will receive an adjusted pointer that can
    53     55   		 * be adjusted to point a field of type size_t that
    54     56   		 * contains the size of the allocated space.*/
    55     57   
    56         -		region.byte = kmem_platform_mmap(null, region_size,
    57         -				posix_prot_read | posix_prot_write,
    58         -				posix_flag_anonymous | posix_map_shared, -1, 0);
           58  +		k_platform_syscall_arg args[] = {
           59  +			null, region_size, 
           60  +			posix_prot_read | posix_prot_write,
           61  +			posix_flag_anonymous | posix_map_shared,
           62  +			-1, 0
           63  +		};
           64  +
           65  +		struct k_platform_syscall_answer r = k_platform_syscall
           66  +			(k_platform_syscall_mmap, Kmsz(args), args);
           67  +
           68  +		if (r.error == 0) region.byte = (ubyte*)r.ret; else {
           69  +			switch (r.error) {
           70  +				case k_platform_error_EAGAIN: return kmcond_bad_lock;
           71  +				case k_platform_error_EINVAL: return kmcond_bad_size;
           72  +				case k_platform_error_EMFILE: return kmcond_too_many;
           73  +				case k_platform_error_ENOMEM: return kmcond_no_room;
           74  +				default: return kmcond_fail_assert;
           75  +			}
           76  +		}
           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  +
    59     82   		/* impl note: while per manpage fd is "ignored"
    60     83   		 * for MAP_ANONYMOUS, "some implementations" require
    61     84   		 * a value of -1 */
    62     85   
    63         -		if (region.raw == (void*) -1) return null;
    64         -		/* worth retrieving errno? discuss */
    65         -
    66     86   #	else
    67     87    	   Knoimpl(kmheapa,KVos);
    68     88   #		error missing implementation
    69     89   #	endif
    70     90   	
    71     91   	void* const object = (region.byte + sizeof (kmbox));
    72     92   
    73     93   	region.header -> kind = kmkind_heap;
    74     94   	region.header -> size = len;
    75     95   
    76         -	return object;
           96  +	*where = object;
           97  +	return kmcond_ok;
    77     98   }