refactor type and cdefs headers

This commit is contained in:
anna 2021-10-12 01:31:49 +02:00
parent e6e3f90d08
commit afbb3743d5
Signed by: fef
GPG key ID: EC22E476DC2D3D84
7 changed files with 536 additions and 54 deletions
arch/x86/include/arch
include/gay
lib/c

View file

@ -2,10 +2,6 @@
#pragma once
#ifndef _SYS_CDEFS_H_
#error this file needs sys/cdefs.h as a prerequisite
#endif
#include <arch/_limits.h>
#define __NO_STRICT_ALIGNMENT
@ -22,12 +18,12 @@ typedef unsigned int __uint32_t;
#ifdef __LP64__
typedef long __int64_t;
typedef unsigned long __uint64_t;
#else
#else /* not __LP64__ */
__extension__
typedef long long __int64_t;
__extension__
typedef unsigned long long __uint64_t;
#endif
#endif /* __LP64__ */
/*
* Standard type definitions.
@ -35,22 +31,22 @@ typedef unsigned long long __uint64_t;
#ifdef __LP64__
typedef __int32_t __clock_t; /* clock()... */
typedef __int64_t __critical_t;
#ifndef _STANDALONE
#if !defined(__KERNEL__) && !defined(_FREESTANDING)
typedef double __double_t;
typedef float __float_t;
#endif
#endif /* not __KERNEL__ or _FREESTANDING */
typedef __int64_t __intfptr_t;
typedef __int64_t __intptr_t;
#else
#else /* not __LP64__ */
typedef unsigned long __clock_t;
typedef __int32_t __critical_t;
#ifndef _STANDALONE
#if !defined(__KERNEL__) && !defined(_FREESTANDING)
typedef long double __double_t;
typedef long double __float_t;
#endif
#endif /* not __KERNEL__ or _FREESTANDING */
typedef __int32_t __intfptr_t;
typedef __int32_t __intptr_t;
#endif
#endif /* __LP64__ */
typedef __int64_t __intmax_t;
typedef __int32_t __int_fast8_t;
typedef __int32_t __int_fast16_t;
@ -69,7 +65,7 @@ typedef __int64_t __ssize_t; /* byte count or error */
typedef __int64_t __time_t; /* time()... */
typedef __uint64_t __uintfptr_t;
typedef __uint64_t __uintptr_t;
#else
#else /* not __LP64__ */
typedef __int32_t __ptrdiff_t;
typedef __int32_t __register_t;
typedef __int32_t __segsz_t;
@ -78,7 +74,7 @@ typedef __int32_t __ssize_t;
typedef __int32_t __time_t;
typedef __uint32_t __uintfptr_t;
typedef __uint32_t __uintptr_t;
#endif
#endif /* __LP64__ */
typedef __uint64_t __uintmax_t;
typedef __uint32_t __uint_fast8_t;
typedef __uint32_t __uint_fast16_t;
@ -93,12 +89,12 @@ typedef __uint64_t __u_register_t;
typedef __uint64_t __vm_offset_t;
typedef __uint64_t __vm_paddr_t;
typedef __uint64_t __vm_size_t;
#else
#else /* not __LP64__ */
typedef __uint32_t __u_register_t;
typedef __uint32_t __vm_offset_t;
typedef __uint64_t __vm_paddr_t;
typedef __uint32_t __vm_size_t;
#endif
#endif /* __LP64__ */
typedef int ___wchar_t;
#define __WCHAR_MIN __INT_MIN /* min value for a wchar_t */
@ -145,5 +141,7 @@ typedef int ___wchar_t;
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* From: @(#)ansi.h 8.2 (Berkeley) 1/4/94
* From: @(#)types.h 8.3 (Berkeley) 1/5/94
* $FreeBSD$
*/

28
include/gay/_null.h Normal file
View file

@ -0,0 +1,28 @@
/* See the end of this file for copyright and license terms. */
#pragma once
#ifndef NULL
# ifdef __cplusplus
# define NULL nullptr
# else
# define NULL ((void *)0)
# endif
#endif
/** @brief For the beloved Go enthusiasts out there */
#define nil NULL
/*
* This file is part of GayBSD.
* Copyright (c) 2021 fef <owo@fef.moe>.
*
* GayBSD is nonviolent software: you may only use, redistribute, and/or
* modify it under the terms of the Cooperative Nonviolent Public License
* (CNPL) as found in the LICENSE file in the source code root directory
* or at <https://git.pixie.town/thufie/npl-builder>; either version 7
* of the license, or (at your option) any later version.
*
* GayBSD comes with ABSOLUTELY NO WARRANTY, to the extent
* permitted by applicable law. See the CNPL for details.
*/

353
include/gay/arith.h Normal file
View file

@ -0,0 +1,353 @@
/* See the end of this file for copyright and license terms. */
#pragma once
#ifndef __clang__
#error "Unsupported compiler, please use clang"
#endif
#include <gay/cdefs.h>
/**
* @defgroup arith Safe integer arithmetic primitives
*
* @{
*/
/**
* @brief Perform an integer addition, store the result in `outptr`,
* and return whether the operation resulted in an overflow.
*
* @param outptr Where to store the result
* @param a First summand
* @param b Second summand
* @returns `true` if the addition overflowed, `false` otherwise
*/
#define add_overflow(outptr, a, b) __builtin_add_overflow(a, b, outptr)
/**
* @brief Add two `signed int`s, store the sum in `outptr`,
* and return whether the operation overflowed.
*
* @param result Where to store the result
* @param a First summand
* @param b Second summand
* @returns `true` if the addition overflowed, `false` otherwise
*/
__always_inline bool iadd_overflow(signed int *result, signed int a, signed int b)
{
return __builtin_sadd_overflow(a, b, result);
}
/**
* @brief Add two `signed long`s, store the sum in `outptr`,
* and return whether the operation overflowed.
*
* @param result Where to store the result
* @param a First summand
* @param b Second summand
* @returns `true` if the addition overflowed, `false` otherwise
*/
__always_inline bool iaddl_overflow(signed long *result, signed int a, signed int b)
{
return __builtin_saddl_overflow(a, b, result);
}
/**
* @brief Add the two `signed long long` arguments `a` and `b`,
* store the sum in `outptr`, and return whether the operation overflowed.
*
* @param result Where to store the result
* @param a First summand
* @param b Second summand
* @returns `true` if the addition overflowed, `false` otherwise
*/
__always_inline bool iaddll_overflow(signed long long *result, signed int a, signed int b)
{
return __builtin_saddll_overflow(a, b, result);
}
/**
* @brief Add the two `unsigned int` arguments `a` and `b`,
* store the sum in `outptr`, and return whether the operation overflowed.
*
* @param result Where to store the result
* @param a First summand
* @param b Second summand
* @returns `true` if the addition overflowed, `false` otherwise
*/
__always_inline bool uadd_overflow(unsigned int *result, unsigned int a, unsigned int b)
{
return __builtin_uadd_overflow(a, b, result);
}
/**
* @brief Add the two `unsigned long` arguments `a` and `b`,
* store the sum in `outptr`, and return whether the operation overflowed.
*
* @param result Where to store the result
* @param a First summand
* @param b Second summand
* @returns `true` if the addition overflowed, `false` otherwise
*/
__always_inline bool uaddl_overflow(unsigned long *result, unsigned long a, unsigned long b)
{
return __builtin_uaddl_overflow(a, b, result);
}
/**
* @brief Add the two `unsigned long long` arguments `a` and `b`,
* store the sum in `outptr`, and return whether the operation overflowed.
*
* @param result Where to store the result
* @param a First summand
* @param b Second summand
* @returns `true` if the addition overflowed, `false` otherwise
*/
__always_inline bool uaddll_overflow(unsigned long long *result,
unsigned long long a, unsigned long long b)
{
return __builtin_uaddll_overflow(a, b, result);
}
/**
* @brief Test whether the sum of `a` and `b` would overflow for
* a given `type` of result operand, but discharge the result.
*
* @param type Type that would store the result
* @param a First summand
* @param b Second summand
* @returns `true` if the sum would **not** fit inside `type`, `false` otherwise
*/
#define add_test_overflow(type, a, b) __builtin_add_p(a, b, type)
/**
* @brief Perform an integer subtraction and store the result to `outptr`,
* and return whether the operation resulted in an underflow.
*
* @param outptr Where to store the result
* @param a The minuend
* @param b The subtrahend
* @returns `true` if the difference underflowed, `false` otherwise
*/
#define sub_underflow(outptr, a, b) __builtin_sub_overflow(a, b, outptr)
/**
* @brief Add two `signed int`s, store the result,
* and return whether the operation overflowed.
*
* @param result Where to store the result
* @param a The minuend
* @param b The subtrahend
* @returns `true` if the difference underflowed, `false` otherwise
*/
__always_inline bool isub_underflow(signed int *result, signed int a, signed int b)
{
return __builtin_ssub_overflow(a, b, result);
}
/**
* @brief Add two `signed long`s, store the result,
* and return whether the operation overflowed.
*
* @param result Where to store the result
* @param a The minuend
* @param b The subtrahend
* @returns `true` if the difference underflowed, `false` otherwise
*/
__always_inline bool isubl_underflow(signed long *result, signed long a, signed long b)
{
return __builtin_ssubl_overflow(a, b, result);
}
/**
* @brief Add the two `signed long long` arguments `a` and `b`,
* store the result, and return whether the operation overflowed.
*
* @param result Where to store the result
* @param a The minuend
* @param b The subtrahend
* @returns `true` if the difference underflowed, `false` otherwise
*/
__always_inline bool isubll_underflow(signed long long *result,
signed long long a, signed long long b)
{
return __builtin_ssubll_overflow(a, b, result);
}
/**
* @brief Add the two `unsigned int` arguments `a` and `b`,
* store the result, and return whether the operation overflowed.
*
* @param result Where to store the result
* @param a The minuend
* @param b The subtrahend
* @returns `true` if the difference underflowed, `false` otherwise
*/
__always_inline bool usub_underflow(unsigned int *result, unsigned int a, unsigned int b)
{
return __builtin_usub_overflow(a, b, result);
}
/**
* @brief Add the two `unsigned long` arguments `a` and `b`,
* store the result, and return whether the operation overflowed.
*
* @param result Where to store the result
* @param a The minuend
* @param b The subtrahend
* @returns `true` if the difference underflowed, `false` otherwise
*/
__always_inline bool usubl_underflow(unsigned long *result, unsigned long a, unsigned long b)
{
return __builtin_usubl_overflow(a, b, result);
}
/**
* @brief Add the two `unsigned long long` arguments `a` and `b`,
* store the result, and return whether the operation overflowed.
*
* @param result Where to store the result
* @param a The minuend
* @param b The subtrahend
* @returns `true` if the difference underflowed, `false` otherwise
*/
__always_inline bool usubll_underflow(unsigned long long *result,
unsigned long long a, unsigned long long b)
{
return __builtin_usubll_overflow(a, b, result);
}
/**
* @brief Test whether the difference between `a` and `b` would underflow for
* a given `type` of result operand, but discharge the result.
*
* @param type Type that would store the result
* @param a The minuend
* @param b The subtrahend
* @returns `true` if the difference would underflow, `false` otherwise
*/
#define sub_test_underflow(type, a, b) __builtin_sub_p(a, b, type)
/**
* @brief Perform an integer multiplication, store the result in `outptr`,
* and return whether the operation resulted in an overflow.
*
* @param outptr Where to store the result
* @param a First factor
* @param b Second factor
* @returns `true` if the multiplication overflowed, `false` otherwise
*/
#define mul_overflow(outptr, a, b) __builtin_mul_overflow(a, b, outptr)
/**
* @brief Multiply two `signed int`s, store the result,
* and return whether the operation overflowed.
*
* @param outptr Where to store the result
* @param a First factor
* @param b Second factor
* @returns `true` if the addition overflowed, `false` otherwise
*/
__always_inline bool imul_overflow(signed int *result, signed int a, signed int b)
{
return __builtin_smul_overflow(a, b, result);
}
/**
* @brief Multiply two `signed long`s, store the result,
* and return whether the operation overflowed.
*
* @param outptr Where to store the result
* @param a First factor
* @param b Second factor
* @returns `true` if the addition overflowed, `false` otherwise
*/
__always_inline bool imul_l_overflow(signed long *result, signed int a, signed int b)
{
return __builtin_smull_overflow(a, b, result);
}
/**
* @brief Multiply the two `signed long long` arguments `a` and `b`,
* store the result, and return whether the operation overflowed.
*
* @param outptr Where to store the result
* @param a First factor
* @param b Second factor
* @returns `true` if the addition overflowed, `false` otherwise
*/
__always_inline bool imul_ll_overflow(signed long long *result, signed int a, signed int b)
{
return __builtin_smulll_overflow(a, b, result);
}
/**
* @brief Multiply the two `unsigned int` arguments `a` and `b`,
* store the result, and return whether the operation overflowed.
*
* @param result Where to store the result
* @param a First factor
* @param b Second factor
* @returns `true` if the addition overflowed, `false` otherwise
*/
__always_inline bool umul_overflow(unsigned int *result, unsigned int a, unsigned int b)
{
return __builtin_umul_overflow(a, b, result);
}
/**
* @brief Multiply the two `unsigned long` arguments `a` and `b`,
* store the result, and return whether the operation overflowed.
*
* @param result Where to store the result
* @param a First factor
* @param b Second factor
* @returns `true` if the addition overflowed, `false` otherwise
*/
__always_inline bool umul_l_overflow(unsigned long *result, unsigned long a, unsigned long b)
{
return __builtin_umull_overflow(a, b, result);
}
/**
* @brief Multiply the two `unsigned long long` arguments `a` and `b`,
* store the result, and return whether the operation overflowed.
*
* @param result Where to store the result
* @param a First factor
* @param b Second factor
* @returns `true` if the addition overflowed, `false` otherwise
*/
__always_inline bool umul_ll_overflow(unsigned long long *result,
unsigned long long a, unsigned long long b)
{
return __builtin_umulll_overflow(a, b, result);
}
/**
* @brief Test whether the product of `a` and `b` would overflow for
* a given `type` of result operand.
*
* @param type Type that would store the result
* @param a First factor
* @param b Second factor
* @returns `true` if the sum would **not** fit inside `type`, `false` otherwise
*/
#define mul_test_overflow(type, a, b) __builtin_mul_p(a, b, type)
/** @} */
/*
* This file is part of GayBSD.
* Copyright (c) 2021 fef <owo@fef.moe>.
*
* GayBSD is nonviolent software: you may only use, redistribute, and/or
* modify it under the terms of the Cooperative Nonviolent Public License
* (CNPL) as found in the LICENSE file in the source code root directory
* or at <https://git.pixie.town/thufie/npl-builder>; either version 7
* of the license, or (at your option) any later version.
*
* GayBSD comes with ABSOLUTELY NO WARRANTY, to the extent
* permitted by applicable law. See the CNPL for details.
*/

View file

@ -6,42 +6,93 @@
#error "Unsupported compiler, please use clang"
#endif
#include <gay/_null.h>
#ifdef __cplusplus
/** @brief Use `__restrict` in header files, and just `restrict` in C code */
#define __restrict
#endif
/** @brief Annotated symbol is an alias for another symbol. */
#define __alias(name) __attribute__(( alias(#name) ))
/** @brief Force a type to be aligned to a certain number of bytes. */
#define __aligned(bytes) __attribute__(( aligned(bytes) ))
/*
* gcc might try to be all cute and already predefine this for us.
* I know gcc is not supported, but i'm still putting it inside an ifdef
* just in case the clang people decide to do that as well at some point.
*/
#ifndef __always_inline
/** @brief Always try to inline a function, even with optimizations disabled. */
#define __always_inline inline __attribute__(( always_inline ))
#endif
#define __hidden __attribute__(( visibility("hidden") ))
/**
* @brief Annotated function behaves like an allocator, so the branch
* prediction optimizer will assume it's unlikely to return `NULL`.
*/
#define __malloc_like __attribute__(( malloc ))
/**
* @brief Hint that the returned pointer will be able to hold at least as much
* bytes as specified by argument number `argn` (counting from 1).
*/
#define __alloc_size(argn) __attribute__(( alloc_size(argn) ))
/**
* @brief Hint that the returned pointer will be able to hold at least as much
* bytes as the product of the arguments `argn1` and `argn2` (counting from 1).
*/
#define __alloc_size2(argn1, argn2) __attribute__(( alloc_size(argn1, argn2) ))
/**
* @brief Tightly pack all members of a structure without any padding at the
* cost of performance. Should only be used for hardware registers and such.
*/
#define __packed __attribute__(( packed ))
/**
* @brief Function does not have any side effects or internal state.
* Subsequent calls with the same parameters always return the same result.
*/
#define __pure __attribute__(( pure ))
/**
* @brief Like `__pure`, and the function additionally does not access or
* manipulate any volatile memory except its own stack.
*/
#define __pure2 __attribute__(( const ))
/** @brief Put the annotated symbol in a specific section. */
#define __section(name) __attribute__(( section(#name) ))
/** @brief Mark the symbol as used, even if it really isn't. */
#define __used __attribute__(( used ))
#define __weak __attribute(( weak ))
/** @brief Symbol may be silently redefined. */
#define __weak __attribute__(( weak ))
#ifdef __cplusplus
/**
* @brief If for whatever reason we ever get into the unfortunate situation of
* having to use C++, this annotation disables the funny name mangling feature
* so we actually have a chance of accessing the symbol from assembly. It also
* forcefully marks it as `__used` because a certain IDE doesn't have full
* assembly support even after it being in the issue tracker for 4 years and
* would therefore spit out annoying warnings about the symbol bring unused.
*/
#define __asmlink __used extern "C"
#else
/* this is mainly for IDEs w/out full assembly support (looking at you, CLion) */
/**
* @brief In non-C++ code, this isn't really required because C doesn't do name
* mangling, but we declare it `__used` because a certain IDE (*cough* CLion)
* doesn't have full assembly support and shows annoying unused warnings
*/
#define __asmlink __used
#endif
#ifndef NULL
#define NULL ((void *)0)
#endif
#ifndef offsetof
#define offsetof(type, member) __builtin_offsetof(type, member)
#endif

View file

@ -39,8 +39,7 @@ enum mm_flags {
* @param flags Allocation flags
* @returns The allocated memory area, or `NULL` if OOM
*/
__attribute__(( malloc ))
void *kmalloc(size_t size, enum mm_flags flags);
void *kmalloc(size_t size, enum mm_flags flags) __malloc_like __alloc_size(1);
/**
* @brief Release memory.

View file

@ -2,45 +2,94 @@
#pragma once
#ifndef NULL
#define NULL ((void *)0)
#endif
#include <gay/_null.h>
#include <arch/_types.h>
typedef _Bool bool;
#define true ((bool)1)
#define false ((bool)0)
#ifndef _BOOL_DECLARED
# define _BOOL_DECLARED 1
# ifndef __cplusplus
# if __STDC_VERSION__ >= 199901L
typedef _Bool bool;
# else
typedef __uint8_t bool;
# endif
# define true ((bool)1)
# define false ((bool)0)
# endif /* not __cplusplus */
#endif /* not _BOOL_DECLARED */
typedef __INT8_TYPE__ i8;
typedef __UINT8_TYPE__ u8;
typedef __int8_t i8;
typedef __uint8_t u8;
typedef __INT16_TYPE__ i16;
typedef __UINT16_TYPE__ u16;
typedef __int16_t i16;
typedef __uint16_t u16;
typedef __INT32_TYPE__ i32;
typedef __UINT32_TYPE__ u32;
typedef __int32_t i32;
typedef __uint32_t u32;
typedef __INT64_TYPE__ i64;
typedef __UINT64_TYPE__ u64;
typedef __int64_t i64;
typedef __int64_t u64;
typedef __SIZE_TYPE__ size_t;
typedef __PTRDIFF_TYPE__ ptrdiff_t;
typedef __INTPTR_TYPE__ intptr_t;
typedef __UINTPTR_TYPE__ uintptr_t;
typedef __ssize_t isize;
typedef __size_t usize;
#define unsigned signed /* l00k @ d33z m4d h4xx0r sk1llz!!1 */
typedef __SIZE_TYPE__ ssize_t;
#undef unsigned
typedef __register_t word_t;
typedef __u_register_t uword_t;
typedef ssize_t isize;
typedef size_t usize;
#ifndef _SIZE_T_DECLARED
#define _SIZE_T_DECLARED 1
typedef __size_t size_t;
#endif /* not _SIZE_T_DECLARED */
typedef __INTMAX_TYPE__ intmax_t;
typedef __UINTMAX_TYPE__ uintmax_t;
typedef __WCHAR_TYPE__ wchar_t;
#ifndef _PTRDIFF_T_DECLARED
#define _PTRDIFF_T_DECLARED 1
typedef __ptrdiff_t ptrdiff_t;
#endif /* not _PTRDIFF_T_DECLARED */
#ifndef _INTPTR_T_DECLARED
#define _INTPTR_T_DECLARED 1
typedef __intptr_t intptr_t;
#endif /* not _INTPTR_T_DECLARED */
#ifndef _UINTPTR_T_DECLARED
#define _UINTPTR_T_DECLARED 1
typedef __uintptr_t uintptr_t;
#endif /* not _UINTPTR_T_DECLARED */
#ifndef _SSIZE_T_DECLARED
#define _SSIZE_T_DECLARED 1
typedef __ssize_t ssize_t;
#endif /* not _SSIZE_T_DECLARED */
#ifndef _INTMAX_T_DECLARED
#define _INTMAX_T_DECLARED 1
typedef __intmax_t intmax_t;
#endif /* not _INTMAX_T_DECLARED */
#ifndef _UINTMAX_T_DECLARED
#define _UINTMAX_T_DECLARED 1
typedef __uintmax_t uintmax_t;
#endif /* not _UINTMAX_T_DECLARED */
#ifndef _WCHAR_T_DECLARED
#define _WCHAR_T_DECLARED 1
typedef __WCHAR_TYPE__ wchar_t;
#endif /* not _WCHAR_T_DECLARED */
#ifndef _WINT_T_DECLARED
#define _WINT_T_DECLARED 1
typedef __WINT_TYPE__ wint_t;
#endif /* not _WINT_T_DECLARED */
typedef intptr_t word_t;
typedef uintptr_t uword_t;
#ifndef _REGISTER_T_DECLARED
#define _REGISTER_T_DECLARED 1
typedef __register_t register_t;
#endif /* not _REGISTER_T_DECLARED */
#ifndef _U_REGISTER_T_DECLARED
#define _U_REGISTER_T_DECLARED 1
typedef __u_register_t u_register_t;
#endif /* not _U_REGISTER_T_DECLARED */
/*
* This file is part of GayBSD.

View file

@ -2,7 +2,11 @@
add_library(c)
target_include_directories(c PRIVATE ${GAY_INCLUDE_DIRS})
target_compile_definitions(c PRIVATE ${GAY_DEFINITIONS} __BSD_VISIBLE=1 _KERNEL=1)
target_compile_definitions(c PRIVATE
${GAY_DEFINITIONS}
__BSD_VISIBLE=1
_POSIX_C_SOURCE=201709L
)
target_include_directories(c PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")