[all] Remove dependencies on non-freestanding libc

This is the first of two rather big changes to clean up includes
throughout the project. In this commit, the implicit semi-dependency on
libc that bonnibel adds to every module is removed. Previously, I was
sloppy with includes of libc headers and include directory order. Now,
the freestanding headers from libc are split out into libc_free, and an
implicit real dependency is added onto this module, unless `no_libc` is
set to `True`. The full libc needs to be explicitly specified as a
dependency to be used.

Several things needed to change in order to do this:

- Many places use `memset` or `memcpy` that cannot depend on libc. The
  kernel has basic implementations of them itself for this reason. Now
  those functions are moved into the lower-level `j6/memutils.h`, and
  libc merely references them. Other modules are now free to reference
  those functions from libj6 instead.
- The kernel's `assert.h` was renamed kassert.h (matching its `kassert`
  function) so that the new `util/assert.h` can use `__has_include` to
  detect it and make sure the `assert` macro is usable in libutil code.
- Several implementation header files under `__libj6/` also moved under
  the new libc_free.
- A new `include_phase` property has been added to modules for Bonnibel,
  which can be "normal" (default) or "late" which uses `-idirafter`
  instead of `-I` for includes.
- Since `<utility>` and `<new>` are not freestanding, implementations of
  `remove_reference`, `forward`, `move`, and `swap` were added to the
  `util` namespace to replace those from `std`, and `util/new.h` was
  added to declare `operator new` and `operator delete`.
This commit is contained in:
Justin C. Miller
2023-07-12 19:38:31 -07:00
parent a7beb0df18
commit f5208d1641
74 changed files with 233 additions and 210 deletions

View File

@@ -1,41 +0,0 @@
#pragma once
/** \file j6libc/bits.h
* Internal helpers for bitwise math.
*
* This file is part of the C standard library for the jsix operating
* system.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef __cplusplus
#error "__j6libc/bits.h included by non-C++ code"
#endif
#include <stdint.h>
#include <__j6libc/size_t.h>
namespace __j6libc {
constexpr size_t log2(size_t n) {
return n < 2 ? 0 : 1 + log2(n/2);
}
constexpr size_t word_bytes = sizeof(void*);
constexpr size_t word_bits = word_bytes << 3;
constexpr uintptr_t word_align_mask = word_bytes - 1;
constexpr unsigned word_shift = log2(word_bytes);
template <typename T>
inline bool is_aligned(uintptr_t addr) {
return (addr & (sizeof(T)-1)) == 0;
}
template <typename T, typename S>
inline bool is_aligned(S *p) {
return is_aligned<T>(reinterpret_cast<uintptr_t>(p));
}
} // namespace __j6libc

View File

@@ -1,39 +0,0 @@
#pragma once
/** \file j6libc/casts.h
* Internal implementations of casting helpers for C's bad lib types
*
* This file is part of the C standard library for the jsix operating
* system.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef __cplusplus
#error "__j6libc/casts.h included by non-C++ code"
#endif
namespace __j6libc {
template <typename T> struct non_const { using type = T; };
template <typename T> struct non_const<T*> { using type = T*; };
template <typename T> struct non_const<const T> { using type = T; };
template <typename T> struct non_const<const T*> { using type = T*; };
// cast_to: like reinterpret_cast, with an optional const_cast. Useful
// when C's stdlib wants to _take_ a const pointer, but return that
// pointer as non-const.
/*
template <typename T, typename S>
inline T cast_to(S p) { return reinterpret_cast<T>(p); }
*/
template <typename T, typename S>
__attribute__ ((always_inline))
inline T cast_to(S p) {
return reinterpret_cast<T>(const_cast<typename non_const<S>::type>(p));
}
} // namespace __j6libc

View File

@@ -1,55 +0,0 @@
#pragma once
/** \file j6libc/copy.h
* Internal implementations to aid in implementing mem* functions
*
* This file is part of the C standard library for the jsix operating
* system.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef __cplusplus
#error "__j6libc/copy.h included by non-C++ code"
#endif
#include <stddef.h>
#include <__j6libc/size_t.h>
namespace __j6libc {
template <size_t N>
inline void do_copy(char *s1, const char *s2) {
#if __has_builtin(__builtin_memcpy_inline)
__builtin_memcpy_inline(s1, s2, N);
#else
#warn "Not using __builtin_memcpy_inline for memcpy"
for (size_t i = 0; i < N; ++i)
s1[i] = s2[i];
#endif
}
template <size_t N>
inline void do_double_copy(char *s1, const char *s2, size_t n) {
do_copy<N>(s1, s2);
ptrdiff_t off = n - N;
if (!off) return;
do_copy<N>(s1+off, s2+off);
}
__attribute__((always_inline))
inline void do_large_copy(char *s1, const char *s2, size_t n) {
asm volatile ("rep movsb" : "+D"(s1), "+S"(s2), "+c"(n) :: "memory");
}
__attribute__((always_inline))
inline void do_backward_copy(char *s1, const char *s2, size_t n) {
for (size_t i = n - 1; i < n; --i)
s1[i] = s2[i];
}
} // namespace __j6libc

View File

@@ -1,13 +0,0 @@
#pragma once
/** \file j6libc/null.h
* Internal definition of NULL
*
* This file is part of the C standard library for the jsix operating
* system.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#define NULL ((void*)0)

View File

@@ -1,15 +0,0 @@
#pragma once
/** \file j6libc/restrict.h
* Internal handling of restrict keyword for C++
*
* This file is part of the C standard library for the jsix operating
* system.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifdef __cplusplus
#define restrict __restrict__
#endif

View File

@@ -1,24 +0,0 @@
#pragma once
/** \file j6libc/size_t.h
* Internal definition of size_t
*
* This file is part of the C standard library for the jsix operating
* system.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
typedef __SIZE_TYPE__ size_t;
#define SIZE_MAX __SIZE_MAX__
#if __SIZE_WIDTH__ == 32
#define SIZE_C( x ) x ## __UINT32_C_SUFFIX__
#elif __SIZE_WIDTH__ == 64
#define SIZE_C( x ) x ## __UINT64_C_SUFFIX__
#elif __SIZE_WIDTH__ == 128
#define SIZE_C( x ) x ## __UINT128_C_SUFFIX__
#else
#error Unsupported size_t width
#endif

View File

@@ -1,18 +0,0 @@
#pragma once
/** \file j6libc/wchar_t.h
* Internal definition of wchar_t
*
* This file is part of the C standard library for the jsix operating
* system.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef __cplusplus
typedef __WCHAR_TYPE__ wchar_t;
#endif
#define WCHAR_MAX __WCHAR_MAX__
#define WCHAR_MIN ((-__WCHAR_MAX__) - 1)

View File

@@ -1,58 +0,0 @@
#pragma once
/** \file float.h
* Characteristics of floating types
*
* This file is part of the C standard library for the jsix operating
* system.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#define FLT_RADIX __FLT_RADIX__
#define FLT_MANT_DIG __FLT_MANT_DIG__
#define DBL_MANT_DIG __DBL_MANT_DIG__
#define LDBL_MANT_DIG __LDBL_MANT_DIG__
#define FLT_DECIMAL_DIG __FLT_DECIMAL_DIG__
#define DBL_DECIMAL_DIG __DBL_DECIMAL_DIG__
#define LDBL_DECIMAL_DIG __LDBL_DECIMAL_DIG__
#define DECIMAL_DIG __DECIMAL_DIG__
#define FLT_DIG __FLT_DIG__
#define DBL_DIG __DBL_DIG__
#define LDBL_DIG __LDBL_DIG__
#define FLT_MIN_EXP __FLT_MIN_EXP__
#define DBL_MIN_EXP __DBL_MIN_EXP__
#define LDBL_MIN_EXP __LDBL_MIN_EXP__
#define FLT_MAX_EXP __FLT_MAX_EXP__
#define DBL_MAX_EXP __DBL_MAX_EXP__
#define LDBL_MAX_EXP __LDBL_MAX_EXP__
#define FLT_MIN_10_EXP __FLT_MIN_10_EXP__
#define DBL_MIN_10_EXP __DBL_MIN_10_EXP__
#define LDBL_MIN_10_EXP __LDBL_MIN_10_EXP__
#define FLT_MAX_10_EXP __FLT_MAX_10_EXP__
#define DBL_MAX_10_EXP __DBL_MAX_10_EXP__
#define LDBL_MAX_10_EXP __LDBL_MAX_10_EXP__
#define FLT_MIN __FLT_MIN__
#define FLT_MAX __FLT_MAX__
#define FLT_EPSILON __FLT_EPSILON__
#define FLT_TRUE_MIN FLT_MIN
#define DBL_MIN __DBL_MIN__
#define DBL_MAX __DBL_MAX__
#define DBL_EPSILON __DBL_EPSILON__
#define DBL_TRUE_MIN DBL_MIN
#define LDBL_MIN __LDBL_MIN__
#define LDBL_MAX __LDBL_MAX__
#define LDBL_EPSILON __LDBL_EPSILON__
#define LDBL_TRUE_MIN LDBL_MIN

View File

@@ -1,23 +0,0 @@
#pragma once
/** \file iso646.h
* Alternative spellings
*
* This file is part of the C standard library for the jsix operating
* system.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#define and &&
#define and_eq &=
#define bitand &
#define bitor |
#define compl ~
#define not !
#define not_eq !=
#define or ||
#define or_eq |=
#define xor ^
#define xor_eq ^=

View File

@@ -26,6 +26,7 @@ libc = module("libc",
kind = "lib",
deps = [ "j6" ],
output = "libc.a",
include_phase = "late",
sources = sources,
public_headers = headers,
)

View File

@@ -1,84 +0,0 @@
#pragma once
/** \file limits.h
* Sizes of integer types
*
* This file is part of the C standard library for the jsix operating
* system.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#define CHAR_BIT __CHAR_BIT__
#define SCHAR_MAX __SCHAR_MAX__
#define SCHAR_MIN ((-__SCHAR_MAX__) - 1)
#define UCHAR_MAX __UCHAR_MAX__
#if ((char)-1) < 0
// char is signed
#define CHAR_MAX SCHAR_MAX
#define CHAR_MIN SCHAR_MIN
#else
// char is unsigned
#define CHAR_MAX UCHAR_MAX
#define CHAR_MIN 0
#endif
#define MB_LEN_MAX
#define SHRT_MAX __SHRT_MAX__
#define SHRT_MIN ((-__SHRT_MAX__) - 1)
#if __SIZEOF_SHORT__ == 1
#define USHRT_MAX __UINT8_MAX__
#elif __SIZEOF_SHORT__ == 2
#define USHRT_MAX __UINT16_MAX__
#elif __SIZEOF_SHORT__ == 4
#define USHRT_MAX __UINT32_MAX__
#endif
#define INT_MAX __INT_MAX__
#define INT_MIN ((-__INT_MAX__) - 1)
#if __SIZEOF_INT__ == 1
#define UINT_MAX __UINT8_MAX__
#elif __SIZEOF_INT__ == 2
#define UINT_MAX __UINT16_MAX__
#elif __SIZEOF_INT__ == 4
#define UINT_MAX __UINT32_MAX__
#elif __SIZEOF_INT__ == 8
#define UINT_MAX __UINT64_MAX__
#endif
#define LONG_MAX __LONG_MAX__
#define LONG_MIN ((-__LONG_MAX__) - 1)
#if __SIZEOF_LONG__ == 1
#define ULONG_MAX __UINT8_MAX__
#elif __SIZEOF_LONG__ == 2
#define ULONG_MAX __UINT16_MAX__
#elif __SIZEOF_LONG__ == 4
#define ULONG_MAX __UINT32_MAX__
#elif __SIZEOF_LONG__ == 8
#define ULONG_MAX __UINT64_MAX__
#elif __SIZEOF_LONG__ == 16
#define ULONG_MAX __UINT128_MAX__
#endif
#define LLONG_MAX __LONG_LONG_MAX__
#define LLONG_MIN ((-__LONG_LONG_MAX__) - 1)
#if __SIZEOF_LONG_LONG__ == 1
#define ULLONG_MAX __UINT8_MAX__
#elif __SIZEOF_LONG_LONG__ == 2
#define ULLONG_MAX __UINT16_MAX__
#elif __SIZEOF_LONG_LONG__ == 4
#define ULLONG_MAX __UINT32_MAX__
#elif __SIZEOF_LONG_LONG__ == 8
#define ULLONG_MAX __UINT64_MAX__
#elif __SIZEOF_LONG_LONG__ == 16
#define ULLONG_MAX __UINT128_MAX__
#endif

View File

@@ -1,20 +0,0 @@
#pragma once
/** \file stdalign.h
* Alignment
*
* This file is part of the C standard library for the jsix operating
* system.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef __cplusplus
#define alignas _Alignas
#define alignof _Alignof
#endif
#define __alignas_is_defined 1
#define __alignof_is_defined 1

View File

@@ -1,18 +0,0 @@
#pragma once
/** \file stdarg.h
* Variable arguments
*
* This file is part of the C standard library for the jsix operating
* system.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
typedef __builtin_va_list va_list;
#define va_arg( ap, type ) (__builtin_va_arg( (ap), type ))
#define va_copy( dest, src ) (__builtin_va_copy( (dest), (src) ))
#define va_end( ap ) (__builtin_va_end( (ap) ))
#define va_start( ap, parmN ) (__builtin_va_start( (ap), (parmN) ))

View File

@@ -1,19 +0,0 @@
#pragma once
/** \file stdbool.h
* Boolean type and values
*
* This file is part of the C standard library for the jsix operating
* system.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef __cplusplus
#define bool _Bool
#define true 1
#define false 0
#endif
#define __bool_true_false_are_defined 1

View File

@@ -1,27 +0,0 @@
#pragma once
/** \file stddef.h
* Common definitions
*
* This file is part of the C standard library for the jsix operating
* system.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include <__j6libc/null.h>
#include <__j6libc/size_t.h>
#include <__j6libc/wchar_t.h>
typedef __PTRDIFF_TYPE__ ptrdiff_t;
#if __BIGGEST_ALIGNMENT__ == __SIZEOF_LONG_DOUBLE__
typedef long double max_align_t;
#else
typedef long long max_align_t;
#endif
#define offsetof(x, y) __builtin_offsetof(x, y)
#define NULL ((void*)0)

View File

@@ -1,68 +0,0 @@
#pragma once
/** \file stdint.h
* Fixed-width integer types
*
* This file is part of the C standard library for the jsix operating
* system.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
/**[[[cog code generation
import cog
from j6libc import definition, int_widths, int_mods
for width in int_widths:
definition("typedef", f"__INT{width}_TYPE__", f"int{width}_t;")
definition("#define", f"INT{width}_WIDTH", f"{width}")
definition("#define", f"INT{width}_MAX", f"__INT{width}_MAX__")
definition("#define", f"INT{width}_MIN", f"((-__INT{width}_MAX__) - 1)")
definition("#define", f"INT{width}_C( x )", f"x ## __INT{width}_C_SUFFIX__")
cog.outl()
definition("typedef", f"__UINT{width}_TYPE__", f"uint{width}_t;")
definition("#define", f"UINT{width}_WIDTH", f"{width}")
definition("#define", f"UINT{width}_MAX", f"__UINT{width}_MAX__")
definition("#define", f"UINT{width}_C( x )", f"x ## __UINT{width}_C_SUFFIX__")
for mod in int_mods:
cog.outl()
definition("typedef", f"__INT_{mod.upper()}{width}_TYPE__", f"int_{mod}{width}_t;")
definition("typedef", f"__UINT_{mod.upper()}{width}_TYPE__", f"uint_{mod}{width}_t;")
definition("#define", f"INT_{mod.upper()}{width}_WIDTH", f"{width}")
definition("#define", f"INT_{mod.upper()}{width}_MAX", f"__INT_{mod.upper()}{width}_MAX__")
definition("#define", f"INT_{mod.upper()}{width}_MIN", f"((-__INT_{mod.upper()}{width}_MAX) - 1)")
cog.outl()
definition("typedef", f"__UINT_{mod.upper()}{width}_TYPE__", f"uint_least{width}_t;")
definition("#define", f"UINT_{mod.upper()}{width}_WIDTH", f"{width}")
definition("#define", f"UINT_{mod.upper()}{width}_MAX", f"__UINT_{mod.upper()}{width}_MAX__")
cog.outl()
]]]*/
/*[[[end]]]*/
typedef __INTMAX_TYPE__ intmax_t;
#define INTMAX_WIDTH __INTMAX_WIDTH__
#define INTMAX_MAX __INTMAX_MAX__
#define INTMAX_MIN ((-__INTMAX_MAX__) - 1)
#define INTMAX_C( x ) x ## __INTMAX_C_SUFFIX__
typedef __UINTMAX_TYPE__ uintmax_t;
#define UINTMAX_WIDTH __UINTMAX_WIDTH__
#define UINTMAX_MAX __UINTMAX_MAX__
#define UINTMAX_C( x ) x ## __UINTMAX_C_SUFFIX__
typedef __INTPTR_TYPE__ intptr_t;
#define INTPTR_WIDTH __INTPTR_WIDTH__
#define INTPTR_MAX __INTPTR_MAX__
#define INTPTR_MIN ((-__INTPTR_MAX__) - 1)
typedef __UINTPTR_TYPE__ uintptr_t;
#define UINTPTR_WIDTH __UINTPTR_WIDTH__
#define UINTPTR_MAX __UINTPTR_MAX__
/* vim: set ft=c: */

View File

@@ -1,17 +0,0 @@
#pragma once
/** \file stdnoreturn.h
* noreturn convenience macros
*
* This file is part of the C standard library for the jsix operating
* system.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#if !defined(__cplusplus) && __STDC_VERSION__ >= 201103L
#define noreturn _Noreturn
#elif !defined(__cplusplus)
#define noreturn
#endif

View File

@@ -1,17 +0,0 @@
/** \file memcpy.cpp
*
* This file is part of the C standard library for the jsix operating
* system.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include <string.h>
#include <stddef.h>
void *memcpy(void * restrict s1, const void * restrict s2, size_t n) {
asm volatile ("rep movsb" : "+D"(s1), "+S"(s2), "+c"(n) :: "memory");
return s1;
}

View File

@@ -1,33 +0,0 @@
/** \file memmove.cpp
*
* This file is part of the C standard library for the jsix operating
* system.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include <string.h>
#include <__j6libc/copy.h>
using namespace __j6libc;
void memmove_dispatch(char *s1, const char *s2, size_t n) {
if (s1 == s2) return;
if (s1 < s2 || s1 > s2 + n)
memcpy(s1, s2, n);
else
do_backward_copy(s1, s2, n);
}
void *memmove(void * restrict s1, const void * restrict s2, size_t n) {
memmove_dispatch(
reinterpret_cast<char*>(s1),
reinterpret_cast<const char*>(s2),
n);
return s1;
}

View File

@@ -1,57 +0,0 @@
/** \file memset.cpp
*
* This file is part of the C standard library for the jsix operating
* system.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include <string.h>
#include <__j6libc/bits.h>
#include <__j6libc/casts.h>
using namespace __j6libc;
#if __UINTPTR_WIDTH__ != 64 && __UINTPTR_WIDTH__ != 32
#error "memset: uintptr_t isn't 4 or 8 bytes"
#endif
static inline uintptr_t repval(uint8_t c) {
uintptr_t r = c;
r |= r << 8;
r |= r << 16;
#if __UINTPTR_WIDTH__ == 64
r |= r << 32;
#endif
return r;
}
void *memset(void *s, int c, size_t n) {
if (!s) return nullptr;
// First, any unalined initial bytes
uint8_t *b = cast_to<uint8_t*>(s);
uint8_t bval = c & 0xff;
while (n && !is_aligned<uintptr_t>(b)) {
*b++ = bval;
--n;
}
// As many word-sized writes as possible
size_t words = n >> word_shift;
uintptr_t pval = repval(c);
uintptr_t *p = cast_to<uintptr_t*>(b);
for (size_t i = 0; i < words; ++i)
*p++ = pval;
// Remaining unaligned bytes
b = reinterpret_cast<uint8_t*>(p);
size_t remainder = n & word_align_mask;
for (size_t i = 0; i < remainder; ++i)
*b++ = bval;
return s;
}