user: implement mlibc as the libc, finally.

It's finally done..

Signed-off-by: kaguya <vpshinomiya@protonmail.com>
This commit is contained in:
kaguya
2026-05-02 03:31:49 -04:00
parent 2fa39ad85a
commit 9a9b91c940
2387 changed files with 152741 additions and 315 deletions
@@ -0,0 +1,64 @@
#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
// va_list
void vwarn(const char *fmt, va_list params) {
fprintf(stderr, "%s: ", program_invocation_short_name);
if (fmt) {
vfprintf(stderr, fmt, params);
fwrite(": ", 1, 2, stderr);
}
perror(nullptr);
}
void vwarnx(const char *fmt, va_list params) {
fprintf(stderr, "%s: ", program_invocation_short_name);
if (fmt) {
vfprintf(stderr, fmt, params);
}
putc('\n', stderr);
}
__attribute__((__noreturn__)) void verr(int status, const char *fmt, va_list params) {
vwarn(fmt, params);
exit(status);
}
__attribute__((__noreturn__)) void verrx(int status, const char *fmt, va_list params) {
vwarnx(fmt, params);
exit(status);
}
// variadic
void warn(const char *fmt, ...) {
va_list params;
va_start(params, fmt);
vwarn(fmt, params);
va_end(params);
}
void warnx(const char *fmt, ...) {
va_list params;
va_start(params, fmt);
vwarnx(fmt, params);
va_end(params);
}
__attribute__((__noreturn__)) void err(int status, const char *fmt, ...) {
va_list params;
va_start(params, fmt);
verr(status, fmt, params);
va_end(params);
}
__attribute__((__noreturn__)) void errx(int status, const char *fmt, ...) {
va_list params;
va_start(params, fmt);
verrx(status, fmt, params);
va_end(params);
}
@@ -0,0 +1,65 @@
#include <stdio.h>
#include <stdarg.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <error.h>
unsigned int error_message_count = 0;
int error_one_per_line = 0;
void (*error_print_progname)(void) = nullptr;
void error(int status, int errnum, const char *format, ...) {
va_list args;
va_start(args, format);
error_message_count++;
fflush(stdout);
if(error_print_progname) {
error_print_progname();
} else {
fprintf(stderr, "%s: ", program_invocation_name);
}
vfprintf(stderr, format, args);
va_end(args);
if(errnum) {
fprintf(stderr, ": %s\n", strerror(errnum));
}
if(status) {
exit(status);
}
}
void error_at_line(int status, int errnum, const char *filename, unsigned int linenum, const char *format, ...) {
va_list args;
va_start(args, format);
static bool first_call = true;
static unsigned int last_line = 0;
if(!(last_line == linenum && error_one_per_line && !first_call)) {
first_call = false;
last_line = linenum;
error_message_count++;
fflush(stdout);
if(error_print_progname) {
error_print_progname();
} else {
fprintf(stderr, "%s:", program_invocation_name);
}
fprintf(stderr, "%s:%u: ", filename, linenum);
vfprintf(stderr, format, args);
if(errnum) {
fprintf(stderr, ": %s\n", strerror(errnum));
}
}
va_end(args);
if(status) {
exit(status);
}
}
@@ -0,0 +1,105 @@
#include <dlfcn.h>
#include <execinfo.h>
#include <inttypes.h>
#include <stdio.h>
#include <unistd.h>
#include <unwind.h>
#include <bits/ensure.h>
#include <mlibc/debug.hpp>
namespace {
using UnwindBacktrace = _Unwind_Reason_Code (*)(_Unwind_Trace_Fn, void *);
using UnwindGetIP = _Unwind_Ptr (*)(_Unwind_Context *);
frg::optional<void *> libgccHandle = frg::null_opt;
UnwindBacktrace unwindBacktrace = nullptr;
UnwindGetIP unwindGetIP = nullptr;
struct UnwindState {
void **frames;
int count;
int current_frame = 0;
};
_Unwind_Reason_Code trace(_Unwind_Context *context, void *arg) {
UnwindState *state = static_cast<UnwindState *>(arg);
if (state->current_frame >= state->count)
return _URC_END_OF_STACK;
uintptr_t ip = unwindGetIP(context);
if (ip) {
#if defined(__x86_64__) || defined(__i386__)
ip--;
#elif defined(__aarch64__) || defined(__loongarch64)
ip -= 4;
#elif defined(__riscv) || defined(__m68k__)
ip -= 2;
#else
#warning "Missing support for architecture"
ip--;
#endif
}
state->frames[state->current_frame++] = reinterpret_cast<void *>(ip);
return _URC_NO_REASON;
}
} // namespace
int backtrace(void **buffer, int size) {
if (size <= 0)
return 0;
if (!libgccHandle) {
libgccHandle = dlopen("libgcc_s.so.1", RTLD_LAZY | RTLD_LOCAL);
if (!libgccHandle || libgccHandle.value() == nullptr) {
mlibc::infoLogger() << "Failed to load libgcc_s.so.1: " << (dlerror() ? dlerror() : "") << frg::endlog;
return 0;
}
unwindBacktrace = reinterpret_cast<UnwindBacktrace>(dlsym(libgccHandle.value(), "_Unwind_Backtrace"));
unwindGetIP = reinterpret_cast<UnwindGetIP>(dlsym(libgccHandle.value(), "_Unwind_GetIP"));
if (!unwindBacktrace || !unwindGetIP) {
mlibc::infoLogger() << "Failed to find unwind functions in libgcc_s.so.1: " << dlerror() << frg::endlog;
return 0;
}
}
UnwindState state{buffer, size};
unwindBacktrace(trace, &state);
return state.current_frame;
}
char **backtrace_symbols(void *const *, int) {
__ensure(!"Not implemented");
__builtin_unreachable();
}
void backtrace_symbols_fd(void *const *buffer, int size, int fd) {
if (size <= 0 || fd < 0)
return;
for (int frame_num = 0; frame_num < size; frame_num++) {
Dl_info info;
if (dladdr(buffer[frame_num], &info) != 0) {
if (info.dli_fname != nullptr)
write(fd, info.dli_fname, strlen(info.dli_fname));
if (info.dli_sname != nullptr)
dprintf(fd, "(%s+0x%" PRIxPTR ") ", info.dli_sname,
reinterpret_cast<uintptr_t>(buffer[frame_num]) - reinterpret_cast<uintptr_t>(info.dli_saddr));
else if(info.dli_saddr)
dprintf(fd, "(+%p) ", info.dli_saddr);
else
dprintf(fd, "() ");
}
dprintf(fd, "[%p]\n", buffer[frame_num]);
}
}
@@ -0,0 +1,12 @@
#include <getopt.h>
#include <mlibc/getopt.hpp>
int getopt_long(int argc, char * const argv[], const char *optstring,
const struct option *longopts, int *longindex) {
return getopt_common(argc, argv, optstring, longopts, longindex, mlibc::GetoptMode::Long);
}
int getopt_long_only(int argc, char * const argv[], const char *optstring,
const struct option *longopts, int *longindex) {
return getopt_common(argc, argv, optstring, longopts, longindex, mlibc::GetoptMode::LongOnly);
}
@@ -0,0 +1,14 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <bits/ensure.h>
[[gnu::noreturn]] void __assert_fail_perror(int errno, const char *file, unsigned int line,
const char *function) {
char *errormsg = strerror(errno);
fprintf(stderr, "In function %s, file %s:%d: Errno '%s' failed!\n",
function, file, line, errormsg);
abort();
}
@@ -0,0 +1,14 @@
#include <errno.h>
#include <signal.h>
#include <bits/ensure.h>
#include <mlibc/debug.hpp>
#include <mlibc/glibc-sysdeps.hpp>
int tgkill(int tgid, int tid, int sig) {
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_tgkill, -1);
if(int e = mlibc::sys_tgkill(tgid, tid, sig); e) {
errno = e;
return -1;
}
return 0;
}
@@ -0,0 +1,7 @@
#include <gshadow.h>
#include <bits/ensure.h>
int getsgnam_r(const char *, struct sgrp *, char *, size_t, struct sgrp **) {
__ensure(!"Not implemented");
__builtin_unreachable();
}
@@ -0,0 +1,6 @@
#include <bits/glibc/glibc_malloc.h>
#include <mlibc/allocator.hpp>
size_t malloc_usable_size(void *p) {
return getAllocator().get_size(p);
}
@@ -0,0 +1,15 @@
#include <bits/ensure.h>
#include <errno.h>
#include <mlibc/glibc-sysdeps.hpp>
#include <sys/personality.h>
int personality(unsigned long persona) {
int out = 0;
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_personality, -1);
if(int e = sysdep(persona, &out); e) {
errno = e;
return -1;
}
return out;
}
@@ -0,0 +1,7 @@
#include <bits/ensure.h>
#include <printf.h>
size_t parse_printf_format(const char * __restrict, size_t, int * __restrict) {
__ensure(!"Not implemented");
__builtin_unreachable();
}
@@ -0,0 +1,41 @@
#include <resolv.h>
#include <bits/ensure.h>
#include <mlibc/debug.hpp>
int dn_expand(const unsigned char *, const unsigned char *,
const unsigned char *, char *, int) {
__ensure(!"Not implemented");
__builtin_unreachable();
}
int res_query(const char *, int, int, unsigned char *, int) {
__ensure(!"Not implemented");
__builtin_unreachable();
}
int res_init() {
mlibc::infoLogger() << "mlibc: res_init is a stub!" << frg::endlog;
return 0;
}
int res_ninit(res_state) {
mlibc::infoLogger() << "mlibc: res_ninit is a stub!" << frg::endlog;
return 0;
}
void res_nclose(res_state) {
mlibc::infoLogger() << "mlibc: res_nclose is a stub!" << frg::endlog;
return;
}
int dn_comp(const char *, unsigned char *, int, unsigned char **, unsigned char **) {
__ensure(!"Not implemented");
__builtin_unreachable();
}
/* This is completely unused, and exists purely to satisfy broken apps. */
struct __res_state *__res_state() {
static struct __res_state res;
return &res;
}
@@ -0,0 +1,14 @@
#include <bits/glibc/glibc_search.h>
#include <mlibc/search.hpp>
int hcreate_r(size_t num_entries, hsearch_data *htab) {
return mlibc::hcreate_r(num_entries, htab);
}
void hdestroy_r(hsearch_data *htab) {
mlibc::hdestroy_r(htab);
}
int hsearch_r(ENTRY item, ACTION action, ENTRY **ret, hsearch_data *htab) {
return mlibc::hsearch_r(item, action, ret, htab);
}
@@ -0,0 +1,231 @@
#include <shadow.h>
#include <errno.h>
#include <limits.h>
#include <pthread.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <bits/ensure.h>
#include <mlibc/debug.hpp>
/*
* The code in this file is largely based on or taken from musl.
* This includes:
* - xatol
* - __parsespent
* - cleanup
* - getspnam_r
* - getspnam
*/
#define NUM(n) ((n) == -1 ? 0 : -1), ((n) == -1 ? 0 : (n))
int putspent(const struct spwd *sp, FILE *f) {
auto str = [] (char *s) {
return ((s) ? (s) : "");
};
return fprintf(f, "%s:%s:%.*ld:%.*ld:%.*ld:%.*ld:%.*ld:%.*ld:%.*u\n",
str(sp->sp_namp), str(sp->sp_pwdp), NUM(sp->sp_lstchg),
NUM(sp->sp_min), NUM(sp->sp_max), NUM(sp->sp_warn),
NUM(sp->sp_inact), NUM(sp->sp_expire), NUM((int)sp->sp_flag)) < 0 ? -1 : 0;
}
#undef NUM
static long xatol(char **s) {
long x;
if(**s == ':' || **s == '\n') {
return -1;
}
for(x = 0; (unsigned int)**s - '0' < 10U; ++*s) {
x = 10 * x + (**s - '0');
}
return x;
}
static int __parsespent(char *s, struct spwd *sp) {
sp->sp_namp = s;
if(!(s = strchr(s, ':'))) {
return -1;
}
*s = 0;
sp->sp_pwdp = ++s;
if(!(s = strchr(s, ':'))) {
return -1;
}
*s = 0;
s++;
sp->sp_lstchg = xatol(&s);
if(*s != ':') {
return -1;
}
s++;
sp->sp_min = xatol(&s);
if(*s != ':') {
return -1;
}
s++;
sp->sp_max = xatol(&s);
if(*s != ':') {
return -1;
}
s++;
sp->sp_warn = xatol(&s);
if(*s != ':') {
return -1;
}
s++;
sp->sp_inact = xatol(&s);
if(*s != ':') {
return -1;
}
s++;
sp->sp_expire = xatol(&s);
if(*s != ':') {
return -1;
}
s++;
sp->sp_flag = xatol(&s);
if(*s != '\n') {
return -1;
}
return 0;
}
static void cleanup(void *p) {
fclose((FILE *)p);
}
int getspnam_r(const char *name, struct spwd *sp, char *buf, size_t size, struct spwd **res) {
char path[20 + NAME_MAX];
FILE *f = nullptr;
int rv = 0;
int fd;
size_t k, l = strlen(name);
int skip = 0;
int cs;
int orig_errno = errno;
*res = nullptr;
/* Disallow potentially-malicious user names */
if(*name=='.' || strchr(name, '/') || !l) {
return errno = EINVAL;
}
/* Buffer size must at least be able to hold name, plus some.. */
if(size < l + 100) {
return errno = ERANGE;
}
/* Protect against truncation */
if(snprintf(path, sizeof path, "/etc/tcb/%s/shadow", name) >= (int)sizeof path) {
return errno = EINVAL;
}
fd = open(path, O_RDONLY|O_NOFOLLOW|O_NONBLOCK|O_CLOEXEC);
if(fd >= 0) {
struct stat st = {};
errno = EINVAL;
if(fstat(fd, &st) || !S_ISREG(st.st_mode) || !(f = fdopen(fd, "rb"))) {
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
close(fd);
pthread_setcancelstate(cs, nullptr);
return errno;
}
} else {
if(errno != ENOENT && errno != ENOTDIR) {
return errno;
}
f = fopen("/etc/shadow", "rbe");
if(!f) {
if(errno != ENOENT && errno != ENOTDIR) {
return errno;
}
return 0;
}
}
pthread_cleanup_push(cleanup, f);
while(fgets(buf, size, f) && (k = strlen(buf)) > 0) {
if(skip || strncmp(name, buf, l) || buf[l] != ':') {
skip = buf[k - 1] != '\n';
continue;
}
if(buf[k - 1] != '\n') {
rv = ERANGE;
break;
}
if(__parsespent(buf, sp) < 0) {
continue;
}
*res = sp;
break;
}
pthread_cleanup_pop(1);
errno = rv ? rv : orig_errno;
return rv;
}
int lckpwdf(void) {
mlibc::infoLogger() << "mlibc: lckpwdf is unimplemented like musl" << frg::endlog;
return 0;
}
int ulckpwdf(void) {
mlibc::infoLogger() << "mlibc: ulckpwdf is unimplemented like musl" << frg::endlog;
return 0;
}
// Musl defines LINE_LIM to 256
#define LINE_LIM 256
struct spwd *getspnam(const char *name) {
static struct spwd sp;
static char *line;
struct spwd *res;
int e;
int orig_errno = errno;
if(!line) {
line = (char *)malloc(LINE_LIM);
}
if(!line) {
return nullptr;
}
e = getspnam_r(name, &sp, line, LINE_LIM, &res);
errno = e ? e : orig_errno;
return res;
}
struct spwd *fgetspent(FILE *f) {
static struct spwd sp;
static char *line;
struct spwd *res = nullptr;
size_t size = 0;
int cs;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
if(getline(&line, &size, f) >= 0 && __parsespent(line, &sp) >= 0) {
res = &sp;
}
pthread_setcancelstate(cs, nullptr);
return res;
}
void endspent(void) {
mlibc::infoLogger() << "mlibc: endspent is a stub" << frg::endlog;
}
struct spwd *sgetspent(const char *) {
__ensure(!"Not implemented");
__builtin_unreachable();
}
@@ -0,0 +1,84 @@
#include <mlibc/file-io.hpp>
#include <stdio_ext.h>
#include <bits/ensure.h>
#include <mlibc/debug.hpp>
size_t __fbufsize(FILE *) {
__ensure(!"Not implemented");
__builtin_unreachable();
}
size_t __fpending(FILE *file_base) {
__ensure(file_base->__dirty_end >= file_base->__dirty_begin);
return file_base->__dirty_end - file_base->__dirty_begin;
}
int __flbf(FILE *) {
__ensure(!"Not implemented");
__builtin_unreachable();
}
int __freadable(FILE *) {
__ensure(!"Not implemented");
__builtin_unreachable();
}
int __fwritable(FILE *) {
__ensure(!"Not implemented");
__builtin_unreachable();
}
int __freading(FILE *file_base) {
return file_base->__io_mode == 0;
}
int __fwriting(FILE *file_base) {
return file_base->__io_mode == 1;
}
int __fsetlocking(FILE *file_base, int state) {
auto file = static_cast<mlibc::abstract_file *>(file_base);
bool oldstate = file->_lock.uselock;
if (state != FSETLOCKING_QUERY) {
if (state == FSETLOCKING_BYCALLER) {
file->_lock.uselock = false;
} else {
file->_lock.uselock = true;
}
}
if (oldstate) {
return FSETLOCKING_INTERNAL;
} else {
return FSETLOCKING_BYCALLER;
}
}
void _flushlbf(void) {
__ensure(!"Not implemented");
__builtin_unreachable();
}
// The following functions are defined by musl.
size_t __freadahead(FILE *file_base) {
if(file_base->__io_mode != 0) {
mlibc::infoLogger() << "mlibc: __freadahead() called but file is not open for reading" << frg::endlog;
return 0;
}
return file_base->__valid_limit - file_base->__offset;
}
const char *__freadptr(FILE *, size_t *) {
__ensure(!"Not implemented");
__builtin_unreachable();
}
void __freadptrinc(FILE *, size_t) {
__ensure(!"Not implemented");
__builtin_unreachable();
}
void __fseterr(FILE *) {
__ensure(!"Not implemented");
__builtin_unreachable();
}
@@ -0,0 +1,11 @@
#include <stdlib.h>
int rpmatch(const char *resp) {
if(!resp || resp[0] == '\0')
return -1;
if(resp[0] == 'y' || resp[0] == 'Y')
return 1;
if(resp[0] == 'n' || resp[0] == 'N')
return 0;
return -1;
}
@@ -0,0 +1,32 @@
#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif
#include <type_traits>
#include <string.h>
/* This is a bit of a weird detail of the GNU implementation and C's lack of
* overloading and strictness: GNU takes const char * and returns a char * so
* that it autocasts to your desired constness, this function never actually
* modifies the string.
*/
char *__mlibc_gnu_basename_c(const char *path) {
char *basename_component = strrchr(path, '/');
if (!basename_component) {
return const_cast<char *>(path);
}
return basename_component + 1;
}
/* GNU exposes these overloads, and as a result, we should probably have them
* checked, to make sure we actually match expectations.
*/
static_assert(
std::is_same_v<decltype(basename((const char *)nullptr)), const char*>,
"C++ overloads broken"
);
static_assert(
std::is_same_v<decltype(basename((char *)nullptr)), char*>,
"C++ overloads broken"
);
@@ -0,0 +1,16 @@
#include <bits/ensure.h>
#include <errno.h>
#include <mlibc/glibc-sysdeps.hpp>
#include <sys/cachectl.h>
#ifdef __riscv
int __riscv_flush_icache(void *start, void *end, unsigned long flags) {
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_riscv_flush_icache, -1);
if(int e = sysdep(start, end, flags); e) {
errno = e;
return -1;
}
return 0;
}
#endif
@@ -0,0 +1,25 @@
#include <errno.h>
#include <sys/io.h>
#include <bits/ensure.h>
#include <mlibc/glibc-sysdeps.hpp>
int ioperm(unsigned long int from, unsigned long int num, int turn_on) {
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_ioperm, -1);
if(int e = sysdep(from, num, turn_on); e) {
errno = e;
return -1;
}
return 0;
}
int iopl(int level) {
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_iopl, -1);
if(int e = sysdep(level); e) {
errno = e;
return -1;
}
return 0;
}
@@ -0,0 +1,21 @@
#include <errno.h>
#include <sys/ioctl.h>
#include <bits/ensure.h>
#include <mlibc/debug.hpp>
#include <mlibc/glibc-sysdeps.hpp>
int ioctl(int fd, unsigned long request, ...) {
va_list args;
va_start(args, request);
int result;
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_ioctl, -1);
void *arg = va_arg(args, void *);
if(int e = mlibc::sys_ioctl(fd, request, arg, &result); e) {
errno = e;
return -1;
}
return result;
}
@@ -0,0 +1,17 @@
#include <bits/ensure.h>
#include <sys/timex.h>
int adjtimex(struct timex *) {
__ensure(!"Not implemented");
__builtin_unreachable();
}
int clock_adjtime(clockid_t, struct timex *) {
__ensure(!"Not implemented");
__builtin_unreachable();
}
int ntp_adjtime(struct timex *) {
__ensure(!"Not implemented");
__builtin_unreachable();
}
@@ -0,0 +1,27 @@
#ifndef _AR_H
#define _AR_H
#define ARMAG "!<arch>\n"
#define SARMAG 8
#define ARFMAG "`\n"
#ifdef __cplusplus
extern "C" {
#endif
struct ar_hdr {
char ar_name[16];
char ar_date[12];
char ar_uid[6];
char ar_gid[6];
char ar_mode[8];
char ar_size[10];
char ar_fmag[2];
};
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,32 @@
#ifndef MLIBC_GLIBC_ASSERT_H
#define MLIBC_GLIBC_ASSERT_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __MLIBC_ABI_ONLY
__attribute__ ((__noreturn__)) void __assert_fail_perror(int __errno, const char *__file, unsigned int __line,
const char *__function);
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __cplusplus
}
#endif
#endif /* MLIBC_GLIBC_ASSERT_H */
#ifdef NDEBUG
#undef assert_perror
#define assert_perror(ignore) ((void)0)
#else /* NDEBUG */
#undef assert_perror
#define assert_perror(errno) (!(errno) \
|| (__assert_fail_perror((errno), __FILE__, __LINE__, __func__), 0))
#endif /* NDEBUG */
@@ -0,0 +1,21 @@
#ifndef _GLIBC_NETINET_ICMP6_H
#define _GLIBC_NETINET_ICMP6_H
#ifdef __cplusplus
extern "C" {
#endif
#define ND_OPT_SOURCE_LINKADDR 1
#define ND_OPT_TARGET_LINKADDR 2
#define ND_OPT_PREFIX_INFORMATION 3
#define ND_OPT_REDIRECTED_HEADER 4
#define ND_OPT_MTU 5
#define ND_OPT_RTR_ADV_INTERVAL 7
#define ND_OPT_HOME_AGENT_INFO 8
#ifdef __cplusplus
}
#endif
#endif /* _GLIBC_NETINET_ICMP6_H */
@@ -0,0 +1,17 @@
#ifndef _GLIBC_MALLOC_H
#define _GLIBC_MALLOC_H
#ifdef __cplusplus
extern "C" {
#endif
#include <bits/size_t.h>
size_t malloc_usable_size(void *__ptr);
#ifdef __cplusplus
}
#endif
#endif /* _GLIBC_MALLOC_H */
@@ -0,0 +1,22 @@
#ifndef _GLIBC_SEARCH_H
#define _GLIBC_SEARCH_H
#ifdef __cplusplus
extern "C" {
#endif
#include <bits/search.h>
#ifndef __MLIBC_ABI_ONLY
int hcreate_r(size_t __num_entries, struct hsearch_data *__htab);
void hdestroy_r(struct hsearch_data *__htab);
int hsearch_r(ENTRY __item, ACTION __action, ENTRY **__ret, struct hsearch_data *__htab);
#endif
#ifdef __cplusplus
}
#endif
#endif /* _GLIBC_SEARCH_H */
@@ -0,0 +1,24 @@
#ifndef MLIBC_GLIBC_SIGNAL_H
#define MLIBC_GLIBC_SIGNAL_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __MLIBC_ABI_ONLY
int tgkill(int __tgid, int __tid, int __sig);
#if defined(_GNU_SOURCE)
typedef void (*sighandler_t)(int __signo);
#endif
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __cplusplus
}
#endif
#endif /* MLIBC_GLIBC_SIGNAL_H */
@@ -0,0 +1,20 @@
#ifndef MLIBC_GLIBC_STDLIB_H
#define MLIBC_GLIBC_STDLIB_H
#ifdef __cplusplus
extern "C" {
#endif
typedef int (*comparison_fn_t) (const void *__a, const void *__b);
#ifndef __MLIBC_ABI_ONLY
int rpmatch(const char *__resp);
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __cplusplus
}
#endif
#endif /* MLIBC_GLIBC_STDLIB_H */
@@ -0,0 +1,54 @@
#ifndef _ENDIAN_H
#define _ENDIAN_H
#include <byteswap.h>
#ifdef __GNUC__
# define BYTE_ORDER __BYTE_ORDER__
# define LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__
# define BIG_ENDIAN __ORDER_BIG_ENDIAN__
# define PDP_ENDIAN __ORDER_PDP_ENDIAN__
# define __BYTE_ORDER __BYTE_ORDER__
#ifndef __LITTLE_ENDIAN /* Linux kernel headers define this already */
# define __LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__
#endif
# define __BIG_ENDIAN __ORDER_BIG_ENDIAN__
# define __PDP_ENDIAN __ORDER_PDP_ENDIAN__
#else
# error "Unsupported compiler"
#endif
#if BYTE_ORDER == LITTLE_ENDIAN
# define htobe16(x) __bswap_16(x)
# define htole16(x) (uint16_t)(x)
# define be16toh(x) __bswap_16(x)
# define le16toh(x) (uint16_t)(x)
# define htobe32(x) __bswap_32(x)
# define htole32(x) (uint32_t)(x)
# define be32toh(x) __bswap_32(x)
# define le32toh(x) (uint32_t)(x)
# define htobe64(x) __bswap_64(x)
# define htole64(x) (uint64_t)(x)
# define be64toh(x) __bswap_64(x)
# define le64toh(x) (uint64_t)(x)
#else
# define htobe16(x) (uint16_t)(x)
# define htole16(x) __bswap_16(x)
# define be16toh(x) (uint16_t)(x)
# define le16toh(x) __bswap_16(x)
# define htobe32(x) (uint32_t)(x)
# define htole32(x) __bswap_32(x)
# define be32toh(x) (uint32_t)(x)
# define le32toh(x) __bswap_32(x)
# define htobe64(x) (uint64_t)(x)
# define htole64(x) __bswap_64(x)
# define be64toh(x) (uint64_t)(x)
# define le64toh(x) __bswap_64(x)
#endif
#endif /* _ENDIAN_H */
@@ -0,0 +1,33 @@
#ifndef _ERR_H
#define _ERR_H
#include <stdarg.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __MLIBC_ABI_ONLY
__attribute__((__format__(__printf__, 1, 2))) void warn(const char *__format, ...);
__attribute__((__format__(__printf__, 1, 0))) void vwarn(const char *__format, va_list __args);
__attribute__((__format__(__printf__, 1, 2))) void warnx(const char *__format, ...);
__attribute__((__format__(__printf__, 1, 0))) void vwarnx(const char *__format, va_list __args);
__attribute__((__noreturn__, __format__(__printf__, 2, 3)))
void err(int __errnum, const char *__format, ...);
__attribute__((__noreturn__, __format__(__printf__, 2, 0)))
void verr(int __errnum, const char *__format, va_list __args);
__attribute__((__noreturn__, , __format__(__printf__, 2, 3)))
void errx(int __errnum, const char *__format, ...);
__attribute__((__noreturn__, __format__(__printf__, 2, 0)))
void verrx(int __errnum, const char *__format, va_list __args);
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __cplusplus
}
#endif
#endif /* _ERR_H */
@@ -0,0 +1,27 @@
#ifndef _ERROR_H
#define _ERROR_H
#include <stdarg.h>
#ifdef __cplusplus
extern "C"{
#endif
#ifndef __MLIBC_ABI_ONLY
__attribute__((__format__(__printf__, 3, 4)))
void error(int __status, int __errnum, const char *__format, ...);
__attribute__((__format__(__printf__, 5, 6)))
void error_at_line(int __status, int __errnum, const char *__filename, unsigned int __linenum, const char *__format, ...);
extern unsigned int error_message_count;
extern int error_one_per_line;
extern void (*error_print_progname)(void);
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __cplusplus
}
#endif
#endif /* _ERROR_H */
@@ -0,0 +1,20 @@
#ifndef _EXECINFO_H
#define _EXECINFO_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __MLIBC_ABI_ONLY
int backtrace(void **__buffer, int __size);
char **backtrace_symbols(void *const *__buffer, int __size);
void backtrace_symbols_fd(void *const *__buffer, int __size, int __fd);
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,6 @@
#ifndef FEATURES_H
#define FEATURES_H
/* This header is a stub */
#endif
@@ -0,0 +1,37 @@
#ifndef _GETOPT_H
#define _GETOPT_H
#include <mlibc-config.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <bits/getopt.h>
#ifndef __MLIBC_ABI_ONLY
extern char **environ;
extern char *optarg;
extern int optind;
extern int opterr;
extern int optopt;
#if __MLIBC_BSD_OPTION
extern int optreset;
#endif /*__MLIBC_BSD_OPTION */
int getopt(int __argc, char *const __argv[], const char *__optstring);
int getopt_long(int __argc, char *const __argv[], const char *__optstring,
const struct option *__longopts, int *__longindex);
int getopt_long_only(int __argc, char *const __argv[], const char *__optstring,
const struct option *__longopts, int *__longindex);
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __cplusplus
}
#endif
#endif /* _GETOPT_H */
@@ -0,0 +1,30 @@
#ifndef _GSHADOW_H
#define _GSHADOW_H
#include <paths.h>
#include <bits/size_t.h>
#define GSHADOW _PATH_GSHADOW
struct sgrp {
char *sg_namp;
char *sg_passwd;
char **sg_adm;
char **sg_mem;
};
#ifndef __MLIBC_ABI_ONLY
#ifdef __cplusplus
extern "C" {
#endif
int getsgnam_r(const char *__name, struct sgrp *__result_buf, char *__buffer, size_t __len, struct sgrp **__result);
#ifdef __cplusplus
}
#endif
#endif /* !__MLIBC_ABI_ONLY */
#endif
@@ -0,0 +1,6 @@
#ifndef _MEMORY_H
#define _MEMORY_H
#include <string.h>
#endif
@@ -0,0 +1,20 @@
#ifndef MLIBC_GLIBC_SYSDEPS
#define MLIBC_GLIBC_SYSDEPS
namespace [[gnu::visibility("hidden")]] mlibc {
[[gnu::weak]] int sys_ioctl(int fd, unsigned long request, void *arg, int *result);
[[gnu::weak]] int sys_tgkill(int tgid, int tid, int sig);
[[gnu::weak]] int sys_personality(unsigned long persona, int *out);
[[gnu::weak]] int sys_ioperm(unsigned long int from, unsigned long int num, int turn_on);
[[gnu::weak]] int sys_iopl(int level);
#ifdef __riscv
[[gnu::weak]] int sys_riscv_flush_icache(void *start, void *end, unsigned long flags);
#endif
} // namespace mlibc
#endif // MLIBC_GLIBC_SYSDEPS
@@ -0,0 +1,46 @@
#ifndef _NET_ETHERNET_H
#define _NET_ETHERNET_H
#include <bits/ether_addr.h>
#include <stdint.h>
#include <mlibc-config.h>
#ifdef __cplusplus
extern "C" {
#endif
#if __MLIBC_LINUX_OPTION
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wvariadic-macros"
#pragma GCC diagnostic ignored "-Wpedantic"
# include <linux/if_ether.h>
#pragma GCC diagnostic pop
#endif /* __MLIBC_LINUX_OPTION */
#define ETHERTYPE_PUP 0x0200
#define ETHERTYPE_SPRITE 0x0500
#define ETHERTYPE_IP 0x0800
#define ETHERTYPE_ARP 0x0806
#define ETHERTYPE_REVARP 0x8035
#define ETHERTYPE_AT 0x809B
#define ETHERTYPE_AARP 0x80F3
#define ETHERTYPE_VLAN 0x8100
#define ETHERTYPE_IPX 0x8137
#define ETHERTYPE_IPV6 0x86dd
#define ETHERTYPE_LOOPBACK 0x9000
struct ether_header {
uint8_t ether_dhost[6];
uint8_t ether_shost[6];
uint16_t ether_type;
};
#define ETHER_ADDR_LEN 6
#define ETHERTYPE_IP 0x0800
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,23 @@
#ifndef _NET_IF_PPP_H
#define _NET_IF_PPP_H
#include <mlibc-config.h>
#if __MLIBC_LINUX_OPTION
#include <asm/ioctl.h>
#include <linux/ppp_defs.h>
#define PPPIOCGFLAGS _IOR('t', 90, int)
#define PPPIOCSFLAGS _IOW('t', 89, int)
#define PPPIOCGASYNCMAP _IOR('t', 88, int)
#define PPPIOCSASYNCMAP _IOW('t', 87, int)
#define PPPIOCGUNIT _IOR('t', 86, int)
#define PPPIOCSMRU _IOW('t', 82, int)
#define PPPIOCSMAXCID _IOW('t', 81, int)
#define PPPIOCGXASYNCMAP _IOR('t', 80, ext_accm)
#define PPPIOCSXASYNCMAP _IOW('t', 79, ext_accm)
#define PPPIOCGDEBUG _IOR('t', 65, int)
#define PPPIOCSDEBUG _IOW('t', 64, int)
#endif
#endif /* _NET_IF_PPP_H */
@@ -0,0 +1,35 @@
#ifndef _NET_ROUTE_H
#define _NET_ROUTE_H
#include <sys/socket.h>
#ifdef __cplusplus
extern "C" {
#endif
#define RTF_HOST 0x0004
#define RTF_REJECT 0x0200
struct rtentry {
unsigned long int rt_pad1;
struct sockaddr rt_dst;
struct sockaddr rt_gateway;
struct sockaddr rt_genmask;
unsigned short int rt_flags;
short int rt_pad2;
unsigned long int rt_pad3;
unsigned char rt_tos;
unsigned char rt_class;
short int rt_pad4[3];
short int rt_metric;
char *rt_dev;
unsigned long int rt_mtu;
unsigned long int rt_window;
unsigned short int rt_irtt;
};
#ifdef __cplusplus
}
#endif
#endif /* _NET_ROUTE_H */
@@ -0,0 +1,51 @@
#ifndef _NETAX25_AX25_H
#define _NETAX25_AX25_H
#include <mlibc-config.h>
#include <sys/socket.h>
#define AX25_VALUES_IPDEFMODE 0
#define AX25_VALUES_AXDEFMODE 1
#define AX25_VALUES_NETROM 2
#define AX25_VALUES_TEXT 3
#define AX25_VALUES_BACKOFF 4
#define AX25_VALUES_CONMODE 5
#define AX25_VALUES_WINDOW 6
#define AX25_VALUES_EWINDOW 7
#define AX25_VALUES_T1 8
#define AX25_VALUES_T2 9
#define AX25_VALUES_T3 10
#define AX25_VALUES_N2 11
#define AX25_VALUES_DIGI 12
#define AX25_VALUES_IDLE 13
#define AX25_VALUES_PACLEN 14
#define AX25_VALUES_IPMAXQUEUE 15
#define AX25_MAX_VALUES 20
typedef struct {
char ax25_call[7];
} ax25_address;
struct sockaddr_ax25 {
sa_family_t sax25_family;
ax25_address sax25_call;
int sax25_ndigis;
};
struct ax25_parms_struct {
ax25_address port_addr;
unsigned short values[AX25_MAX_VALUES];
};
#if __MLIBC_LINUX_OPTION
#include <abi-bits/ioctls.h>
#define SIOCAX25GETUID (SIOCPROTOPRIVATE)
#define SIOCAX25ADDUID (SIOCPROTOPRIVATE + 1)
#define SIOCAX25DELUID (SIOCPROTOPRIVATE + 2)
#define SIOCAX25NOUID (SIOCPROTOPRIVATE + 3)
#define SIOCAX25GETPARMS (SIOCPROTOPRIVATE + 5)
#define SIOCAX25SETPARMS (SIOCPROTOPRIVATE + 6)
#endif /* __MLIBC_LINUX_OPTION */
#endif /* _NETAX25_AX25_H */
@@ -0,0 +1,7 @@
#ifndef _NETINET_IN_SYSTM_H
#define _NETINET_IN_SYSTM_H
#endif /* _NETINET_IN_SYSTM_H */
@@ -0,0 +1,35 @@
#ifndef _NETIPX_IPX_H
#define _NETIPX_IPX_H
#include <mlibc-config.h>
#include <sys/socket.h>
#include <stdint.h>
typedef struct ipx_config_data {
unsigned char ipxcfg_auto_select_primary;
unsigned char ipxcfg_auto_create_interfaces;
} ipx_config_data;
#define IPX_TYPE 1
#define IPX_NODE_LEN 6
struct sockaddr_ipx {
sa_family_t sipx_family;
uint16_t sipx_port;
uint32_t sipx_network;
unsigned char sipx_node[IPX_NODE_LEN];
uint8_t sipx_type;
unsigned char sipx_zero;
};
#define SOL_IPX 256
#if __MLIBC_LINUX_OPTION
#include <abi-bits/ioctls.h>
#define SIOCAIPXITFCRT (SIOCPROTOPRIVATE)
#define SIOCAIPXPRISLT (SIOCPROTOPRIVATE + 1)
#define SIOCIPXCFGDATA (SIOCPROTOPRIVATE + 2)
#endif
#endif /* _NETIPX_IPX_H */
@@ -0,0 +1,27 @@
#ifndef _NETROM_NETROM_H
#define _NETROM_NETROM_H
#include <mlibc-config.h>
struct nr_parms_struct {
unsigned int quality;
unsigned int obs_count;
unsigned int ttl;
unsigned int timeout;
unsigned int ack_delay;
unsigned int busy_delay;
unsigned int tries;
unsigned int window;
unsigned int paclen;
};
#if __MLIBC_LINUX_OPTION
#include <abi-bits/ioctls.h>
#define SIOCNRGETPARMS (SIOCPROTOPRIVATE)
#define SIOCNRSETPARMS (SIOCPROTOPRIVATE + 1)
#define SIOCNRDECOBS (SIOCPROTOPRIVATE + 2)
#define SIOCNRRTCTL (SIOCPROTOPRIVATE + 3)
#endif
#endif /* _NETROM_NETROM_H */
@@ -0,0 +1,41 @@
/* This file is taken from musl */
/* Path to original: include/paths.h */
#ifndef _PATHS_H
#define _PATHS_H
#define _PATH_DEFPATH "/usr/local/bin:/bin:/usr/bin"
#define _PATH_STDPATH "/bin:/usr/bin:/sbin:/usr/sbin"
#define _PATH_BSHELL "/bin/sh"
#define _PATH_CONSOLE "/dev/console"
#define _PATH_DEVNULL "/dev/null"
#define _PATH_GSHADOW "/etc/gshadow"
#define _PATH_KLOG "/proc/kmsg"
#define _PATH_LASTLOG "/var/log/lastlog"
#define _PATH_MAILDIR "/var/mail"
#define _PATH_MAN "/usr/share/man"
#define _PATH_MNTTAB "/etc/fstab"
#define _PATH_MOUNTED "/etc/mtab"
#define _PATH_NOLOGIN "/etc/nologin"
#define _PATH_PRESERVE "/var/lib"
#define _PATH_SENDMAIL "/usr/sbin/sendmail"
#define _PATH_SHADOW "/etc/shadow"
#define _PATH_SHELLS "/etc/shells"
#define _PATH_TTY "/dev/tty"
#define _PATH_UTMP "/var/run/utmp"
#define _PATH_VI "/usr/bin/vi"
#define _PATH_WTMP "/var/log/wtmp"
#define _PATH_DEV "/dev/"
#define _PATH_TMP "/tmp/"
#define _PATH_VARDB "/var/lib/misc/"
#define _PATH_VARRUN "/var/run/"
#define _PATH_VARTMP "/var/tmp/"
#ifdef _GNU_SOURCE
#define _PATH_UTMPX _PATH_UTMP
#define _PATH_WTMPX _PATH_WTMP
#endif
#endif /* _PATHS_H */
@@ -0,0 +1,41 @@
#ifndef _PRINTF_H
#define _PRINTF_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#include <stdarg.h>
#ifndef __MLIBC_ABI_ONLY
/* This seems to be a glibc thing, so constants are from glibc */
size_t parse_printf_format(const char * __restrict __format, size_t __size, int * __restrict __argtypes);
#endif /* !__MLIBC_ABI_ONLY */
enum {
PA_INT,
PA_CHAR,
PA_WCHAR,
PA_STRING,
PA_WSTRING,
PA_POINTER,
PA_FLOAT,
PA_DOUBLE,
PA_LAST
};
#define PA_FLAG_MASK 0xff00
#define PA_FLAG_LONG_LONG (1 << 8)
#define PA_FLAG_LONG_DOUBLE PA_FLAG_LONG_LONG
#define PA_FLAG_LONG (1 << 9)
#define PA_FLAG_SHORT (1 << 10)
#define PA_FLAG_PTR (1 << 11)
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,78 @@
#ifndef _RESOLV_H
#define _RESOLV_H
#include <netinet/in.h>
#define RES_INIT 0x00000001
#define RES_DEBUG 0x00000002
#define RES_USEVC 0x00000008
#define RES_IGNTC 0x00000020
#define RES_RECURSE 0x00000040
#define RES_DEFNAMES 0x00000080
#define RES_STAYOPEN 0x00000100
#define RES_DNSRCH 0x00000200
#define MAXNS 3
#define MAXDNSRCH 6
#define _PATH_RESCONF "/etc/resolv.conf"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __MLIBC_ABI_ONLY
int dn_expand(const unsigned char *__msg, const unsigned char *__eomorig,
const unsigned char *__comp_dn, char *__exp_dn, int __size);
int res_query(const char *__dname, int __class, int __type,
unsigned char *__answer, int __anslen);
int res_init(void);
int dn_comp(const char *, unsigned char *, int, unsigned char **, unsigned char **);
#endif /* !__MLIBC_ABI_ONLY */
/* From musl: Unused; purely for broken apps
* To avoid an massive struct, only add the items requested. */
typedef struct __res_state {
int retrans;
int retry;
unsigned long options;
int nscount;
struct sockaddr_in nsaddr_list[MAXNS];
char *dnsrch[MAXDNSRCH + 1];
char defdname[256];
unsigned ndots:4;
unsigned nsort:4;
union {
char pad[52];
struct {
uint16_t nscount;
uint16_t nsmap[MAXNS];
int nssocks[MAXNS];
uint16_t nscount6;
uint16_t nsinit;
struct sockaddr_in6 *nsaddrs[MAXNS];
unsigned int _initstamp[2];
} _ext;
} _u;
} *res_state;
#ifndef __MLIBC_ABI_ONLY
struct __res_state *__res_state(void);
#define _res (*__res_state())
int res_ninit(res_state __state);
void res_nclose(res_state __state);
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __cplusplus
}
#endif
#endif /* _RESOLV_H */
@@ -0,0 +1,43 @@
#ifndef _SHADOW_H
#define _SHADOW_H
#include <stdint.h>
#include <stdio.h>
#include <paths.h>
#ifdef __cplusplus
extern "C" {
#endif
struct spwd {
char *sp_namp;
char *sp_pwdp;
long sp_lstchg;
long sp_min;
long sp_max;
long sp_warn;
long sp_inact;
long sp_expire;
unsigned long sp_flag;
};
#define SHADOW _PATH_SHADOW
#ifndef __MLIBC_ABI_ONLY
int putspent(const struct spwd *__sp, FILE *__f);
int lckpwdf(void);
int ulckpwdf(void);
struct spwd *getspnam(const char *__name);
int getspnam_r(const char *__name, struct spwd *__sp, char *__buf, size_t __size, struct spwd **__res);
struct spwd *fgetspent(FILE *__f);
void endspent(void);
struct spwd *sgetspent(const char *__s);
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,42 @@
#ifndef _STDIO_EXT_H
#define _STDIO_EXT_H
#include <stddef.h>
#include <stdio.h>
#define FSETLOCKING_INTERNAL 1
#define FSETLOCKING_BYCALLER 2
#define FSETLOCKING_QUERY 3
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __MLIBC_ABI_ONLY
size_t __fbufsize(FILE *__stream);
size_t __fpending(FILE *__stream);
int __flbf(FILE *__stream);
int __freadable(FILE *__stream);
int __fwritable(FILE *__stream);
int __freading(FILE *__stream);
int __fwriting(FILE *__stream);
int __fsetlocking(FILE *__stream, int __type);
void __fpurge(FILE *__stream);
void _flushlbf(void);
/* The following functions are defined by musl. */
size_t __freadahead(FILE *__stream);
const char *__freadptr(FILE *__stream, size_t *__size);
void __freadptrinc(FILE *, size_t);
void __fseterr(FILE *__stream);
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __cplusplus
}
#endif
#endif /* _STDIO_EXT_H */
@@ -0,0 +1,16 @@
#ifndef _SYS_CACHECTL_H
#define _SYS_CACHECTL_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __riscv
int __riscv_flush_icache(void *, void *, unsigned long);
#endif
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,8 @@
#ifndef _SYS_DIR_H
#define _SYS_DIR_H
#include <dirent.h>
#define direct dirent
#endif
@@ -0,0 +1 @@
#include <errno.h>
@@ -0,0 +1,108 @@
#ifndef _SYS_IO_H
#define _SYS_IO_H
#include <bits/inline-definition.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __MLIBC_ABI_ONLY
int ioperm(unsigned long int __from, unsigned long int __num, int __turn_on);
__attribute__((deprecated)) int iopl(int __level);
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __x86_64__
__MLIBC_INLINE_DEFINITION unsigned char inb(unsigned short int __port) {
unsigned char __value;
__asm__ __volatile__ ("inb %w1,%0":"=a" (__value):"Nd" (__port));
return __value;
}
__MLIBC_INLINE_DEFINITION unsigned char inb_p(unsigned short int __port) {
unsigned char __value;
__asm__ __volatile__ ("inb %w1,%0\noutb %%al,$0x80":"=a" (__value):"Nd" (__port));
return __value;
}
__MLIBC_INLINE_DEFINITION unsigned short int inw(unsigned short int __port) {
unsigned short __value;
__asm__ __volatile__ ("inw %w1,%0":"=a" (__value):"Nd" (__port));
return __value;
}
__MLIBC_INLINE_DEFINITION unsigned short int inw_p(unsigned short int __port) {
unsigned short int __value;
__asm__ __volatile__ ("inw %w1,%0\noutb %%al,$0x80":"=a" (__value):"Nd" (__port));
return __value;
}
__MLIBC_INLINE_DEFINITION unsigned int inl(unsigned short int __port) {
unsigned int __value;
__asm__ __volatile__ ("inl %w1,%0":"=a" (__value):"Nd" (__port));
return __value;
}
__MLIBC_INLINE_DEFINITION unsigned int inl_p(unsigned short int __port) {
unsigned int __value;
__asm__ __volatile__ ("inl %w1,%0\noutb %%al,$0x80":"=a" (__value):"Nd" (__port));
return __value;
}
__MLIBC_INLINE_DEFINITION void outb(unsigned char value, unsigned short int __port) {
__asm__ __volatile__ ("outb %b0,%w1": :"a" (value), "Nd" (__port));
}
__MLIBC_INLINE_DEFINITION void outb_p(unsigned char __value, unsigned short int __port) {
__asm__ __volatile__ ("outb %b0,%w1\noutb %%al,$0x80": :"a" (__value), "Nd" (__port));
}
__MLIBC_INLINE_DEFINITION void outw(unsigned short int __value, unsigned short int __port) {
__asm__ __volatile__ ("outw %w0,%w1": :"a" (__value), "Nd" (__port));
}
__MLIBC_INLINE_DEFINITION void outw_p(unsigned short int __value, unsigned short int __port) {
__asm__ __volatile__ ("outw %w0,%w1\noutb %%al,$0x80": :"a" (__value), "Nd" (__port));
}
__MLIBC_INLINE_DEFINITION void outl(unsigned int __value, unsigned short int __port) {
__asm__ __volatile__ ("outl %0,%w1": :"a" (__value), "Nd" (__port));
}
__MLIBC_INLINE_DEFINITION void outl_p(unsigned int __value, unsigned short int __port) {
__asm__ __volatile__ ("outl %0,%w1\noutb %%al,$0x80": :"a" (__value), "Nd" (__port));
}
__MLIBC_INLINE_DEFINITION void insb(unsigned short int __port, void *__addr, unsigned long int __count) {
__asm__ __volatile__ ("cld ; rep ; insb":"=D" (__addr), "=c" (__count) :"d" (__port), "0" (__addr), "1" (__count));
}
__MLIBC_INLINE_DEFINITION void insw(unsigned short int __port, void *__addr, unsigned long int __count) {
__asm__ __volatile__ ("cld ; rep ; insw":"=D" (__addr), "=c" (__count) :"d" (__port), "0" (__addr), "1" (__count));
}
__MLIBC_INLINE_DEFINITION void insl(unsigned short int __port, void *__addr, unsigned long int __count) {
__asm__ __volatile__ ("cld ; rep ; insl":"=D" (__addr), "=c" (__count) :"d" (__port), "0" (__addr), "1" (__count));
}
__MLIBC_INLINE_DEFINITION void outsb(unsigned short int __port, const void *__addr, unsigned long int __count) {
__asm__ __volatile__ ("cld ; rep ; outsb":"=S" (__addr), "=c" (__count) :"d" (__port), "0" (__addr), "1" (__count));
}
__MLIBC_INLINE_DEFINITION void outsw(unsigned short int __port, const void *__addr, unsigned long int __count) {
__asm__ __volatile__ ("cld ; rep ; outsw":"=S" (__addr), "=c" (__count) :"d" (__port), "0" (__addr), "1" (__count));
}
__MLIBC_INLINE_DEFINITION void outsl(unsigned short int __port, const void *__addr, unsigned long int __count) {
__asm__ __volatile__ ("cld ; rep ; outsl":"=S" (__addr), "=c" (__count) :"d" (__port), "0" (__addr), "1" (__count));
}
#endif
#ifdef __cplusplus
}
#endif
#endif /* _SYS_IO_H */
@@ -0,0 +1,48 @@
#ifndef _SYS_IOCTL_H
#define _SYS_IOCTL_H
#include <mlibc-config.h>
#include <abi-bits/ioctls.h>
/* On Linux, sys/ioctl.h includes the termios ioctls. */
#if __MLIBC_LINUX_OPTION
# include <asm/ioctls.h>
# include <bits/winsize.h>
# include <sys/ttydefaults.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __MLIBC_ABI_ONLY
int ioctl(int __fd, unsigned long __request, ...);
#endif /* !__MLIBC_ABI_ONLY */
#define TIOCMGET 0x5415
#define TIOCMBIS 0x5416
#define TIOCMBIC 0x5417
#define FIONREAD 0x541B
#define FIONBIO 0x5421
#define FIONCLEX 0x5450
#define FIOCLEX 0x5451
#define SIOCGIFNAME 0x8910
#define SIOCGIFCONF 0x8912
#define SIOCGIFFLAGS 0x8913
#define SIOCSIFFLAGS 0x8914
#define SIOCGIFMTU 0x8921
#define SIOCSIFMTU 0x8922
#define SIOCGIFINDEX 0x8933
#define SIOCPROTOPRIVATE 0x89E0
#define SIOCDEVPRIVATE 0x89F0
#ifdef __cplusplus
}
#endif
#endif /* _SYS_IOCTL_H */
@@ -0,0 +1,17 @@
#ifndef _SYS_KD_H
#define _SYS_KD_H
/* Make sure the <linux/types.h> header is not loaded. */
#ifndef _LINUX_TYPES_H
# define _LINUX_TYPES_H 1
# define __undef_LINUX_TYPES_H
#endif
#include <linux/kd.h>
#ifdef __undef_LINUX_TYPES_H
# undef _LINUX_TYPES_H
# undef __undef_LINUX_TYPES_H
#endif
#endif /* _SYS_KD_H */
@@ -0,0 +1,102 @@
#ifndef _SYS_MTIO_H
#define _SYS_MTIO_H
#include <mlibc-config.h>
#include <sys/ioctl.h>
#ifdef __cplusplus
extern "C" {
#endif
struct mtop {
short int mt_op;
int mt_count;
};
struct mtget {
long int mt_type;
long int mt_resid;
long int mt_dsreg;
long int mt_gstat;
long int mt_erreg;
int mt_fileno;
int mt_blkno;
};
struct mtpos {
long int mt_blkno;
};
struct mtconfiginfo {
long int mt_type;
long int ifc_type;
unsigned short int irqnr;
unsigned short int dmanr;
unsigned short int port;
unsigned long int debug;
unsigned have_dens:1;
unsigned have_bsf:1;
unsigned have_fsr:1;
unsigned have_bsr:1;
unsigned have_eod:1;
unsigned have_seek:1;
unsigned have_tell:1;
unsigned have_ras1:1;
unsigned have_ras2:1;
unsigned have_ras3:1;
unsigned have_qfa:1;
unsigned pad1:5;
char reserved[10];
};
#define MTRESET 0
#define MTFSF 1
#define MTBSF 2
#define MTFSR 3
#define MTBSR 4
#define MTWEOF 5
#define MTREW 6
#define MTOFFL 7
#define MTNOP 8
#define MTRETEN 9
#define MTBSFM 10
#define MTFSFM 11
#define MTEOM 12
#define MTERASE 13
#define MTRAS1 14
#define MTRAS2 15
#define MTRAS3 16
#define MTSETBLK 20
#define MTSETDENSITY 21
#define MTSEEK 22
#define MTTELL 23
#define MTSETDRVBUFFER 24
#define MTFSS 25
#define MTBSS 26
#define MTWSM 27
#define MTLOCK 28
#define MTUNLOCK 29
#define MTLOAD 30
#define MTUNLOAD 31
#define MTCOMPRESSION 32
#define MTSETPART 33
#define MTMKPART 34
#define GMT_WR_PROT(x) ((x) & 0x04000000)
#if __MLIBC_LINUX_OPTION
#define MTIOCTOP _IOR('m', 1, struct mtop)
#define MTIOCGET _IOR('m', 2, struct mtget)
#define MTIOCPOS _IOR('m', 3, struct mtpos)
#define MTIOCGETCONFIG _IOR('m', 4, struct mtconfiginfo)
#define MTIOCSETCONFIG _IOR('m', 5, struct mtconfiginfo)
#endif
#ifdef __cplusplus
}
#endif
#endif /* _SYS_MTIO_H */
@@ -0,0 +1,58 @@
#ifndef _SYS_PERSONALITY_H
#define _SYS_PERSONALITY_H
#ifdef __cplusplus
extern "C" {
#endif
enum {
UNAME26 = 0x0020000,
ADDR_NO_RANDOMIZE = 0x0040000,
FDPIC_FUNCPTRS = 0x0080000,
MMAP_PAGE_ZERO = 0x0100000,
ADDR_COMPAT_LAYOUT = 0x0200000,
READ_IMPLIES_EXEC = 0x0400000,
ADDR_LIMIT_32BIT = 0x0800000,
SHORT_INODE = 0x1000000,
WHOLE_SECONDS = 0x2000000,
STICKY_TIMEOUTS = 0x4000000,
ADDR_LIMIT_3GB = 0x8000000
};
enum {
PER_LINUX = 0x0000,
PER_LINUX_32BIT = 0x0000 | ADDR_LIMIT_32BIT,
PER_LINUX_FDPIC = 0x0000 | FDPIC_FUNCPTRS,
PER_SVR4 = 0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
PER_SVR3 = 0x0002 | STICKY_TIMEOUTS | SHORT_INODE,
PER_SCOSVR3 = 0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS | SHORT_INODE,
PER_OSR5 = 0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS,
PER_WYSEV386 = 0x0004 | STICKY_TIMEOUTS | SHORT_INODE,
PER_ISCR4 = 0x0005 | STICKY_TIMEOUTS,
PER_BSD = 0x0006,
PER_SUNOS = 0x0006 | STICKY_TIMEOUTS,
PER_XENIX = 0x0007 | STICKY_TIMEOUTS | SHORT_INODE,
PER_LINUX32 = 0x0008,
PER_LINUX32_3GB = 0x0008 | ADDR_LIMIT_3GB,
PER_IRIX32 = 0x0009 | STICKY_TIMEOUTS,
PER_IRIXN32 = 0x000a | STICKY_TIMEOUTS,
PER_IRIX64 = 0x000b | STICKY_TIMEOUTS,
PER_RISCOS = 0x000c,
PER_SOLARIS = 0x000d | STICKY_TIMEOUTS,
PER_UW7 = 0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
PER_OSF4 = 0x000f,
PER_HPUX = 0x0010,
PER_MASK = 0x00ff
};
#ifndef __MLIBC_ABI_ONLY
int personality(unsigned long __persona);
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __cplusplus
}
#endif
#endif /* _SYS_PERSONALITY_H */
@@ -0,0 +1,75 @@
#ifndef _SYS_PROCFS_H
#define _SYS_PROCFS_H
#include <sys/user.h>
#include <sys/time.h>
#include <abi-bits/pid_t.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef unsigned long elf_greg_t;
#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof (elf_greg_t))
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
typedef struct user_fpregs_struct elf_fpregset_t;
typedef elf_gregset_t prgregset_t;
typedef struct user_fpregs_struct prfpregset_t;
#define ELF_PRARGSZ 80
struct elf_siginfo {
int si_signo;
int si_code;
int si_errno;
};
struct elf_prstatus {
struct elf_siginfo pr_info;
short int pr_cursig;
unsigned long int pr_sigpend;
unsigned long int pr_sighold;
pid_t pr_pid;
pid_t pr_ppid;
pid_t pr_pgrp;
pid_t pr_sid;
struct timeval pr_utime;
struct timeval pr_stime;
struct timeval pr_cutime;
struct timeval pr_cstime;
elf_gregset_t pr_reg;
int pr_fpvalid;
};
struct elf_prpsinfo {
char pr_state;
char pr_sname;
char pr_zomb;
char pr_nice;
unsigned long pr_flag;
#if __INTPTR_WIDTH__ == 32
unsigned short int pr_uid;
unsigned short int pr_gid;
#else
unsigned int pr_uid;
unsigned int pr_gid;
#endif
int pr_pid;
int pr_ppid;
int pr_pgrp;
int pr_sid;
char pr_fname[16];
char pr_psargs[ELF_PRARGSZ];
};
typedef pid_t lwpid_t;
typedef void *psaddr_t;
typedef struct elf_prstatus prstatus_t;
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,36 @@
#ifndef _SYS_REG_H
#define _SYS_REG_H
#ifdef __x86_64__
#define R15 0
#define R14 1
#define R13 2
#define R12 3
#define RBP 4
#define RBX 5
#define R11 6
#define R10 7
#define R9 8
#define R8 9
#define RAX 10
#define RCX 11
#define RDX 12
#define RSI 13
#define RDI 14
#define ORIG_RAX 15
#define RIP 16
#define CS 17
#define EFLAGS 18
#define RSP 19
#define SS 20
#define FS_BASE 21
#define GS_BASE 22
#define DS 23
#define ES 24
#define FS 25
#define GS 26
#elif !(defined(__i386__) || defined(__riscv) || defined(__aarch64__) || defined(__m68k__) || defined(__loongarch64))
#error "Missing architecture specific code."
#endif
#endif
@@ -0,0 +1 @@
#include <signal.h>
@@ -0,0 +1,14 @@
#ifndef _SYS_TIMEB_H
#define _SYS_TIMEB_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* _SYS_TIMEB_H */
@@ -0,0 +1,80 @@
#ifndef _SYS_TIMEX_H
#define _SYS_TIMEX_H
#ifdef __cplusplus
extern "C" {
#endif
#include <abi-bits/clockid_t.h>
#include <bits/posix/timeval.h>
struct timex {
int modes;
long offset;
long freq;
long maxerror;
long esterror;
int status;
long constant;
long precision;
long tolerance;
struct timeval time;
long tick;
long ppsfreq;
long jitter;
int shift;
long stabil;
long jitcnt;
long calcnt;
long errcnt;
long stbcnt;
int tai;
int __padding[11];
};
#define ADJ_OFFSET 0x0001
#define ADJ_FREQUENCY 0x0002
#define ADJ_MAXERROR 0x0004
#define ADJ_ESTERROR 0x0008
#define ADJ_STATUS 0x0010
#define ADJ_TIMECONST 0x0020
#define ADJ_TAI 0x0080
#define ADJ_SETOFFSET 0x0100
#define ADJ_MICRO 0x1000
#define ADJ_NANO 0x2000
#define ADJ_TICK 0x4000
#define ADJ_OFFSET_SINGLESHOT 0x8001
#define ADJ_OFFSET_SS_READ 0xa001
#define STA_PLL 0x0001
#define STA_PPSFREQ 0x0002
#define STA_PPSTIME 0x0004
#define STA_FLL 0x0008
#define STA_INS 0x0010
#define STA_DEL 0x0020
#define STA_UNSYNC 0x0040
#define STA_FREQHOLD 0x0080
#define STA_PPSSIGNAL 0x0100
#define STA_PPSJITTER 0x0200
#define STA_PPSWANDER 0x0400
#define STA_PPSERROR 0x0800
#define STA_CLOCKERR 0x1000
#define STA_NANO 0x2000
#define STA_MODE 0x4000
#define STA_CLK 0x8000
#define TIME_ERROR 5
#ifndef __MLIBC_ABI_ONLY
int adjtimex(struct timex *__buf);
int clock_adjtime(clockid_t __clockid, struct timex *__buf);
int ntp_adjtime(struct timex *__buf);
#endif /* !__MLIBC_ABI_ONLY */
#ifdef __cplusplus
}
#endif
#endif /* _SYS_TIMEX_H */
@@ -0,0 +1,14 @@
#ifndef _SYS_UCONTEXT_H
#define _SYS_UCONTEXT_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* _SYS_UCONTEXT_H */
@@ -0,0 +1,51 @@
#ifndef _SYS_USER_H
#define _SYS_USER_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* TODO: This assumes x86-64. */
struct user_fpregs_struct {
uint16_t cwd, swd, ftw, fop;
uint64_t rip, rdp;
uint32_t mxcsr, mxcr_mask;
uint32_t st_space[32], xmm_space[64], padding[24];
};
struct user_regs_struct {
unsigned long r15, r14, r13, r12, rbp, rbx, r11, r10, r9, r8;
unsigned long rax, rcx, rdx, rsi, rdi, orig_rax, rip;
unsigned long cs, eflags, rsp, ss, fs_base, gs_base, ds, es, fs, gs;
};
struct user {
struct user_regs_struct regs;
int u_fpvalid;
struct user_fpregs_struct i387;
unsigned long u_tsize;
unsigned long u_dsize;
unsigned long u_ssize;
unsigned long start_code;
unsigned long start_stack;
long signal;
int reserved;
struct user_regs_struct *u_ar0;
struct user_fpregs_struct *u_fpstate;
unsigned long magic;
char u_comm[32];
unsigned long u_debugreg[8];
};
#ifdef __cplusplus
}
#endif
#define PAGE_SHIFT 12
#define PAGE_SIZE (1UL << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE - 1))
#endif
@@ -0,0 +1,24 @@
#ifndef _SYSEXITS_H
#define _SYSEXITS_H
#define EX_OK 0
#define EX_USAGE 64
#define EX_DATAERR 65
#define EX_NOINPUT 66
#define EX_NOUSER 67
#define EX_NOHOST 68
#define EX_UNAVAILABLE 69
#define EX_SOFTWARE 70
#define EX_OSERR 71
#define EX_OSFILE 72
#define EX_CANTCREAT 73
#define EX_IOERR 74
#define EX_TEMPFAIL 75
#define EX_PROTOCOL 76
#define EX_NOPERM 77
#define EX_CONFIG 78
#define EX__BASE 64
#define EX__MAX 78
#endif /* _SYSEXITS_H */
@@ -0,0 +1,96 @@
if not glibc_option
subdir_done()
endif
libc_sources += files(
'generic/getopt.cpp',
'generic/stdio_ext.cpp',
'generic/sys-ioctl.cpp',
'generic/err.cpp',
'generic/error.cpp',
'generic/resolv.cpp',
'generic/shadow.cpp',
'generic/printf.cpp',
'generic/glibc-signal.cpp',
'generic/execinfo.cpp',
'generic/string.cpp',
'generic/personality.cpp',
'generic/gshadow.cpp',
'generic/sys-timex.cpp',
'generic/glibc-assert.cpp',
'generic/malloc.cpp',
'generic/sys-cachectl.cpp',
'generic/sys-io.cpp',
'generic/search.cpp',
'generic/stdlib.cpp'
)
if not no_headers
install_headers(
'include/getopt.h',
'include/stdio_ext.h',
'include/err.h',
'include/error.h',
'include/paths.h',
'include/sysexits.h',
'include/resolv.h',
'include/endian.h',
'include/ar.h',
'include/shadow.h',
'include/memory.h',
'include/printf.h',
'include/gshadow.h',
'include/execinfo.h',
'include/features.h'
)
install_headers(
'include/sys/cachectl.h',
'include/sys/dir.h',
'include/sys/ioctl.h',
'include/sys/user.h',
'include/sys/procfs.h',
'include/sys/reg.h',
'include/sys/errno.h',
'include/sys/signal.h',
'include/sys/ucontext.h',
'include/sys/personality.h',
'include/sys/timeb.h',
'include/sys/mtio.h',
'include/sys/endian.h',
'include/sys/timex.h',
'include/sys/kd.h',
'include/sys/io.h',
subdir: 'sys'
)
install_headers(
'include/net/ethernet.h',
'include/net/route.h',
'include/net/if_ppp.h',
subdir: 'net'
)
install_headers(
'include/netax25/ax25.h',
subdir: 'netax25'
)
install_headers(
'include/netipx/ipx.h',
subdir: 'netipx'
)
install_headers(
'include/netrom/netrom.h',
subdir: 'netrom'
)
install_headers(
'include/netinet/in_systm.h',
subdir: 'netinet'
)
install_headers(
'include/bits/glibc/glibc_signal.h',
'include/bits/glibc/glibc_assert.h',
'include/bits/glibc/glibc_malloc.h',
'include/bits/glibc/glibc_icmp6.h',
'include/bits/glibc/glibc_search.h',
'include/bits/glibc/glibc_stdlib.h',
subdir: 'bits/glibc'
)
endif