mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-05-25 22:14:34 +00:00
refactor(userspace): build using cmake
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
This commit is contained in:
parent
40f46312f8
commit
201ace7eec
File diff suppressed because it is too large
Load Diff
@ -15,8 +15,8 @@
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_API_SYSCALLS_LIST_H__
|
||||
#define __FENNIX_API_SYSCALLS_LIST_H__
|
||||
#ifndef __FENNIX_API_SYSTEM_CALLS_LIST_H__
|
||||
#define __FENNIX_API_SYSTEM_CALLS_LIST_H__
|
||||
|
||||
#pragma region Syscall Wrappers
|
||||
|
||||
@ -1809,4 +1809,4 @@ typedef enum
|
||||
/** @copydoc SYS_UNAME */
|
||||
#define call_uname(buf) syscall1(SYS_UNAME, (scarg)buf)
|
||||
|
||||
#endif // !__FENNIX_API_SYSCALLS_LIST_H__
|
||||
#endif // !__FENNIX_API_SYSTEM_CALLS_LIST_H__
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -15,8 +15,8 @@
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_API_SYSCALLS_LIST_H__
|
||||
#define __FENNIX_API_SYSCALLS_LIST_H__
|
||||
#ifndef __FENNIX_API_SYSTEM_CALLS_LIST_H__
|
||||
#define __FENNIX_API_SYSTEM_CALLS_LIST_H__
|
||||
|
||||
#pragma region Syscall Wrappers
|
||||
|
||||
@ -1809,4 +1809,4 @@ typedef enum
|
||||
/** @copydoc SYS_UNAME */
|
||||
#define call_uname(buf) syscall1(SYS_UNAME, (scarg)buf)
|
||||
|
||||
#endif // !__FENNIX_API_SYSCALLS_LIST_H__
|
||||
#endif // !__FENNIX_API_SYSTEM_CALLS_LIST_H__
|
||||
|
@ -20,4 +20,18 @@
|
||||
|
||||
#include <interface/errno.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
int *__errno_location(void) __attribute__((const));
|
||||
char *strerror(int errnum);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#define errno (*__errno_location())
|
||||
|
||||
#endif // !__FENNIX_KERNEL_STD_ERRNO_H__
|
||||
|
5
Userspace/.vscode/settings.json
vendored
5
Userspace/.vscode/settings.json
vendored
@ -1,5 +1,6 @@
|
||||
{
|
||||
"git.openRepositoryInParentFolders": "always",
|
||||
"git.alwaysSignOff": true,
|
||||
"git.defaultBranchName": "master"
|
||||
}
|
||||
"git.defaultBranchName": "master",
|
||||
"cmake.ignoreCMakeListsMissing": true
|
||||
}
|
||||
|
18
Userspace/Fennix C Library.code-workspace
Normal file
18
Userspace/Fennix C Library.code-workspace
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "./libc"
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
"terminal.integrated.cwd": "../../",
|
||||
"debug.allowBreakpointsEverywhere": true,
|
||||
"git.alwaysSignOff": true,
|
||||
"git.defaultBranchName": "master",
|
||||
"git.openRepositoryInParentFolders": "always",
|
||||
"C_Cpp.autoAddFileAssociations": false,
|
||||
"conventionalCommits.scopes": [
|
||||
"userspace/libc"
|
||||
]
|
||||
}
|
||||
}
|
18
Userspace/Fennix Core Utilities.code-workspace
Normal file
18
Userspace/Fennix Core Utilities.code-workspace
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "./coreutils"
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
"terminal.integrated.cwd": "../../",
|
||||
"debug.allowBreakpointsEverywhere": true,
|
||||
"git.alwaysSignOff": true,
|
||||
"git.defaultBranchName": "master",
|
||||
"git.openRepositoryInParentFolders": "always",
|
||||
"C_Cpp.autoAddFileAssociations": false,
|
||||
"conventionalCommits.scopes": [
|
||||
"userspace/coreutils"
|
||||
]
|
||||
}
|
||||
}
|
@ -35,7 +35,7 @@ create_out:
|
||||
mkdir -p out/usr/share/doc
|
||||
mkdir -p out/usr/share/info
|
||||
mkdir -p out/usr/include
|
||||
cp $(WORKSPACE_DIR)/../Kernel/include/interface/* $(WORKSPACE_DIR)/out/include/fennix/
|
||||
cp $(WORKSPACE_DIR)/../Kernel/include/interface/* $(WORKSPACE_DIR)/out/include/fennix/
|
||||
|
||||
build_coreutils:
|
||||
mkdir -p cache/coreutils
|
||||
@ -49,8 +49,23 @@ build_coreutils:
|
||||
make -j$(shell nproc) && \
|
||||
make install
|
||||
|
||||
build_libc:
|
||||
cp -f $(WORKSPACE_DIR)/../Kernel/include/interface/errno.h $(WORKSPACE_DIR)/libc/abis/fennix/generic/bits/errno.h
|
||||
cp -f $(WORKSPACE_DIR)/../Kernel/include/interface/syscalls.h $(WORKSPACE_DIR)/libc/abis/fennix/generic/bits/syscalls.h
|
||||
mkdir -p cache/libc
|
||||
cd cache/libc && \
|
||||
cmake $(WORKSPACE_DIR)/libc \
|
||||
-DCMAKE_INSTALL_PREFIX:PATH=$(WORKSPACE_DIR)/out \
|
||||
-DCMAKE_SYSROOT=$(WORKSPACE_DIR)/out \
|
||||
-DCMAKE_C_STANDARD_INCLUDE_DIRECTORIES=$(WORKSPACE_DIR)/out/include \
|
||||
-DTARGET_OS=fennix \
|
||||
-DTARGET_ARCH=$(OSARCH) \
|
||||
&& \
|
||||
make -j$(shell nproc) && \
|
||||
make install
|
||||
|
||||
build: create_out
|
||||
make -C libc build
|
||||
$(MAKE) build_libc
|
||||
make -C libs build
|
||||
$(MAKE) build_coreutils
|
||||
make -C apps build
|
||||
@ -62,6 +77,5 @@ clean:
|
||||
rm -rf out cache
|
||||
mkdir -p cache
|
||||
touch cache/.gitkeep
|
||||
make -C libc clean
|
||||
make -C libs clean
|
||||
make -C apps clean
|
||||
|
1
Userspace/libc/.gitignore
vendored
Normal file
1
Userspace/libc/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
build
|
27
Userspace/libc/.vscode/c_boilerplates.code-snippets
vendored
Normal file
27
Userspace/libc/.vscode/c_boilerplates.code-snippets
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"C Library License": {
|
||||
"isFileTemplate": true,
|
||||
"prefix": [
|
||||
"license",
|
||||
],
|
||||
"body": [
|
||||
"/*",
|
||||
"\tThis file is part of Fennix C Library.",
|
||||
"",
|
||||
"\tFennix C Library is free software: you can redistribute it and/or",
|
||||
"\tmodify it under the terms of the GNU General Public License as",
|
||||
"\tpublished by the Free Software Foundation, either version 3 of",
|
||||
"\tthe License, or (at your option) any later version.",
|
||||
"",
|
||||
"\tFennix C Library is distributed in the hope that it will be useful,",
|
||||
"\tbut WITHOUT ANY WARRANTY; without even the implied warranty of",
|
||||
"\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
|
||||
"\tGNU General Public License for more details.",
|
||||
"",
|
||||
"\tYou should have received a copy of the GNU General Public License",
|
||||
"\talong with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.",
|
||||
"*/"
|
||||
],
|
||||
"description": "Create libc license."
|
||||
}
|
||||
}
|
104
Userspace/libc/CMakeLists.txt
Normal file
104
Userspace/libc/CMakeLists.txt
Normal file
@ -0,0 +1,104 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
||||
project(FennixCLibrary VERSION 1.0.0)
|
||||
|
||||
if(NOT DEFINED ENV{WORKSPACE_DIR})
|
||||
set(STANDALONE_BUILD ON)
|
||||
message(STATUS "Compiling standalone")
|
||||
set(CMAKE_INSTALL_PREFIX "/usr")
|
||||
else()
|
||||
set(STANDALONE_BUILD OFF)
|
||||
set(CMAKE_INSTALL_PREFIX "$ENV{WORKSPACE_DIR}/out")
|
||||
message(STATUS "Compiling within workspace")
|
||||
try_compile(
|
||||
WORKSPACE_TEST
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_SOURCE_DIR}/workspace_test.c
|
||||
CMAKE_FLAGS "-DCMAKE_C_COMPILER=$ENV{CC} -DCMAKE_CXX_COMPILER=$ENV{CXX} -DCMAKE_ASM_COMPILER=$ENV{AS} -DCMAKE_AR=$ENV{AR} -DCMAKE_LINKER=$ENV{LD}"
|
||||
OUTPUT_VARIABLE OUTPUT)
|
||||
if(NOT WORKSPACE_TEST)
|
||||
message(FATAL_ERROR "Workspace test failed: ${OUTPUT}")
|
||||
else()
|
||||
message(STATUS "Workspace test passed")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED TARGET_OS)
|
||||
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
|
||||
set(TARGET_OS "linux")
|
||||
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Fennix")
|
||||
set(TARGET_OS "fennix")
|
||||
else()
|
||||
message(FATAL_ERROR "Unsupported OS: ${CMAKE_SYSTEM_NAME}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED TARGET_ARCH)
|
||||
set(TARGET_ARCH ${CMAKE_SYSTEM_PROCESSOR})
|
||||
endif()
|
||||
|
||||
message(STATUS "Building for ${TARGET_OS}/${TARGET_ARCH}")
|
||||
|
||||
if(DEFINED ENV{CC})
|
||||
set(CMAKE_C_COMPILER "$ENV{CC}")
|
||||
endif()
|
||||
if(DEFINED ENV{CXX})
|
||||
set(CMAKE_CXX_COMPILER "$ENV{CXX}")
|
||||
endif()
|
||||
if(DEFINED ENV{AS})
|
||||
set(CMAKE_ASM_COMPILER "$ENV{AS}")
|
||||
endif()
|
||||
if(DEFINED ENV{AR})
|
||||
set(CMAKE_AR "$ENV{AR}")
|
||||
endif()
|
||||
if(DEFINED ENV{LD})
|
||||
set(CMAKE_LINKER "$ENV{LD}")
|
||||
endif()
|
||||
|
||||
if(DEFINED ENV{DEBUG} AND "$ENV{DEBUG}" STREQUAL "1")
|
||||
set(CMAKE_C_FLAGS "-ggdb3 -O0 -DDEBUG")
|
||||
else()
|
||||
set(CMAKE_C_FLAGS "-O2")
|
||||
endif()
|
||||
|
||||
set(SYSDEPS_DIR ${CMAKE_SOURCE_DIR}/sysdeps)
|
||||
set(ABIS_DIR ${CMAKE_SOURCE_DIR}/abis)
|
||||
|
||||
set(SYSDEPS_GENERIC ${SYSDEPS_DIR}/${TARGET_OS}/generic)
|
||||
set(SYSDEPS_PATH ${SYSDEPS_DIR}/${TARGET_OS}/${TARGET_ARCH})
|
||||
set(ABIS_GENERIC ${ABIS_DIR}/${TARGET_OS}/generic)
|
||||
set(ABIS_PATH ${ABIS_DIR}/${TARGET_OS}/${TARGET_ARCH})
|
||||
|
||||
if(NOT EXISTS ${SYSDEPS_PATH} AND NOT EXISTS ${SYSDEPS_GENERIC})
|
||||
message(FATAL_ERROR "Missing sysdeps for ${TARGET_OS}: ${SYSDEPS_PATH} or ${SYSDEPS_GENERIC}")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS ${ABIS_PATH} AND NOT EXISTS ${ABIS_GENERIC})
|
||||
message(FATAL_ERROR "Missing abis for ${TARGET_OS}: ${ABIS_PATH} or ${ABIS_GENERIC}")
|
||||
endif()
|
||||
|
||||
message(STATUS "Using sysdeps from: ${SYSDEPS_GENERIC} and ${SYSDEPS_PATH}")
|
||||
message(STATUS "Using abis from: ${ABIS_GENERIC} and ${ABIS_PATH}")
|
||||
|
||||
include_directories(${ABIS_GENERIC} ${ABIS_PATH})
|
||||
include_directories(${CMAKE_SOURCE_DIR}/include)
|
||||
|
||||
add_subdirectory(runtime)
|
||||
add_subdirectory(interpreter)
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(libs)
|
||||
|
||||
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/
|
||||
DESTINATION include
|
||||
FILES_MATCHING
|
||||
PATTERN "*")
|
||||
|
||||
install(DIRECTORY ${ABIS_GENERIC}/
|
||||
DESTINATION ${CMAKE_INSTALL_PREFIX}/include/
|
||||
FILES_MATCHING
|
||||
PATTERN "*")
|
||||
|
||||
install(DIRECTORY ${ABIS_PATH}/
|
||||
DESTINATION ${CMAKE_INSTALL_PREFIX}/include/
|
||||
FILES_MATCHING
|
||||
PATTERN "*")
|
@ -1,12 +0,0 @@
|
||||
build:
|
||||
cp -f $(WORKSPACE_DIR)/../Kernel/include/interface/errno.h $(CURDIR)/include/errno.h
|
||||
cp -f $(WORKSPACE_DIR)/../Kernel/include/interface/syscalls.h $(CURDIR)/include/fennix/syscalls.h
|
||||
cp -a $(CURDIR)/include/. $(WORKSPACE_DIR)/out/include
|
||||
make -C interpreter build
|
||||
make -C runtime build
|
||||
make -C src build
|
||||
|
||||
clean:
|
||||
make -C interpreter clean
|
||||
make -C runtime clean
|
||||
make -C src clean
|
591
Userspace/libc/abis/fennix/generic/bits/errno.h
Normal file
591
Userspace/libc/abis/fennix/generic/bits/errno.h
Normal file
@ -0,0 +1,591 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_API_ERRNO_H__
|
||||
#define __FENNIX_API_ERRNO_H__
|
||||
|
||||
/**
|
||||
* The documentation for these error codes are from:
|
||||
* https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html
|
||||
*
|
||||
* Full list:
|
||||
* https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/basedefs/errno.h.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* No Error
|
||||
*/
|
||||
#define EOK 0
|
||||
|
||||
/**
|
||||
* Argument list too long. The sum of the number of bytes used by the
|
||||
* new process image's argument list and environment list is greater
|
||||
* than the system-imposed limit of {ARG_MAX} bytes.
|
||||
* or:
|
||||
* Lack of space in an output buffer.
|
||||
* or:
|
||||
* Argument is greater than the system-imposed maximum.
|
||||
*/
|
||||
#define E2BIG 1
|
||||
|
||||
/**
|
||||
* Permission denied. An attempt was made to access a file in a way
|
||||
* forbidden by its file access permissions.
|
||||
*/
|
||||
#define EACCES 2
|
||||
|
||||
/**
|
||||
* Address in use. The specified address is in use.
|
||||
*/
|
||||
#define EADDRINUSE 3
|
||||
|
||||
/**
|
||||
* Address not available. The specified address is not available from
|
||||
* the local system.
|
||||
*/
|
||||
#define EADDRNOTAVAIL 4
|
||||
|
||||
/**
|
||||
* Address family not supported. The implementation does not support
|
||||
* the specified address family, or the specified address is not a
|
||||
* valid address for the address family of the specified socket.
|
||||
*/
|
||||
#define EAFNOSUPPORT 5
|
||||
|
||||
/**
|
||||
* Resource temporarily unavailable. This is a temporary condition
|
||||
* and later calls to the same routine may complete normally.
|
||||
*/
|
||||
#define EAGAIN 6
|
||||
|
||||
/**
|
||||
* Connection already in progress. A connection request is already in
|
||||
* progress for the specified socket.
|
||||
*/
|
||||
#define EALREADY 7
|
||||
|
||||
/**
|
||||
* Bad file descriptor. A file descriptor argument is out of range,
|
||||
* refers to no open file, or a read (write) request is made to a
|
||||
* file that is only open for writing (reading).
|
||||
*/
|
||||
#define EBADF 8
|
||||
|
||||
/**
|
||||
* Bad message. During a read(), getmsg(), getpmsg(), or ioctl()
|
||||
* I_RECVFD request to a STREAMS device, a message arrived at the
|
||||
* head of the STREAM that is inappropriate for the function
|
||||
* receiving the message.
|
||||
* read()
|
||||
* Message waiting to be read on a STREAM is not a data message.
|
||||
* getmsg() or getpmsg()
|
||||
* A file descriptor was received instead of a control message.
|
||||
* ioctl()
|
||||
* Control or data information was received instead of a file
|
||||
* descriptor when I_RECVFD was specified.
|
||||
*/
|
||||
#define EBADMSG 9
|
||||
|
||||
/**
|
||||
* Resource busy. An attempt was made to make use of a system
|
||||
* resource that is not currently available, as it is being
|
||||
* used by another process in a manner that would have
|
||||
* conflicted with the request being made by this process.
|
||||
*/
|
||||
#define EBUSY 10
|
||||
|
||||
/**
|
||||
* Operation canceled. The associated asynchronous operation was
|
||||
* canceled before completion.
|
||||
*/
|
||||
#define ECANCELED 11
|
||||
|
||||
/**
|
||||
* No child process. A wait(), waitid(), or waitpid() function was
|
||||
* executed by a process that had no existing or unwaited-for
|
||||
* child process.
|
||||
*/
|
||||
#define ECHILD 12
|
||||
|
||||
/**
|
||||
* Connection aborted. The connection has been aborted.
|
||||
*/
|
||||
#define ECONNABORTED 13
|
||||
|
||||
/**
|
||||
* Connection refused. An attempt to connect to a socket was refused
|
||||
* because there was no process listening or because the queue of
|
||||
* connection requests was full and the underlying protocol does not
|
||||
* support retransmissions.
|
||||
*/
|
||||
#define ECONNREFUSED 14
|
||||
|
||||
/**
|
||||
* Connection reset. The connection was forcibly closed by the peer.
|
||||
*/
|
||||
#define ECONNRESET 15
|
||||
|
||||
/**
|
||||
* Resource deadlock would occur. An attempt was made to lock a system
|
||||
* resource that would have resulted in a deadlock situation.
|
||||
*/
|
||||
#define EDEADLK 16
|
||||
|
||||
/**
|
||||
* Destination address required. No bind address was established.
|
||||
*/
|
||||
#define EDESTADDRREQ 17
|
||||
|
||||
/**
|
||||
* Domain error. An input argument is outside the defined domain of the
|
||||
* mathematical function (defined in the ISO C standard).
|
||||
*/
|
||||
#define EDOM 18
|
||||
|
||||
/**
|
||||
* Reserved.
|
||||
*/
|
||||
#define EDQUOT 19
|
||||
|
||||
/**
|
||||
* File exists. An existing file was mentioned in an inappropriate
|
||||
* context; for example, as a new link name in the link() function.
|
||||
*/
|
||||
#define EEXIST 20
|
||||
|
||||
/**
|
||||
* Bad address. The system detected an invalid address in attempting
|
||||
* to use an argument of a call. The reliable detection of this error
|
||||
* cannot be guaranteed, and when not detected may result in the
|
||||
* generation of a signal, indicating an address violation, which is
|
||||
* sent to the process.
|
||||
*/
|
||||
#define EFAULT 21
|
||||
|
||||
/**
|
||||
* File too large. The size of a file would exceed the maximum file
|
||||
* size of an implementation or offset maximum established in the
|
||||
* corresponding file description.
|
||||
*/
|
||||
#define EFBIG 22
|
||||
|
||||
/**
|
||||
* Host is unreachable. The destination host cannot be reached
|
||||
* (probably because the host is down or a remote router cannot
|
||||
* reach it).
|
||||
*/
|
||||
#define EHOSTUNREACH 23
|
||||
|
||||
/**
|
||||
* Identifier removed. Returned during XSI interprocess communication
|
||||
* if an identifier has been removed from the system.
|
||||
*/
|
||||
#define EIDRM 24
|
||||
|
||||
/**
|
||||
* Illegal byte sequence. A wide-character code has been detected that
|
||||
* does not correspond to a valid character, or a byte sequence does
|
||||
* not form a valid wide-character code (defined in the ISO C standard).
|
||||
*/
|
||||
#define EILSEQ 25
|
||||
|
||||
/**
|
||||
* Operation in progress. This code is used to indicate that an
|
||||
* asynchronous operation has not yet completed.
|
||||
* or:
|
||||
* O_NONBLOCK is set for the socket file descriptor and the connection
|
||||
* cannot be immediately established.
|
||||
*/
|
||||
#define EINPROGRESS 26
|
||||
|
||||
/**
|
||||
* Interrupted function call. An asynchronous signal was caught by the
|
||||
* process during the execution of an interruptible function. If the
|
||||
* signal handler performs a normal return, the interrupted function
|
||||
* call may return this condition (see the Base Definitions volume
|
||||
* of POSIX.1-2017, <signal.h>).
|
||||
*/
|
||||
#define EINTR 27
|
||||
|
||||
/**
|
||||
* Invalid argument. Some invalid argument was supplied; for example,
|
||||
* specifying an undefined signal in a signal() function or a
|
||||
* kill() function.
|
||||
*/
|
||||
#define EINVAL 28
|
||||
|
||||
/**
|
||||
* Input/output error. Some physical input or output error has occurred.
|
||||
* This error may be reported on a subsequent operation on the same
|
||||
* file descriptor. Any other error-causing operation on the same file
|
||||
* descriptor may cause the [EIO] error indication to be lost.
|
||||
*/
|
||||
#define EIO 29
|
||||
|
||||
/**
|
||||
* Socket is connected. The specified socket is already connected.
|
||||
*/
|
||||
#define EISCONN 30
|
||||
|
||||
/**
|
||||
* Is a directory. An attempt was made to open a directory with write
|
||||
* mode specified.
|
||||
*/
|
||||
#define EISDIR 31
|
||||
|
||||
/**
|
||||
* Symbolic link loop. A loop exists in symbolic links encountered
|
||||
* during pathname resolution. This error may also be returned if
|
||||
* more than {SYMLOOP_MAX} symbolic links are encountered during
|
||||
* pathname resolution.
|
||||
*/
|
||||
#define ELOOP 32
|
||||
|
||||
/**
|
||||
* File descriptor value too large or too many open streams. An
|
||||
* attempt was made to open a file descriptor with a value greater
|
||||
* than or equal to {OPEN_MAX}, or an attempt was made to open more
|
||||
* than the maximum number of streams allowed in the process.
|
||||
*/
|
||||
#define EMFILE 33
|
||||
|
||||
/**
|
||||
* Too many links. An attempt was made to have the link count of a
|
||||
* single file exceed {LINK_MAX}.
|
||||
*/
|
||||
#define EMLINK 34
|
||||
|
||||
/**
|
||||
* Message too large. A message sent on a transport provider was
|
||||
* larger than an internal message buffer or some other network limit.
|
||||
* or:
|
||||
* Inappropriate message buffer length.
|
||||
*/
|
||||
#define EMSGSIZE 35
|
||||
|
||||
/**
|
||||
* Reserved.
|
||||
*/
|
||||
#define EMULTIHOP 36
|
||||
|
||||
/**
|
||||
* Filename too long. The length of a pathname exceeds {PATH_MAX} and
|
||||
* the implementation considers this to be an error, or a pathname
|
||||
* component is longer than {NAME_MAX}. This error may also occur
|
||||
* when pathname substitution, as a result of encountering a
|
||||
* symbolic link during pathname resolution, results in a pathname
|
||||
* string the size of which exceeds {PATH_MAX}.
|
||||
*/
|
||||
#define ENAMETOOLONG 37
|
||||
|
||||
/**
|
||||
* Network is down. The local network interface used to reach the
|
||||
* destination is down.
|
||||
*/
|
||||
#define ENETDOWN 38
|
||||
|
||||
/**
|
||||
* The connection was aborted by the network.
|
||||
*/
|
||||
#define ENETRESET 39
|
||||
|
||||
/**
|
||||
* Network unreachable. No route to the network is present.
|
||||
*/
|
||||
#define ENETUNREACH 40
|
||||
|
||||
/**
|
||||
* Too many files open in system. Too many files are currently open
|
||||
* in the system. The system has reached its predefined limit for
|
||||
* simultaneously open files and temporarily cannot accept requests
|
||||
* to open another one.
|
||||
*/
|
||||
#define ENFILE 41
|
||||
|
||||
/**
|
||||
* No buffer space available. Insufficient buffer resources were
|
||||
* available in the system to perform the socket operation.
|
||||
*/
|
||||
#define ENOBUFS 42
|
||||
|
||||
/**
|
||||
* No message available. No message is available on the STREAM head
|
||||
* read queue.
|
||||
*/
|
||||
#define ENODATA 43
|
||||
|
||||
/**
|
||||
* No such device. An attempt was made to apply an inappropriate
|
||||
* function to a device; for example, trying to read a write-only
|
||||
* device such as a printer.
|
||||
*/
|
||||
#define ENODEV 44
|
||||
|
||||
/**
|
||||
* No such file or directory. A component of a specified pathname
|
||||
* does not exist, or the pathname is an empty string.
|
||||
*/
|
||||
#define ENOENT 45
|
||||
|
||||
/**
|
||||
* Executable file format error. A request is made to execute a file
|
||||
* that, although it has appropriate privileges, is not in the
|
||||
* format required by the implementation for executable files.
|
||||
*/
|
||||
#define ENOEXEC 46
|
||||
|
||||
/**
|
||||
* No locks available. A system-imposed limit on the number of
|
||||
* simultaneous file and record locks has been reached and no more
|
||||
* are currently available.
|
||||
*/
|
||||
#define ENOLCK 47
|
||||
|
||||
/**
|
||||
* Reserved.
|
||||
*/
|
||||
#define ENOLINK 48
|
||||
|
||||
/**
|
||||
* Not enough space. The new process image requires more memory than
|
||||
* is allowed by the hardware or system-imposed memory management
|
||||
* constraints.
|
||||
*/
|
||||
#define ENOMEM 49
|
||||
|
||||
/**
|
||||
* No message of the desired type. The message queue does not contain
|
||||
* a message of the required type during XSI interprocess communication.
|
||||
*/
|
||||
#define ENOMSG 50
|
||||
|
||||
/**
|
||||
* Protocol not available. The protocol option specified to
|
||||
* setsockopt() is not supported by the implementation.
|
||||
*/
|
||||
#define ENOPROTOOPT 51
|
||||
|
||||
/**
|
||||
* No space left on a device. During the write() function on a
|
||||
* regular file or when extending a directory, there is no free
|
||||
* space left on the device.
|
||||
*/
|
||||
#define ENOSPC 52
|
||||
|
||||
/**
|
||||
* No STREAM resources. Insufficient STREAMS memory resources are
|
||||
* available to perform a STREAMS-related function. This is a
|
||||
* temporary condition; it may be recovered from if other
|
||||
* processes release resources.
|
||||
*/
|
||||
#define ENOSR 53
|
||||
|
||||
/**
|
||||
* Not a STREAM. A STREAM function was attempted on a file descriptor
|
||||
* that was not associated with a STREAMS device.
|
||||
*/
|
||||
#define ENOSTR 54
|
||||
|
||||
/**
|
||||
* Functionality not supported. An attempt was made to use optional
|
||||
* functionality that is not supported in this implementation.
|
||||
*/
|
||||
#define ENOSYS 55
|
||||
|
||||
/**
|
||||
* Socket not connected. The socket is not connected.
|
||||
*/
|
||||
#define ENOTCONN 56
|
||||
|
||||
/**
|
||||
* Not a directory. A component of the specified pathname exists, but
|
||||
* it is not a directory, when a directory was expected; or an
|
||||
* attempt was made to create a non-directory file, and the specified
|
||||
* pathname contains at least one non- \<slash\> character and ends
|
||||
* with one or more trailing \<slash\> characters.
|
||||
*/
|
||||
#define ENOTDIR 57
|
||||
|
||||
/**
|
||||
* Directory not empty. A directory other than an empty directory
|
||||
* was supplied when an empty directory was expected.
|
||||
*/
|
||||
#define ENOTEMPTY 58
|
||||
|
||||
/**
|
||||
* State not recoverable. The state protected by a robust mutex
|
||||
* is not recoverable.
|
||||
*/
|
||||
#define ENOTRECOVERABLE 59
|
||||
|
||||
/**
|
||||
* Not a socket. The file descriptor does not refer to a socket.
|
||||
*/
|
||||
#define ENOTSOCK 60
|
||||
|
||||
/**
|
||||
* Not supported. The implementation does not support the requested
|
||||
* feature or value.
|
||||
*/
|
||||
#define ENOTSUP 61
|
||||
|
||||
/**
|
||||
* Inappropriate I/O control operation. A control function has been
|
||||
* attempted for a file or special file for which the operation
|
||||
* is inappropriate.
|
||||
*/
|
||||
#define ENOTTY 62
|
||||
|
||||
/**
|
||||
* No such device or address. Input or output on a special file
|
||||
* refers to a device that does not exist, or makes a request
|
||||
* beyond the capabilities of the device. It may also occur when,
|
||||
* for example, a tape drive is not on-line.
|
||||
*/
|
||||
#define ENXIO 63
|
||||
|
||||
/**
|
||||
* Operation not supported on socket. The type of socket (address
|
||||
* family or protocol) does not support the requested operation.
|
||||
*/
|
||||
#define EOPNOTSUPP 64
|
||||
|
||||
/**
|
||||
* Value too large to be stored in data type. An operation was
|
||||
* attempted which would generate a value that is outside the
|
||||
* range of values that can be represented in the relevant data
|
||||
* type or that are allowed for a given data item.
|
||||
*/
|
||||
#define EOVERFLOW 65
|
||||
|
||||
/**
|
||||
* Previous owner died. The owner of a robust mutex terminated
|
||||
* while holding the mutex lock.
|
||||
*/
|
||||
#define EOWNERDEAD 66
|
||||
|
||||
/**
|
||||
* Operation not permitted. An attempt was made to perform an
|
||||
* operation limited to processes with appropriate privileges or
|
||||
* to the owner of a file or other resource.
|
||||
*/
|
||||
#define EPERM 67
|
||||
|
||||
/**
|
||||
* Broken pipe. A write was attempted on a socket, pipe, or FIFO
|
||||
* for which there is no process to read the data.
|
||||
*/
|
||||
#define EPIPE 68
|
||||
|
||||
/**
|
||||
* Protocol error. Some protocol error occurred. This error is
|
||||
* device-specific, but is generally not related to a
|
||||
* hardware failure.
|
||||
*/
|
||||
#define EPROTO 69
|
||||
|
||||
/**
|
||||
* Protocol not supported. The protocol is not supported by the
|
||||
* address family, or the protocol is not supported by
|
||||
* the implementation.
|
||||
*/
|
||||
#define EPROTONOSUPPORT 70
|
||||
|
||||
/**
|
||||
* Protocol wrong type for socket. The socket type is not
|
||||
* supported by the protocol.
|
||||
*/
|
||||
#define EPROTOTYPE 71
|
||||
|
||||
/**
|
||||
* Result too large or too small. The result of the function
|
||||
* is too large (overflow) or too small (underflow) to be
|
||||
* represented in the available space.
|
||||
*/
|
||||
#define ERANGE 72
|
||||
|
||||
/**
|
||||
* Read-only file system. An attempt was made to modify a file
|
||||
* or directory on a file system that is read-only.
|
||||
*/
|
||||
#define EROFS 73
|
||||
|
||||
/**
|
||||
* Invalid seek. An attempt was made to access the file offset
|
||||
* associated with a pipe or FIFO.
|
||||
*/
|
||||
#define ESPIPE 74
|
||||
|
||||
/**
|
||||
* No such process. No process can be found corresponding to that
|
||||
* specified by the given process ID.
|
||||
*/
|
||||
#define ESRCH 75
|
||||
|
||||
/**
|
||||
* Reserved.
|
||||
*/
|
||||
#define ESTALE 76
|
||||
|
||||
/**
|
||||
* STREAM ioctl() timeout. The timer set for a STREAMS ioctl() call
|
||||
* has expired. The cause of this error is device-specific and could
|
||||
* indicate either a hardware or software failure, or a timeout
|
||||
* value that is too short for the specific operation. The status
|
||||
* of the ioctl() operation is unspecified.
|
||||
*/
|
||||
#define ETIME 77
|
||||
|
||||
/**
|
||||
* Connection timed out. The connection to a remote machine has
|
||||
* timed out.
|
||||
* If the connection timed out during execution of the function that
|
||||
* reported this error (as opposed to timing out prior to the
|
||||
* function being called), it is unspecified whether the function
|
||||
* has completed some or all of the documented behavior associated
|
||||
* with a successful completion of the function.
|
||||
* or:
|
||||
* Operation timed out. The time limit associated with the operation
|
||||
* was exceeded before the operation completed.
|
||||
*/
|
||||
#define ETIMEDOUT 78
|
||||
|
||||
/**
|
||||
* Text file busy. An attempt was made to execute a pure-procedure
|
||||
* program that is currently open for writing, or an attempt has
|
||||
* been made to open for writing a pure-procedure program that
|
||||
* is being executed.
|
||||
*/
|
||||
#define ETXTBSY 79
|
||||
|
||||
/**
|
||||
* Operation would block. An operation on a socket marked as
|
||||
* non-blocking has encountered a situation such as no data available
|
||||
* that otherwise would have caused the function to suspend execution.
|
||||
*/
|
||||
#define EWOULDBLOCK 80
|
||||
|
||||
/**
|
||||
* Improper link. A link to a file on another file system was attempted.
|
||||
*/
|
||||
#define EXDEV 81
|
||||
|
||||
#ifdef __kernel__
|
||||
#define __ERRNO_MAX 82
|
||||
#endif
|
||||
|
||||
#endif // !__FENNIX_API_ERRNO_H__
|
124
Userspace/libc/abis/fennix/generic/bits/signal.h
Normal file
124
Userspace/libc/abis/fennix/generic/bits/signal.h
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
This file is part of Fennix C Library.
|
||||
|
||||
Fennix C Library is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __BITS_SIGNAL_H
|
||||
#define __BITS_SIGNAL_H
|
||||
|
||||
#include <bits/syscalls.h>
|
||||
|
||||
#define SIGNULL __SYS_SIGNULL
|
||||
#define SIGABRT __SYS_SIGABRT
|
||||
#define SIGALRM __SYS_SIGALRM
|
||||
#define SIGBUS __SYS_SIGBUS
|
||||
#define SIGCHLD __SYS_SIGCHLD
|
||||
#define SIGCONT __SYS_SIGCONT
|
||||
#define SIGFPE __SYS_SIGFPE
|
||||
#define SIGHUP __SYS_SIGHUP
|
||||
#define SIGILL __SYS_SIGILL
|
||||
#define SIGINT __SYS_SIGINT
|
||||
#define SIGKILL __SYS_SIGKILL
|
||||
#define SIGPIPE __SYS_SIGPIPE
|
||||
#define SIGQUIT __SYS_SIGQUIT
|
||||
#define SIGSEGV __SYS_SIGSEGV
|
||||
#define SIGSTOP __SYS_SIGSTOP
|
||||
#define SIGTERM __SYS_SIGTERM
|
||||
#define SIGTSTP __SYS_SIGTSTP
|
||||
#define SIGTTIN __SYS_SIGTTIN
|
||||
#define SIGTTOU __SYS_SIGTTOU
|
||||
#define SIGUSR1 __SYS_SIGUSR1
|
||||
#define SIGUSR2 __SYS_SIGUSR2
|
||||
#define SIGPOLL __SYS_SIGPOLL
|
||||
#define SIGPROF __SYS_SIGPROF
|
||||
#define SIGSYS __SYS_SIGSYS
|
||||
#define SIGTRAP __SYS_SIGTRAP
|
||||
#define SIGURG __SYS_SIGURG
|
||||
#define SIGVTALRM __SYS_SIGVTALRM
|
||||
#define SIGXCPU __SYS_SIGXCPU
|
||||
#define SIGXFSZ __SYS_SIGXFSZ
|
||||
#define SIGCOMP1 __SYS_SIGCOMP1
|
||||
#define SIGCOMP2 __SYS_SIGCOMP2
|
||||
#define SIGCOMP3 __SYS_SIGCOMP3
|
||||
#define SIGRTMIN __SYS_SIGRTMIN
|
||||
#define SIGRT_1 __SYS_SIGRT_1
|
||||
#define SIGRT_2 __SYS_SIGRT_2
|
||||
#define SIGRT_3 __SYS_SIGRT_3
|
||||
#define SIGRT_4 __SYS_SIGRT_4
|
||||
#define SIGRT_5 __SYS_SIGRT_5
|
||||
#define SIGRT_6 __SYS_SIGRT_6
|
||||
#define SIGRT_7 __SYS_SIGRT_7
|
||||
#define SIGRT_8 __SYS_SIGRT_8
|
||||
#define SIGRT_9 __SYS_SIGRT_9
|
||||
#define SIGRT_10 __SYS_SIGRT_10
|
||||
#define SIGRT_11 __SYS_SIGRT_11
|
||||
#define SIGRT_12 __SYS_SIGRT_12
|
||||
#define SIGRT_13 __SYS_SIGRT_13
|
||||
#define SIGRT_14 __SYS_SIGRT_14
|
||||
#define SIGRT_15 __SYS_SIGRT_15
|
||||
#define SIGRT_16 __SYS_SIGRT_16
|
||||
#define SIGRT_17 __SYS_SIGRT_17
|
||||
#define SIGRT_18 __SYS_SIGRT_18
|
||||
#define SIGRT_19 __SYS_SIGRT_19
|
||||
#define SIGRT_20 __SYS_SIGRT_20
|
||||
#define SIGRT_21 __SYS_SIGRT_21
|
||||
#define SIGRT_22 __SYS_SIGRT_22
|
||||
#define SIGRT_23 __SYS_SIGRT_23
|
||||
#define SIGRT_24 __SYS_SIGRT_24
|
||||
#define SIGRT_25 __SYS_SIGRT_25
|
||||
#define SIGRT_26 __SYS_SIGRT_26
|
||||
#define SIGRT_27 __SYS_SIGRT_27
|
||||
#define SIGRT_28 __SYS_SIGRT_28
|
||||
#define SIGRT_29 __SYS_SIGRT_29
|
||||
#define SIGRT_30 __SYS_SIGRT_30
|
||||
#define SIGRT_31 __SYS_SIGRT_31
|
||||
#define SIGRTMAX __SYS_SIGRTMAX
|
||||
#define SIGNAL_MAX __SYS_SIGNAL_MAX
|
||||
|
||||
#define SIG_TERM __SYS_SIG_TERM
|
||||
// #define SIG_IGN __SYS_SIG_IGN
|
||||
#define SIG_CORE __SYS_SIG_CORE
|
||||
#define SIG_STOP __SYS_SIG_STOP
|
||||
#define SIG_CONT __SYS_SIG_CONT
|
||||
|
||||
#define SIG_BLOCK __SYS_SIG_BLOCK
|
||||
#define SIG_UNBLOCK __SYS_SIG_UNBLOCK
|
||||
#define SIG_SETMASK __SYS_SIG_SETMASK
|
||||
|
||||
#define SA_NOCLDSTOP __SYS_SA_NOCLDSTOP
|
||||
#define SA_ONSTACK __SYS_SA_ONSTACK
|
||||
#define SA_RESETHAND __SYS_SA_RESETHAND
|
||||
#define SA_RESTART __SYS_SA_RESTART
|
||||
#define SA_SIGINFO __SYS_SA_SIGINFO
|
||||
#define SA_NOCLDWAIT __SYS_SA_NOCLDWAIT
|
||||
#define SA_NODEFER __SYS_SA_NODEFER
|
||||
|
||||
#define SS_ONSTACK
|
||||
#define SS_DISABLE
|
||||
|
||||
#define MINSIGSTKSZ
|
||||
#define SIGSTKSZ
|
||||
|
||||
#define SIG_ERR ((void (*)(int))__SYS_SIG_ERR)
|
||||
#define SIG_DFL ((void (*)(int))__SYS_SIG_DFL)
|
||||
#define SIG_IGN ((void (*)(int))__SYS_SIG_IGN)
|
||||
|
||||
#define SIGEV_NONE
|
||||
#define SIGEV_SIGNAL
|
||||
#define SIGEV_THREAD
|
||||
|
||||
typedef unsigned long sigset_t;
|
||||
|
||||
#endif // __BITS_SIGNAL_H
|
34
Userspace/libc/abis/fennix/generic/bits/socket.h
Normal file
34
Userspace/libc/abis/fennix/generic/bits/socket.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
This file is part of Fennix C Library.
|
||||
|
||||
Fennix C Library is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __BITS_SOCKET_H
|
||||
#define __BITS_SOCKET_H
|
||||
|
||||
#define __socklen_t_defined
|
||||
typedef __UINT32_TYPE__ socklen_t;
|
||||
|
||||
#define __sa_family_t_defined
|
||||
typedef unsigned int sa_family_t;
|
||||
|
||||
#define __sockaddr_defined
|
||||
struct sockaddr
|
||||
{
|
||||
sa_family_t sa_family;
|
||||
char sa_data[14];
|
||||
};
|
||||
|
||||
#endif // __BITS_SOCKET_H
|
@ -15,8 +15,8 @@
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_API_SYSCALLS_LIST_H__
|
||||
#define __FENNIX_API_SYSCALLS_LIST_H__
|
||||
#ifndef __FENNIX_API_SYSTEM_CALLS_LIST_H__
|
||||
#define __FENNIX_API_SYSTEM_CALLS_LIST_H__
|
||||
|
||||
#pragma region Syscall Wrappers
|
||||
|
||||
@ -1809,4 +1809,4 @@ typedef enum
|
||||
/** @copydoc SYS_UNAME */
|
||||
#define call_uname(buf) syscall1(SYS_UNAME, (scarg)buf)
|
||||
|
||||
#endif // !__FENNIX_API_SYSCALLS_LIST_H__
|
||||
#endif // !__FENNIX_API_SYSTEM_CALLS_LIST_H__
|
70
Userspace/libc/include/bits/libc.h
Normal file
70
Userspace/libc/include/bits/libc.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
This file is part of Fennix C Library.
|
||||
|
||||
Fennix C Library is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef FENNIX_BITS_LIBC_H
|
||||
#define FENNIX_BITS_LIBC_H
|
||||
|
||||
#include <bits/socket.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef __kernel__
|
||||
#error "Kernel code should not include this header"
|
||||
#endif // __kernel__
|
||||
|
||||
#ifndef export
|
||||
#define export __attribute__((__visibility__("default")))
|
||||
#endif // export
|
||||
|
||||
#define sysdep(name) \
|
||||
__libc_##name
|
||||
|
||||
void sysdep(Exit)(int Status);
|
||||
int sysdep(Accept)(int Socket, struct sockaddr *restrict Address, socklen_t *restrict AddressLength);
|
||||
int sysdep(Bind)(int Socket, const struct sockaddr *Address, socklen_t AddressLength);
|
||||
int sysdep(Connect)(int Socket, const struct sockaddr *Address, socklen_t AddressLength);
|
||||
int sysdep(Listen)(int Socket, int Backlog);
|
||||
int sysdep(Socket)(int Domain, int Type, int Protocol);
|
||||
int sysdep(UnixName)(struct utsname *Name);
|
||||
int sysdep(WaitProcessID)(pid_t ProcessID, int *Status, int Options);
|
||||
int sysdep(IOControl)(int Descriptor, unsigned long Operation, void *Argument);
|
||||
void *sysdep(MemoryMap)(void *Address, size_t Length, int Protection, int Flags, int Descriptor, off_t Offset);
|
||||
int sysdep(MemoryUnmap)(void *Address, size_t Length);
|
||||
int sysdep(MemoryProtect)(void *Address, size_t Length, int Protection);
|
||||
int sysdep(Fork)(void);
|
||||
int sysdep(Read)(int Descriptor, void *Buffer, size_t Size);
|
||||
int sysdep(Write)(int Descriptor, const void *Buffer, size_t Size);
|
||||
int sysdep(PRead)(int Descriptor, void *Buffer, size_t Size, off_t Offset);
|
||||
int sysdep(PWrite)(int Descriptor, const void *Buffer, size_t Size, off_t Offset);
|
||||
int sysdep(Open)(const char *Pathname, int Flags, mode_t Mode);
|
||||
int sysdep(Close)(int Descriptor);
|
||||
int sysdep(Access)(const char *Pathname, int Mode);
|
||||
int sysdep(Tell)(int Descriptor);
|
||||
int sysdep(Seek)(int Descriptor, off_t Offset, int Whence);
|
||||
pid_t sysdep(GetProcessID)(void);
|
||||
pid_t sysdep(GetParentProcessID)(void);
|
||||
int sysdep(Execve)(const char *Pathname, char *const *Argv, char *const *Envp);
|
||||
int sysdep(Kill)(pid_t ProcessID, int Signal);
|
||||
int sysdep(Stat)(const char *Pathname, struct stat *Statbuf);
|
||||
int sysdep(FStat)(int Descriptor, struct stat *Statbuf);
|
||||
int sysdep(LStat)(const char *Pathname, struct stat *Statbuf);
|
||||
int sysdep(Truncate)(const char *Pathname, off_t Length);
|
||||
int sysdep(MakeDirectory)(const char *Pathname, mode_t Mode);
|
||||
int sysdep(ProcessControl)(unsigned long Option, unsigned long Arg1, unsigned long Arg2, unsigned long Arg3, unsigned long Arg4);
|
||||
|
||||
#endif // FENNIX_BITS_LIBC_H
|
36
Userspace/libc/include/bits/types/signal.h
Normal file
36
Userspace/libc/include/bits/types/signal.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
This file is part of Fennix C Library.
|
||||
|
||||
Fennix C Library is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __BITS_TYPES_SIGNAL_H
|
||||
#define __BITS_TYPES_SIGNAL_H
|
||||
|
||||
union sigval
|
||||
{
|
||||
int sival_int; /* Integer signal value. */
|
||||
void *sival_ptr; /* Pointer signal value. */
|
||||
};
|
||||
|
||||
typedef struct sigevent
|
||||
{
|
||||
int sigev_notify; /* Notification type. */
|
||||
int sigev_signo; /* Signal number. */
|
||||
union sigval sigev_value; /* Signal value. */
|
||||
void (*sigev_notify_function)(union sigval); /* Notification function. */
|
||||
pthread_attr_t *sigev_notify_attributes; /* Notification attributes. */
|
||||
} sigevent;
|
||||
|
||||
#endif // __BITS_TYPES_SIGNAL_H
|
@ -1,592 +1,24 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
This file is part of Fennix C Library.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
Fennix C Library is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
Fennix C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_API_ERRNO_H__
|
||||
#define __FENNIX_API_ERRNO_H__
|
||||
#ifndef _ERRNO_H
|
||||
#define _ERRNO_H
|
||||
|
||||
/**
|
||||
* The documentation for these error codes are from:
|
||||
* https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html
|
||||
*
|
||||
* Full list:
|
||||
* https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/basedefs/errno.h.html
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
/**
|
||||
* No Error
|
||||
*/
|
||||
EOK = 0,
|
||||
|
||||
/**
|
||||
* Argument list too long. The sum of the number of bytes used by the
|
||||
* new process image's argument list and environment list is greater
|
||||
* than the system-imposed limit of {ARG_MAX} bytes.
|
||||
* or:
|
||||
* Lack of space in an output buffer.
|
||||
* or:
|
||||
* Argument is greater than the system-imposed maximum.
|
||||
*/
|
||||
E2BIG = 1,
|
||||
|
||||
/**
|
||||
* Permission denied. An attempt was made to access a file in a way
|
||||
* forbidden by its file access permissions.
|
||||
*/
|
||||
EACCES = 2,
|
||||
|
||||
/**
|
||||
* Address in use. The specified address is in use.
|
||||
*/
|
||||
EADDRINUSE = 3,
|
||||
|
||||
/**
|
||||
* Address not available. The specified address is not available from
|
||||
* the local system.
|
||||
*/
|
||||
EADDRNOTAVAIL = 4,
|
||||
|
||||
/**
|
||||
* Address family not supported. The implementation does not support
|
||||
* the specified address family, or the specified address is not a
|
||||
* valid address for the address family of the specified socket.
|
||||
*/
|
||||
EAFNOSUPPORT = 5,
|
||||
|
||||
/**
|
||||
* Resource temporarily unavailable. This is a temporary condition
|
||||
* and later calls to the same routine may complete normally.
|
||||
*/
|
||||
EAGAIN = 6,
|
||||
|
||||
/**
|
||||
* Connection already in progress. A connection request is already in
|
||||
* progress for the specified socket.
|
||||
*/
|
||||
EALREADY = 7,
|
||||
|
||||
/**
|
||||
* Bad file descriptor. A file descriptor argument is out of range,
|
||||
* refers to no open file, or a read (write) request is made to a
|
||||
* file that is only open for writing (reading).
|
||||
*/
|
||||
EBADF = 8,
|
||||
|
||||
/**
|
||||
* Bad message. During a read(), getmsg(), getpmsg(), or ioctl()
|
||||
* I_RECVFD request to a STREAMS device, a message arrived at the
|
||||
* head of the STREAM that is inappropriate for the function
|
||||
* receiving the message.
|
||||
* read()
|
||||
* Message waiting to be read on a STREAM is not a data message.
|
||||
* getmsg() or getpmsg()
|
||||
* A file descriptor was received instead of a control message.
|
||||
* ioctl()
|
||||
* Control or data information was received instead of a file
|
||||
* descriptor when I_RECVFD was specified.
|
||||
*/
|
||||
EBADMSG = 9,
|
||||
|
||||
/**
|
||||
* Resource busy. An attempt was made to make use of a system
|
||||
* resource that is not currently available, as it is being
|
||||
* used by another process in a manner that would have
|
||||
* conflicted with the request being made by this process.
|
||||
*/
|
||||
EBUSY = 10,
|
||||
|
||||
/**
|
||||
* Operation canceled. The associated asynchronous operation was
|
||||
* canceled before completion.
|
||||
*/
|
||||
ECANCELED = 11,
|
||||
|
||||
/**
|
||||
* No child process. A wait(), waitid(), or waitpid() function was
|
||||
* executed by a process that had no existing or unwaited-for
|
||||
* child process.
|
||||
*/
|
||||
ECHILD = 12,
|
||||
|
||||
/**
|
||||
* Connection aborted. The connection has been aborted.
|
||||
*/
|
||||
ECONNABORTED = 13,
|
||||
|
||||
/**
|
||||
* Connection refused. An attempt to connect to a socket was refused
|
||||
* because there was no process listening or because the queue of
|
||||
* connection requests was full and the underlying protocol does not
|
||||
* support retransmissions.
|
||||
*/
|
||||
ECONNREFUSED = 14,
|
||||
|
||||
/**
|
||||
* Connection reset. The connection was forcibly closed by the peer.
|
||||
*/
|
||||
ECONNRESET = 15,
|
||||
|
||||
/**
|
||||
* Resource deadlock would occur. An attempt was made to lock a system
|
||||
* resource that would have resulted in a deadlock situation.
|
||||
*/
|
||||
EDEADLK = 16,
|
||||
|
||||
/**
|
||||
* Destination address required. No bind address was established.
|
||||
*/
|
||||
EDESTADDRREQ = 17,
|
||||
|
||||
/**
|
||||
* Domain error. An input argument is outside the defined domain of the
|
||||
* mathematical function (defined in the ISO C standard).
|
||||
*/
|
||||
EDOM = 18,
|
||||
|
||||
/**
|
||||
* Reserved.
|
||||
*/
|
||||
EDQUOT = 19,
|
||||
|
||||
/**
|
||||
* File exists. An existing file was mentioned in an inappropriate
|
||||
* context; for example, as a new link name in the link() function.
|
||||
*/
|
||||
EEXIST = 20,
|
||||
|
||||
/**
|
||||
* Bad address. The system detected an invalid address in attempting
|
||||
* to use an argument of a call. The reliable detection of this error
|
||||
* cannot be guaranteed, and when not detected may result in the
|
||||
* generation of a signal, indicating an address violation, which is
|
||||
* sent to the process.
|
||||
*/
|
||||
EFAULT = 21,
|
||||
|
||||
/**
|
||||
* File too large. The size of a file would exceed the maximum file
|
||||
* size of an implementation or offset maximum established in the
|
||||
* corresponding file description.
|
||||
*/
|
||||
EFBIG = 22,
|
||||
|
||||
/**
|
||||
* Host is unreachable. The destination host cannot be reached
|
||||
* (probably because the host is down or a remote router cannot
|
||||
* reach it).
|
||||
*/
|
||||
EHOSTUNREACH = 23,
|
||||
|
||||
/**
|
||||
* Identifier removed. Returned during XSI interprocess communication
|
||||
* if an identifier has been removed from the system.
|
||||
*/
|
||||
EIDRM = 24,
|
||||
|
||||
/**
|
||||
* Illegal byte sequence. A wide-character code has been detected that
|
||||
* does not correspond to a valid character, or a byte sequence does
|
||||
* not form a valid wide-character code (defined in the ISO C standard).
|
||||
*/
|
||||
EILSEQ = 25,
|
||||
|
||||
/**
|
||||
* Operation in progress. This code is used to indicate that an
|
||||
* asynchronous operation has not yet completed.
|
||||
* or:
|
||||
* O_NONBLOCK is set for the socket file descriptor and the connection
|
||||
* cannot be immediately established.
|
||||
*/
|
||||
EINPROGRESS = 26,
|
||||
|
||||
/**
|
||||
* Interrupted function call. An asynchronous signal was caught by the
|
||||
* process during the execution of an interruptible function. If the
|
||||
* signal handler performs a normal return, the interrupted function
|
||||
* call may return this condition (see the Base Definitions volume
|
||||
* of POSIX.1-2017, <signal.h>).
|
||||
*/
|
||||
EINTR = 27,
|
||||
|
||||
/**
|
||||
* Invalid argument. Some invalid argument was supplied; for example,
|
||||
* specifying an undefined signal in a signal() function or a
|
||||
* kill() function.
|
||||
*/
|
||||
EINVAL = 28,
|
||||
|
||||
/**
|
||||
* Input/output error. Some physical input or output error has occurred.
|
||||
* This error may be reported on a subsequent operation on the same
|
||||
* file descriptor. Any other error-causing operation on the same file
|
||||
* descriptor may cause the [EIO] error indication to be lost.
|
||||
*/
|
||||
EIO = 29,
|
||||
|
||||
/**
|
||||
* Socket is connected. The specified socket is already connected.
|
||||
*/
|
||||
EISCONN = 30,
|
||||
|
||||
/**
|
||||
* Is a directory. An attempt was made to open a directory with write
|
||||
* mode specified.
|
||||
*/
|
||||
EISDIR = 31,
|
||||
|
||||
/**
|
||||
* Symbolic link loop. A loop exists in symbolic links encountered
|
||||
* during pathname resolution. This error may also be returned if
|
||||
* more than {SYMLOOP_MAX} symbolic links are encountered during
|
||||
* pathname resolution.
|
||||
*/
|
||||
ELOOP = 32,
|
||||
|
||||
/**
|
||||
* File descriptor value too large or too many open streams. An
|
||||
* attempt was made to open a file descriptor with a value greater
|
||||
* than or equal to {OPEN_MAX}, or an attempt was made to open more
|
||||
* than the maximum number of streams allowed in the process.
|
||||
*/
|
||||
EMFILE = 33,
|
||||
|
||||
/**
|
||||
* Too many links. An attempt was made to have the link count of a
|
||||
* single file exceed {LINK_MAX}.
|
||||
*/
|
||||
EMLINK = 34,
|
||||
|
||||
/**
|
||||
* Message too large. A message sent on a transport provider was
|
||||
* larger than an internal message buffer or some other network limit.
|
||||
* or:
|
||||
* Inappropriate message buffer length.
|
||||
*/
|
||||
EMSGSIZE = 35,
|
||||
|
||||
/**
|
||||
* Reserved.
|
||||
*/
|
||||
EMULTIHOP = 36,
|
||||
|
||||
/**
|
||||
* Filename too long. The length of a pathname exceeds {PATH_MAX} and
|
||||
* the implementation considers this to be an error, or a pathname
|
||||
* component is longer than {NAME_MAX}. This error may also occur
|
||||
* when pathname substitution, as a result of encountering a
|
||||
* symbolic link during pathname resolution, results in a pathname
|
||||
* string the size of which exceeds {PATH_MAX}.
|
||||
*/
|
||||
ENAMETOOLONG = 37,
|
||||
|
||||
/**
|
||||
* Network is down. The local network interface used to reach the
|
||||
* destination is down.
|
||||
*/
|
||||
ENETDOWN = 38,
|
||||
|
||||
/**
|
||||
* The connection was aborted by the network.
|
||||
*/
|
||||
ENETRESET = 39,
|
||||
|
||||
/**
|
||||
* Network unreachable. No route to the network is present.
|
||||
*/
|
||||
ENETUNREACH = 40,
|
||||
|
||||
/**
|
||||
* Too many files open in system. Too many files are currently open
|
||||
* in the system. The system has reached its predefined limit for
|
||||
* simultaneously open files and temporarily cannot accept requests
|
||||
* to open another one.
|
||||
*/
|
||||
ENFILE = 41,
|
||||
|
||||
/**
|
||||
* No buffer space available. Insufficient buffer resources were
|
||||
* available in the system to perform the socket operation.
|
||||
*/
|
||||
ENOBUFS = 42,
|
||||
|
||||
/**
|
||||
* No message available. No message is available on the STREAM head
|
||||
* read queue.
|
||||
*/
|
||||
ENODATA = 43,
|
||||
|
||||
/**
|
||||
* No such device. An attempt was made to apply an inappropriate
|
||||
* function to a device; for example, trying to read a write-only
|
||||
* device such as a printer.
|
||||
*/
|
||||
ENODEV = 44,
|
||||
|
||||
/**
|
||||
* No such file or directory. A component of a specified pathname
|
||||
* does not exist, or the pathname is an empty string.
|
||||
*/
|
||||
ENOENT = 45,
|
||||
|
||||
/**
|
||||
* Executable file format error. A request is made to execute a file
|
||||
* that, although it has appropriate privileges, is not in the
|
||||
* format required by the implementation for executable files.
|
||||
*/
|
||||
ENOEXEC = 46,
|
||||
|
||||
/**
|
||||
* No locks available. A system-imposed limit on the number of
|
||||
* simultaneous file and record locks has been reached and no more
|
||||
* are currently available.
|
||||
*/
|
||||
ENOLCK = 47,
|
||||
|
||||
/**
|
||||
* Reserved.
|
||||
*/
|
||||
ENOLINK = 48,
|
||||
|
||||
/**
|
||||
* Not enough space. The new process image requires more memory than
|
||||
* is allowed by the hardware or system-imposed memory management
|
||||
* constraints.
|
||||
*/
|
||||
ENOMEM = 49,
|
||||
|
||||
/**
|
||||
* No message of the desired type. The message queue does not contain
|
||||
* a message of the required type during XSI interprocess communication.
|
||||
*/
|
||||
ENOMSG = 50,
|
||||
|
||||
/**
|
||||
* Protocol not available. The protocol option specified to
|
||||
* setsockopt() is not supported by the implementation.
|
||||
*/
|
||||
ENOPROTOOPT = 51,
|
||||
|
||||
/**
|
||||
* No space left on a device. During the write() function on a
|
||||
* regular file or when extending a directory, there is no free
|
||||
* space left on the device.
|
||||
*/
|
||||
ENOSPC = 52,
|
||||
|
||||
/**
|
||||
* No STREAM resources. Insufficient STREAMS memory resources are
|
||||
* available to perform a STREAMS-related function. This is a
|
||||
* temporary condition; it may be recovered from if other
|
||||
* processes release resources.
|
||||
*/
|
||||
ENOSR = 53,
|
||||
|
||||
/**
|
||||
* Not a STREAM. A STREAM function was attempted on a file descriptor
|
||||
* that was not associated with a STREAMS device.
|
||||
*/
|
||||
ENOSTR = 54,
|
||||
|
||||
/**
|
||||
* Functionality not supported. An attempt was made to use optional
|
||||
* functionality that is not supported in this implementation.
|
||||
*/
|
||||
ENOSYS = 55,
|
||||
|
||||
/**
|
||||
* Socket not connected. The socket is not connected.
|
||||
*/
|
||||
ENOTCONN = 56,
|
||||
|
||||
/**
|
||||
* Not a directory. A component of the specified pathname exists, but
|
||||
* it is not a directory, when a directory was expected; or an
|
||||
* attempt was made to create a non-directory file, and the specified
|
||||
* pathname contains at least one non- \<slash\> character and ends
|
||||
* with one or more trailing \<slash\> characters.
|
||||
*/
|
||||
ENOTDIR = 57,
|
||||
|
||||
/**
|
||||
* Directory not empty. A directory other than an empty directory
|
||||
* was supplied when an empty directory was expected.
|
||||
*/
|
||||
ENOTEMPTY = 58,
|
||||
|
||||
/**
|
||||
* State not recoverable. The state protected by a robust mutex
|
||||
* is not recoverable.
|
||||
*/
|
||||
ENOTRECOVERABLE = 59,
|
||||
|
||||
/**
|
||||
* Not a socket. The file descriptor does not refer to a socket.
|
||||
*/
|
||||
ENOTSOCK = 60,
|
||||
|
||||
/**
|
||||
* Not supported. The implementation does not support the requested
|
||||
* feature or value.
|
||||
*/
|
||||
ENOTSUP = 61,
|
||||
|
||||
/**
|
||||
* Inappropriate I/O control operation. A control function has been
|
||||
* attempted for a file or special file for which the operation
|
||||
* is inappropriate.
|
||||
*/
|
||||
ENOTTY = 62,
|
||||
|
||||
/**
|
||||
* No such device or address. Input or output on a special file
|
||||
* refers to a device that does not exist, or makes a request
|
||||
* beyond the capabilities of the device. It may also occur when,
|
||||
* for example, a tape drive is not on-line.
|
||||
*/
|
||||
ENXIO = 63,
|
||||
|
||||
/**
|
||||
* Operation not supported on socket. The type of socket (address
|
||||
* family or protocol) does not support the requested operation.
|
||||
*/
|
||||
EOPNOTSUPP = 64,
|
||||
|
||||
/**
|
||||
* Value too large to be stored in data type. An operation was
|
||||
* attempted which would generate a value that is outside the
|
||||
* range of values that can be represented in the relevant data
|
||||
* type or that are allowed for a given data item.
|
||||
*/
|
||||
EOVERFLOW = 65,
|
||||
|
||||
/**
|
||||
* Previous owner died. The owner of a robust mutex terminated
|
||||
* while holding the mutex lock.
|
||||
*/
|
||||
EOWNERDEAD = 66,
|
||||
|
||||
/**
|
||||
* Operation not permitted. An attempt was made to perform an
|
||||
* operation limited to processes with appropriate privileges or
|
||||
* to the owner of a file or other resource.
|
||||
*/
|
||||
EPERM = 67,
|
||||
|
||||
/**
|
||||
* Broken pipe. A write was attempted on a socket, pipe, or FIFO
|
||||
* for which there is no process to read the data.
|
||||
*/
|
||||
EPIPE = 68,
|
||||
|
||||
/**
|
||||
* Protocol error. Some protocol error occurred. This error is
|
||||
* device-specific, but is generally not related to a
|
||||
* hardware failure.
|
||||
*/
|
||||
EPROTO = 69,
|
||||
|
||||
/**
|
||||
* Protocol not supported. The protocol is not supported by the
|
||||
* address family, or the protocol is not supported by
|
||||
* the implementation.
|
||||
*/
|
||||
EPROTONOSUPPORT = 70,
|
||||
|
||||
/**
|
||||
* Protocol wrong type for socket. The socket type is not
|
||||
* supported by the protocol.
|
||||
*/
|
||||
EPROTOTYPE = 71,
|
||||
|
||||
/**
|
||||
* Result too large or too small. The result of the function
|
||||
* is too large (overflow) or too small (underflow) to be
|
||||
* represented in the available space.
|
||||
*/
|
||||
ERANGE = 72,
|
||||
|
||||
/**
|
||||
* Read-only file system. An attempt was made to modify a file
|
||||
* or directory on a file system that is read-only.
|
||||
*/
|
||||
EROFS = 73,
|
||||
|
||||
/**
|
||||
* Invalid seek. An attempt was made to access the file offset
|
||||
* associated with a pipe or FIFO.
|
||||
*/
|
||||
ESPIPE = 74,
|
||||
|
||||
/**
|
||||
* No such process. No process can be found corresponding to that
|
||||
* specified by the given process ID.
|
||||
*/
|
||||
ESRCH = 75,
|
||||
|
||||
/**
|
||||
* Reserved.
|
||||
*/
|
||||
ESTALE = 76,
|
||||
|
||||
/**
|
||||
* STREAM ioctl() timeout. The timer set for a STREAMS ioctl() call
|
||||
* has expired. The cause of this error is device-specific and could
|
||||
* indicate either a hardware or software failure, or a timeout
|
||||
* value that is too short for the specific operation. The status
|
||||
* of the ioctl() operation is unspecified.
|
||||
*/
|
||||
ETIME = 77,
|
||||
|
||||
/**
|
||||
* Connection timed out. The connection to a remote machine has
|
||||
* timed out.
|
||||
* If the connection timed out during execution of the function that
|
||||
* reported this error (as opposed to timing out prior to the
|
||||
* function being called), it is unspecified whether the function
|
||||
* has completed some or all of the documented behavior associated
|
||||
* with a successful completion of the function.
|
||||
* or:
|
||||
* Operation timed out. The time limit associated with the operation
|
||||
* was exceeded before the operation completed.
|
||||
*/
|
||||
ETIMEDOUT = 78,
|
||||
|
||||
/**
|
||||
* Text file busy. An attempt was made to execute a pure-procedure
|
||||
* program that is currently open for writing, or an attempt has
|
||||
* been made to open for writing a pure-procedure program that
|
||||
* is being executed.
|
||||
*/
|
||||
ETXTBSY = 79,
|
||||
|
||||
/**
|
||||
* Operation would block. An operation on a socket marked as
|
||||
* non-blocking has encountered a situation such as no data available
|
||||
* that otherwise would have caused the function to suspend execution.
|
||||
*/
|
||||
EWOULDBLOCK = 80,
|
||||
|
||||
/**
|
||||
* Improper link. A link to a file on another file system was attempted.
|
||||
*/
|
||||
EXDEV = 81,
|
||||
|
||||
__ERRNO_MAX
|
||||
} KernelErrors;
|
||||
#include <bits/errno.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
@ -602,4 +34,4 @@ extern "C"
|
||||
|
||||
#define errno (*__errno_location())
|
||||
|
||||
#endif // !__FENNIX_API_ERRNO_H__
|
||||
#endif // _ERRNO_H
|
||||
|
@ -24,115 +24,11 @@ extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <fennix/syscalls.h>
|
||||
#include <bits/libc.h>
|
||||
#include <bits/types/timespec.h>
|
||||
|
||||
#define SIGNULL __SYS_SIGNULL
|
||||
#define SIGABRT __SYS_SIGABRT
|
||||
#define SIGALRM __SYS_SIGALRM
|
||||
#define SIGBUS __SYS_SIGBUS
|
||||
#define SIGCHLD __SYS_SIGCHLD
|
||||
#define SIGCONT __SYS_SIGCONT
|
||||
#define SIGFPE __SYS_SIGFPE
|
||||
#define SIGHUP __SYS_SIGHUP
|
||||
#define SIGILL __SYS_SIGILL
|
||||
#define SIGINT __SYS_SIGINT
|
||||
#define SIGKILL __SYS_SIGKILL
|
||||
#define SIGPIPE __SYS_SIGPIPE
|
||||
#define SIGQUIT __SYS_SIGQUIT
|
||||
#define SIGSEGV __SYS_SIGSEGV
|
||||
#define SIGSTOP __SYS_SIGSTOP
|
||||
#define SIGTERM __SYS_SIGTERM
|
||||
#define SIGTSTP __SYS_SIGTSTP
|
||||
#define SIGTTIN __SYS_SIGTTIN
|
||||
#define SIGTTOU __SYS_SIGTTOU
|
||||
#define SIGUSR1 __SYS_SIGUSR1
|
||||
#define SIGUSR2 __SYS_SIGUSR2
|
||||
#define SIGPOLL __SYS_SIGPOLL
|
||||
#define SIGPROF __SYS_SIGPROF
|
||||
#define SIGSYS __SYS_SIGSYS
|
||||
#define SIGTRAP __SYS_SIGTRAP
|
||||
#define SIGURG __SYS_SIGURG
|
||||
#define SIGVTALRM __SYS_SIGVTALRM
|
||||
#define SIGXCPU __SYS_SIGXCPU
|
||||
#define SIGXFSZ __SYS_SIGXFSZ
|
||||
#define SIGCOMP1 __SYS_SIGCOMP1
|
||||
#define SIGCOMP2 __SYS_SIGCOMP2
|
||||
#define SIGCOMP3 __SYS_SIGCOMP3
|
||||
#define SIGRTMIN __SYS_SIGRTMIN
|
||||
#define SIGRT_1 __SYS_SIGRT_1
|
||||
#define SIGRT_2 __SYS_SIGRT_2
|
||||
#define SIGRT_3 __SYS_SIGRT_3
|
||||
#define SIGRT_4 __SYS_SIGRT_4
|
||||
#define SIGRT_5 __SYS_SIGRT_5
|
||||
#define SIGRT_6 __SYS_SIGRT_6
|
||||
#define SIGRT_7 __SYS_SIGRT_7
|
||||
#define SIGRT_8 __SYS_SIGRT_8
|
||||
#define SIGRT_9 __SYS_SIGRT_9
|
||||
#define SIGRT_10 __SYS_SIGRT_10
|
||||
#define SIGRT_11 __SYS_SIGRT_11
|
||||
#define SIGRT_12 __SYS_SIGRT_12
|
||||
#define SIGRT_13 __SYS_SIGRT_13
|
||||
#define SIGRT_14 __SYS_SIGRT_14
|
||||
#define SIGRT_15 __SYS_SIGRT_15
|
||||
#define SIGRT_16 __SYS_SIGRT_16
|
||||
#define SIGRT_17 __SYS_SIGRT_17
|
||||
#define SIGRT_18 __SYS_SIGRT_18
|
||||
#define SIGRT_19 __SYS_SIGRT_19
|
||||
#define SIGRT_20 __SYS_SIGRT_20
|
||||
#define SIGRT_21 __SYS_SIGRT_21
|
||||
#define SIGRT_22 __SYS_SIGRT_22
|
||||
#define SIGRT_23 __SYS_SIGRT_23
|
||||
#define SIGRT_24 __SYS_SIGRT_24
|
||||
#define SIGRT_25 __SYS_SIGRT_25
|
||||
#define SIGRT_26 __SYS_SIGRT_26
|
||||
#define SIGRT_27 __SYS_SIGRT_27
|
||||
#define SIGRT_28 __SYS_SIGRT_28
|
||||
#define SIGRT_29 __SYS_SIGRT_29
|
||||
#define SIGRT_30 __SYS_SIGRT_30
|
||||
#define SIGRT_31 __SYS_SIGRT_31
|
||||
#define SIGRTMAX __SYS_SIGRTMAX
|
||||
#define SIGNAL_MAX __SYS_SIGNAL_MAX
|
||||
|
||||
#define SIG_TERM __SYS_SIG_TERM
|
||||
// #define SIG_IGN __SYS_SIG_IGN
|
||||
#define SIG_CORE __SYS_SIG_CORE
|
||||
#define SIG_STOP __SYS_SIG_STOP
|
||||
#define SIG_CONT __SYS_SIG_CONT
|
||||
|
||||
#define SIG_BLOCK __SYS_SIG_BLOCK
|
||||
#define SIG_UNBLOCK __SYS_SIG_UNBLOCK
|
||||
#define SIG_SETMASK __SYS_SIG_SETMASK
|
||||
|
||||
#define SA_NOCLDSTOP __SYS_SA_NOCLDSTOP
|
||||
#define SA_ONSTACK __SYS_SA_ONSTACK
|
||||
#define SA_RESETHAND __SYS_SA_RESETHAND
|
||||
#define SA_RESTART __SYS_SA_RESTART
|
||||
#define SA_SIGINFO __SYS_SA_SIGINFO
|
||||
#define SA_NOCLDWAIT __SYS_SA_NOCLDWAIT
|
||||
#define SA_NODEFER __SYS_SA_NODEFER
|
||||
|
||||
#define SS_ONSTACK
|
||||
#define SS_DISABLE
|
||||
|
||||
#define MINSIGSTKSZ
|
||||
#define SIGSTKSZ
|
||||
|
||||
#define SIG_ERR ((void (*)(int))__SYS_SIG_ERR)
|
||||
#define SIG_DFL ((void (*)(int))__SYS_SIG_DFL)
|
||||
#define SIG_IGN ((void (*)(int))__SYS_SIG_IGN)
|
||||
|
||||
#define SIGEV_NONE
|
||||
#define SIGEV_SIGNAL
|
||||
#define SIGEV_THREAD
|
||||
|
||||
typedef unsigned long sigset_t;
|
||||
|
||||
union sigval
|
||||
{
|
||||
int sival_int; /* Integer signal value. */
|
||||
void *sival_ptr; /* Pointer signal value. */
|
||||
};
|
||||
#include <bits/signal.h>
|
||||
#include <bits/types/signal.h>
|
||||
|
||||
typedef struct siginfo_t
|
||||
{
|
||||
@ -149,15 +45,6 @@ extern "C"
|
||||
union sigval si_value; /* Signal value. */
|
||||
} siginfo_t;
|
||||
|
||||
typedef struct sigevent
|
||||
{
|
||||
int sigev_notify; /* Notification type. */
|
||||
int sigev_signo; /* Signal number. */
|
||||
union sigval sigev_value; /* Signal value. */
|
||||
void (*sigev_notify_function)(union sigval); /* Notification function. */
|
||||
pthread_attr_t *sigev_notify_attributes; /* Notification attributes. */
|
||||
} sigevent;
|
||||
|
||||
struct sigaction
|
||||
{
|
||||
void (*sa_handler)(int); /* Pointer to a signal-catching function or one of the SIG_IGN or SIG_DFL. */
|
||||
|
@ -21,15 +21,26 @@
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
#include <bits/socket.h>
|
||||
|
||||
typedef uint32_t socklen_t;
|
||||
#ifndef __socklen_t_defined
|
||||
#define __socklen_t_defined
|
||||
typedef __UINT32_TYPE__ socklen_t;
|
||||
#endif
|
||||
|
||||
#ifndef __sa_family_t_defined
|
||||
#define __sa_family_t_defined
|
||||
typedef unsigned int sa_family_t;
|
||||
#endif
|
||||
|
||||
#ifndef __sockaddr_defined
|
||||
#define __sockaddr_defined
|
||||
struct sockaddr
|
||||
{
|
||||
sa_family_t sa_family;
|
||||
char sa_data[14];
|
||||
};
|
||||
#endif
|
||||
|
||||
#define _SS_MAXSIZE 128
|
||||
#define _SS_ALIGNSIZE (sizeof(int64_t))
|
||||
|
@ -30,10 +30,6 @@ extern "C"
|
||||
#define restrict __restrict__
|
||||
#endif // restrict
|
||||
|
||||
#ifndef export
|
||||
#define export __attribute__((__visibility__("default")))
|
||||
#endif // export
|
||||
|
||||
typedef long blkcnt_t;
|
||||
|
||||
typedef long blksize_t;
|
||||
|
@ -25,7 +25,7 @@ extern "C"
|
||||
|
||||
#include <bits/types/timespec.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <bits/types/signal.h>
|
||||
#include <locale.h>
|
||||
|
||||
typedef struct tm
|
||||
|
21
Userspace/libc/interpreter/CMakeLists.txt
Normal file
21
Userspace/libc/interpreter/CMakeLists.txt
Normal file
@ -0,0 +1,21 @@
|
||||
file(GLOB_RECURSE SYSDEPS_SOURCES ${SYSDEPS_PATH}/*.c ${SYSDEPS_GENERIC}/*.c)
|
||||
file(GLOB_RECURSE INTERPRETER_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.c")
|
||||
list(APPEND INTERPRETER_FILES ${SYSDEPS_SOURCES})
|
||||
|
||||
add_executable(ld.so ${INTERPRETER_FILES})
|
||||
|
||||
execute_process(COMMAND git rev-parse HEAD
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE GIT_COMMIT
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
if(GIT_COMMIT)
|
||||
add_compile_definitions(LIBC_GIT_COMMIT="${GIT_COMMIT}")
|
||||
endif()
|
||||
|
||||
add_compile_definitions(FENNIX_DYNAMIC_LOADER="1")
|
||||
|
||||
install(TARGETS ld.so DESTINATION lib)
|
||||
target_compile_options(ld.so PRIVATE -fvisibility=hidden -fPIC)
|
||||
target_link_options(ld.so PRIVATE -nostdlib -shared -fPIC -fPIE -fno-plt -Wl,-e,_dl_start)
|
@ -1,40 +0,0 @@
|
||||
default:
|
||||
$(error Do not run this Makefile directly!)
|
||||
|
||||
OBJECT_NAME := ld.so
|
||||
|
||||
OUTPUT_DIR=$(WORKSPACE_DIR)/out/lib/
|
||||
SYSROOT = --sysroot=$(WORKSPACE_DIR)/out/
|
||||
|
||||
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||
CXX_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||
OBJ = ${S_SOURCES:.S=.o} ${C_SOURCES:.c=.o} ${CXX_SOURCES:.cpp=.o}
|
||||
|
||||
CFLAGS := -fvisibility=hidden -fPIC -I$(WORKSPACE_DIR)/out/include -DLIBC_GIT_COMMIT='"$(shell git rev-parse HEAD)"'
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always
|
||||
endif
|
||||
|
||||
build: $(OBJECT_NAME)
|
||||
|
||||
$(OBJECT_NAME): $(OBJ)
|
||||
$(info Linking $@)
|
||||
$(CC) -nostdlib -shared -fPIC -fPIE -fno-plt -Wl,-soname,$(OBJECT_NAME) $(SYSROOT) $(OBJ) -o $(OBJECT_NAME)
|
||||
cp $(OBJECT_NAME) $(OUTPUT_DIR)$(OBJECT_NAME)
|
||||
|
||||
%.o: %.c
|
||||
$(info Compiling $<)
|
||||
$(CC) $(CFLAGS) -std=c17 -c $< -o $@
|
||||
|
||||
%.o: %.cpp
|
||||
$(info Compiling $<)
|
||||
$(CC) $(CFLAGS) -std=c++20 -c $< -o $@
|
||||
|
||||
%.o: %.S
|
||||
$(info Compiling $<)
|
||||
$(AS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(OBJ) $(OBJECT_NAME)
|
@ -15,8 +15,9 @@
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <fennix/syscalls.h>
|
||||
#include <bits/libc.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
@ -39,7 +40,7 @@ MemoryBlock *memory_pool = NULL;
|
||||
void *request_page(size_t size)
|
||||
{
|
||||
size_t aligned_size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
|
||||
void *addr = (void *)call_mmap(NULL, aligned_size, __SYS_PROT_READ | __SYS_PROT_WRITE, __SYS_MAP_ANONYMOUS | __SYS_MAP_PRIVATE, -1, 0);
|
||||
void *addr = (void *)sysdep(MemoryMap)(NULL, aligned_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
||||
if ((intptr_t)addr < 0)
|
||||
return NULL;
|
||||
return addr;
|
||||
@ -48,7 +49,7 @@ void *request_page(size_t size)
|
||||
void free_page(void *addr, size_t size)
|
||||
{
|
||||
size_t aligned_size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
|
||||
call_munmap(addr, aligned_size);
|
||||
sysdep(MemoryUnmap)(addr, aligned_size);
|
||||
}
|
||||
|
||||
MemoryBlock *allocate_block(size_t slot_size)
|
||||
|
@ -15,7 +15,7 @@
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <fennix/syscalls.h>
|
||||
#include <bits/libc.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
@ -15,11 +15,14 @@
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <fennix/syscalls.h>
|
||||
#include <bits/libc.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <inttypes.h>
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "elf.h"
|
||||
@ -167,9 +170,15 @@ __attribute__((noinline)) void *_dl_fixup(ElfInfo *Info, long RelIndex)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef __fennix__
|
||||
#include <fennix/syscalls.h>
|
||||
#endif
|
||||
|
||||
int _dl_preload()
|
||||
{
|
||||
#ifdef __fennix__
|
||||
call_api_version(0);
|
||||
#endif
|
||||
|
||||
/* TODO: Do aditional checks for miscellaneous things */
|
||||
|
||||
@ -353,16 +362,16 @@ void ProcessNeededLibraries(Elf_Dyn *elem, ElfInfo *Info)
|
||||
strcpy(fullLibPath, "/lib/");
|
||||
strcat(fullLibPath, libPath);
|
||||
/* TODO: more checks and also check environment variables */
|
||||
if (call_access(fullLibPath, __SYS_F_OK) != 0)
|
||||
if (sysdep(Access)(fullLibPath, F_OK) != 0)
|
||||
{
|
||||
printf("dl: Can't access %s\n", fullLibPath);
|
||||
return;
|
||||
}
|
||||
|
||||
int fd = call_open(fullLibPath, __SYS_O_RDONLY, 0644);
|
||||
int fd = sysdep(Open)(fullLibPath, O_RDONLY, 0644);
|
||||
int status = LoadElf(fd, fullLibPath, &info);
|
||||
elem->d_un.d_ptr = (uintptr_t)info; /* if LoadElf fails, info will still be NULL */
|
||||
call_close(fd);
|
||||
sysdep(Close)(fd);
|
||||
if (status < 0) /* announce that LoadElf failed */
|
||||
printf("dl: Can't load %s\n", fullLibPath);
|
||||
}
|
||||
@ -431,7 +440,7 @@ int LoadElfPhdrDYN(int fd, ElfInfo *Info)
|
||||
|
||||
for (Elf_Half i = 0; i < header.e_phnum; i++)
|
||||
{
|
||||
ssize_t read = call_pread(fd, &phdr, sizeof(Elf_Phdr), header.e_phoff + (header.e_phentsize * i));
|
||||
ssize_t read = sysdep(PRead)(fd, &phdr, sizeof(Elf_Phdr), header.e_phoff + (header.e_phentsize * i));
|
||||
if (read != sizeof(Elf_Phdr))
|
||||
{
|
||||
printf("dl: Can't read program header %d\n", i);
|
||||
@ -450,23 +459,23 @@ int LoadElfPhdrDYN(int fd, ElfInfo *Info)
|
||||
|
||||
int mmapProt = 0;
|
||||
if (phdr.p_flags & PF_X)
|
||||
mmapProt |= __SYS_PROT_EXEC;
|
||||
mmapProt |= PROT_EXEC;
|
||||
if (phdr.p_flags & PF_W)
|
||||
mmapProt |= __SYS_PROT_WRITE;
|
||||
mmapProt |= PROT_WRITE;
|
||||
if (phdr.p_flags & PF_R)
|
||||
mmapProt |= __SYS_PROT_READ;
|
||||
mmapProt |= PROT_READ;
|
||||
|
||||
off_t sectionOffset = ALIGN_DOWN(phdr.p_vaddr, phdr.p_align);
|
||||
size_t sectionSize = ALIGN_UP(phdr.p_memsz + (phdr.p_vaddr - sectionOffset), phdr.p_align);
|
||||
uintptr_t section = call_mmap(base + sectionOffset,
|
||||
sectionSize, mmapProt,
|
||||
__SYS_MAP_ANONYMOUS | __SYS_MAP_PRIVATE | __SYS_MAP_FIXED,
|
||||
-1, 0);
|
||||
uintptr_t section = (uintptr_t)sysdep(MemoryMap)((void *)(base + sectionOffset),
|
||||
sectionSize, mmapProt,
|
||||
MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED,
|
||||
-1, 0);
|
||||
sectionOffset = phdr.p_vaddr - ALIGN_DOWN(phdr.p_vaddr, phdr.p_align);
|
||||
|
||||
if (phdr.p_filesz > 0)
|
||||
{
|
||||
ssize_t read = call_pread(fd, section + sectionOffset, phdr.p_filesz, phdr.p_offset);
|
||||
ssize_t read = sysdep(PRead)(fd, (void *)(section + sectionOffset), phdr.p_filesz, phdr.p_offset);
|
||||
if (read != phdr.p_filesz)
|
||||
{
|
||||
printf("dl: Can't read segment %d in PT_LOAD\n", i);
|
||||
@ -495,15 +504,15 @@ int LoadElfPhdrDYN(int fd, ElfInfo *Info)
|
||||
{
|
||||
int mmapProt = 0;
|
||||
if (phdr.p_flags & PF_X)
|
||||
mmapProt |= __SYS_PROT_EXEC;
|
||||
mmapProt |= PROT_EXEC;
|
||||
if (phdr.p_flags & PF_W)
|
||||
mmapProt |= __SYS_PROT_WRITE;
|
||||
mmapProt |= PROT_WRITE;
|
||||
if (phdr.p_flags & PF_R)
|
||||
mmapProt |= __SYS_PROT_READ;
|
||||
mmapProt |= PROT_READ;
|
||||
|
||||
dynamicTable = (Elf_Dyn *)call_mmap(0, ALIGN_UP(phdr.p_memsz, phdr.p_align),
|
||||
mmapProt, __SYS_MAP_ANONYMOUS | __SYS_MAP_PRIVATE | __SYS_MAP_FIXED,
|
||||
-1, 0);
|
||||
dynamicTable = (Elf_Dyn *)sysdep(MemoryMap)(0, ALIGN_UP(phdr.p_memsz, phdr.p_align),
|
||||
mmapProt, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED,
|
||||
-1, 0);
|
||||
|
||||
if ((intptr_t)dynamicTable <= 0)
|
||||
{
|
||||
@ -511,7 +520,7 @@ int LoadElfPhdrDYN(int fd, ElfInfo *Info)
|
||||
return (int)(uintptr_t)dynamicTable;
|
||||
}
|
||||
|
||||
read = call_pread(fd, dynamicTable, phdr.p_memsz, phdr.p_offset);
|
||||
read = sysdep(PRead)(fd, dynamicTable, phdr.p_memsz, phdr.p_offset);
|
||||
if (read != phdr.p_memsz)
|
||||
{
|
||||
printf("dl: Can't read PT_DYNAMIC\n");
|
||||
@ -598,7 +607,7 @@ int LoadElf(int fd, char *Path, ElfInfo **Out)
|
||||
}
|
||||
|
||||
Elf_Ehdr header;
|
||||
call_pread(fd, &header, sizeof(Elf_Ehdr), 0);
|
||||
sysdep(PRead)(fd, &header, sizeof(Elf_Ehdr), 0);
|
||||
|
||||
int status = CheckElfEhdr(&header, Path);
|
||||
if (status != 0)
|
||||
@ -606,11 +615,11 @@ int LoadElf(int fd, char *Path, ElfInfo **Out)
|
||||
|
||||
info = AllocateLib();
|
||||
info->Header = header;
|
||||
info->Path = (char *)call_mmap(0,
|
||||
ALIGN_UP(strlen(Path) + 1, 0x1000 /* TODO: get page size from kernel */),
|
||||
__SYS_PROT_READ,
|
||||
__SYS_MAP_ANONYMOUS | __SYS_MAP_PRIVATE,
|
||||
-1, 0);
|
||||
info->Path = (char *)sysdep(MemoryMap)(0,
|
||||
ALIGN_UP(strlen(Path) + 1, 0x1000 /* TODO: get page size from kernel */),
|
||||
PROT_READ,
|
||||
MAP_ANONYMOUS | MAP_PRIVATE,
|
||||
-1, 0);
|
||||
if ((intptr_t)info->Path <= 0)
|
||||
{
|
||||
printf("dl: Can't allocate memory for path\n");
|
||||
@ -648,7 +657,7 @@ int LoadElf(int fd, char *Path, ElfInfo **Out)
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
call_munmap((uintptr_t)info->Path, ALIGN_UP(strlen(Path) + 1, 0x1000));
|
||||
sysdep(MemoryUnmap)((void *)info->Path, ALIGN_UP(strlen(Path) + 1, 0x1000));
|
||||
FreeLib(info);
|
||||
return status;
|
||||
}
|
||||
@ -956,18 +965,18 @@ int _dl_main(int argc, char *argv[], char *envp[])
|
||||
{
|
||||
char *path = argv[0];
|
||||
ElfInfo *info = NULL;
|
||||
if (call_access(path, __SYS_F_OK) < 0)
|
||||
if (sysdep(Access)(path, F_OK) < 0)
|
||||
{
|
||||
printf("dl: Can't access file %s\n", path);
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
int fd = call_open(path, __SYS_O_RDONLY, 0644);
|
||||
int fd = sysdep(Open)(path, O_RDONLY, 0644);
|
||||
int status = LoadElf(fd, path, &info);
|
||||
if (status < 0)
|
||||
{
|
||||
printf("%s: Can't load ELF file\n", path);
|
||||
call_close(fd);
|
||||
sysdep(Close)(fd);
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -975,11 +984,11 @@ int _dl_main(int argc, char *argv[], char *envp[])
|
||||
if (status < 0)
|
||||
{
|
||||
printf("%s: Can't relocate ELF file\n", path);
|
||||
call_close(fd);
|
||||
sysdep(Close)(fd);
|
||||
return status;
|
||||
}
|
||||
|
||||
call_close(fd);
|
||||
sysdep(Close)(fd);
|
||||
Elf_Addr entry = info->BaseAddress + info->Header.e_entry;
|
||||
return ((int (*)(int, char *[], char *[]))entry)(argc, argv, envp);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* nanoprintf v0.5.3: a tiny embeddable printf replacement written in C.
|
||||
/* nanoprintf v0.5.4: a tiny embeddable printf replacement written in C.
|
||||
https://github.com/charlesnicholson/nanoprintf
|
||||
charles.nicholson+nanoprintf@gmail.com
|
||||
dual-licensed under 0bsd and unlicense, take your pick. see eof for details. */
|
||||
@ -336,6 +336,7 @@ static int npf_parse_format_spec(char const *format, npf_format_spec_t *out_spec
|
||||
}
|
||||
|
||||
#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1
|
||||
out_spec->field_width = 0;
|
||||
out_spec->field_width_opt = NPF_FMT_SPEC_OPT_NONE;
|
||||
if (*cur == '*')
|
||||
{
|
||||
@ -344,7 +345,6 @@ static int npf_parse_format_spec(char const *format, npf_format_spec_t *out_spec
|
||||
}
|
||||
else
|
||||
{
|
||||
out_spec->field_width = 0;
|
||||
while ((*cur >= '0') && (*cur <= '9'))
|
||||
{
|
||||
out_spec->field_width_opt = NPF_FMT_SPEC_OPT_LITERAL;
|
||||
|
@ -17,7 +17,8 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <fennix/syscalls.h>
|
||||
#include <bits/libc.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "elf.h"
|
||||
#include "misc.h"
|
||||
@ -31,7 +32,7 @@ void flush_buffer()
|
||||
{
|
||||
if (print_buffer_offset > 0)
|
||||
{
|
||||
call_write(1, print_buffer, print_buffer_offset);
|
||||
sysdep(Write)(1, print_buffer, print_buffer_offset);
|
||||
print_buffer_offset = 0;
|
||||
}
|
||||
}
|
||||
@ -45,11 +46,11 @@ void print_wrapper(int c, void *)
|
||||
|
||||
void __init_print_buffer()
|
||||
{
|
||||
print_buffer = (char *)call_mmap(0,
|
||||
0x1000,
|
||||
__SYS_PROT_READ | __SYS_PROT_WRITE,
|
||||
__SYS_MAP_PRIVATE | __SYS_MAP_ANONYMOUS,
|
||||
-1, 0);
|
||||
print_buffer = (char *)sysdep(MemoryMap)(0,
|
||||
0x1000,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
-1, 0);
|
||||
print_buffer_size = 0x1000;
|
||||
print_buffer_offset = 0;
|
||||
}
|
||||
@ -58,7 +59,7 @@ void __fini_print_buffer()
|
||||
{
|
||||
flush_buffer();
|
||||
if (print_buffer != NULL)
|
||||
call_munmap(print_buffer, 0x1000);
|
||||
sysdep(MemoryUnmap)(print_buffer, 0x1000);
|
||||
print_buffer = NULL;
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <fennix/syscalls.h>
|
||||
#include <bits/libc.h>
|
||||
|
||||
// const char __interp[] __attribute__((section(".interp"))) = "/boot/fennix.elf";
|
||||
|
||||
@ -97,54 +97,11 @@ const struct
|
||||
void __init_print_buffer();
|
||||
void __fini_print_buffer();
|
||||
|
||||
__attribute__((naked, used, no_stack_protector)) void _start()
|
||||
{
|
||||
#if defined(__amd64__)
|
||||
__asm__(
|
||||
"xorq %rbp, %rbp\n" /* Clear rbp */
|
||||
|
||||
"push %rdi\n"
|
||||
"push %rsi\n"
|
||||
"push %rdx\n"
|
||||
"push %rcx\n"
|
||||
"push %r8\n"
|
||||
"push %r9\n"
|
||||
|
||||
"call __init_print_buffer\n" /* Call __init_print_buffer */
|
||||
"call _dl_preload\n" /* Call _dl_preload */
|
||||
"movl %eax, %edi\n" /* Move return value to edi */
|
||||
"cmp $0, %edi\n" /* Check if return value is 0 */
|
||||
"jne _exit\n" /* If not, jump to _exit */
|
||||
|
||||
"pop %r9\n"
|
||||
"pop %r8\n"
|
||||
"pop %rcx\n"
|
||||
"pop %rdx\n"
|
||||
"pop %rsi\n"
|
||||
"pop %rdi\n"
|
||||
|
||||
"call main\n" /* Call _dl_main */
|
||||
"movl %eax, %edi\n" /* Move return value to edi */
|
||||
"call _exit\n"); /* Call _exit */
|
||||
#elif defined(__i386__)
|
||||
#warning "i386 _start not implemented"
|
||||
#elif defined(__arm__)
|
||||
#warning "arm _start not implemented"
|
||||
#elif defined(__aarch64__)
|
||||
#warning "aarch64 _start not implemented"
|
||||
#else
|
||||
#error "Unsupported architecture"
|
||||
#endif
|
||||
}
|
||||
|
||||
__attribute__((no_stack_protector)) _Noreturn void _exit(int status)
|
||||
{
|
||||
__fini_print_buffer();
|
||||
call_exit(status);
|
||||
/* At this point, the program *SHOULD* have exited. */
|
||||
#if defined(__amd64__) || defined(__i386__)
|
||||
__asm__("ud2\n");
|
||||
#endif
|
||||
sysdep(Exit)(status);
|
||||
/* At this point, the program *SHOULD* have exited. */
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
|
5
Userspace/libc/libs/CMakeLists.txt
Normal file
5
Userspace/libc/libs/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(FennixStandardLibraries)
|
||||
|
||||
add_subdirectory(libm)
|
||||
add_subdirectory(libstdc++)
|
15
Userspace/libc/libs/libm/CMakeLists.txt
Normal file
15
Userspace/libc/libs/libm/CMakeLists.txt
Normal file
@ -0,0 +1,15 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(FennixMathLibrary)
|
||||
|
||||
set(SOURCES libm.c)
|
||||
|
||||
add_library(m STATIC ${SOURCES})
|
||||
add_library(m_shared SHARED ${SOURCES})
|
||||
|
||||
target_link_options(m_shared PRIVATE -nostdlib)
|
||||
set_target_properties(m_shared PROPERTIES OUTPUT_NAME "m")
|
||||
|
||||
install(TARGETS m m_shared
|
||||
ARCHIVE DESTINATION lib
|
||||
LIBRARY DESTINATION lib
|
||||
PUBLIC_HEADER DESTINATION include)
|
15
Userspace/libc/libs/libstdc++/CMakeLists.txt
Normal file
15
Userspace/libc/libs/libstdc++/CMakeLists.txt
Normal file
@ -0,0 +1,15 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(FennixStandardC++Library)
|
||||
|
||||
set(SOURCES libstdc++.cpp)
|
||||
|
||||
add_library(stdc++ STATIC ${SOURCES})
|
||||
add_library(stdc++_shared SHARED ${SOURCES})
|
||||
|
||||
target_link_options(stdc++_shared PRIVATE -nostdlib)
|
||||
set_target_properties(stdc++_shared PROPERTIES OUTPUT_NAME "stdc++")
|
||||
|
||||
install(TARGETS stdc++ stdc++_shared
|
||||
ARCHIVE DESTINATION lib
|
||||
LIBRARY DESTINATION lib
|
||||
PUBLIC_HEADER DESTINATION include)
|
18
Userspace/libc/runtime/CMakeLists.txt
Normal file
18
Userspace/libc/runtime/CMakeLists.txt
Normal file
@ -0,0 +1,18 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(FennixRuntime)
|
||||
|
||||
if(NOT DEFINED TARGET_OS)
|
||||
message(FATAL_ERROR "TARGET_OS is not set")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED TARGET_ARCH)
|
||||
message(FATAL_ERROR "TARGET_ARCH is not set")
|
||||
endif()
|
||||
|
||||
set(RUNTIME_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${TARGET_OS}/${TARGET_ARCH}")
|
||||
|
||||
if(NOT EXISTS "${RUNTIME_DIR}/CMakeLists.txt")
|
||||
message(FATAL_ERROR "No runtime support for ${TARGET_OS}/${TARGET_ARCH}")
|
||||
endif()
|
||||
|
||||
add_subdirectory(${RUNTIME_DIR})
|
@ -1,27 +0,0 @@
|
||||
default:
|
||||
$(error Do not run this Makefile directly!)
|
||||
|
||||
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||
CXX_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||
OBJ = ${S_SOURCES:.S=.o} ${C_SOURCES:.c=.o} ${CXX_SOURCES:.cpp=.o}
|
||||
|
||||
CRTBEGIN_PATH = $(shell $(CC) -print-file-name=crtbegin.o)
|
||||
CRTEND_PATH = $(shell $(CC) -print-file-name=crtend.o)
|
||||
CRTI_PATH = $(shell $(CC) -print-file-name=crti.o)
|
||||
CRTN_PATH = $(shell $(CC) -print-file-name=crtn.o)
|
||||
|
||||
build: $(OBJ)
|
||||
cp $^ ../../out/lib/
|
||||
cp $(CRTBEGIN_PATH) $(CRTEND_PATH) $(CRTI_PATH) $(CRTN_PATH) $(WORKSPACE_DIR)/out/lib/
|
||||
|
||||
%.o: %.c
|
||||
$(info Compiling $<)
|
||||
$(CC) -nostdlib -std=c17 -DLIBC_GIT_COMMIT='"$(shell git rev-parse HEAD)"' -c $< -o $@
|
||||
|
||||
%.o: %.S
|
||||
$(info Compiling $<)
|
||||
$(AS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(OBJ)
|
34
Userspace/libc/runtime/fennix/amd64/CMakeLists.txt
Normal file
34
Userspace/libc/runtime/fennix/amd64/CMakeLists.txt
Normal file
@ -0,0 +1,34 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(FennixRuntime_${TARGET_OS}_${TARGET_ARCH})
|
||||
|
||||
find_program(COMPILER_PATH NAMES $ENV{CC} gcc REQUIRED)
|
||||
|
||||
set(LIB_OUTPUT_DIR "${CMAKE_INSTALL_PREFIX}/lib")
|
||||
file(MAKE_DIRECTORY ${LIB_OUTPUT_DIR})
|
||||
|
||||
add_custom_target(copy_crt_files ALL
|
||||
COMMAND ${COMPILER_PATH} -print-file-name=libgcc.a | xargs cp -t ${LIB_OUTPUT_DIR}
|
||||
COMMAND ${COMPILER_PATH} -print-file-name=crtbegin.o | xargs cp -t ${LIB_OUTPUT_DIR}
|
||||
COMMAND ${COMPILER_PATH} -print-file-name=crtend.o | xargs cp -t ${LIB_OUTPUT_DIR}
|
||||
COMMAND ${COMPILER_PATH} -print-file-name=crti.o | xargs cp -t ${LIB_OUTPUT_DIR}
|
||||
COMMAND ${COMPILER_PATH} -print-file-name=crtn.o | xargs cp -t ${LIB_OUTPUT_DIR}
|
||||
COMMENT "Copying CRT files"
|
||||
)
|
||||
|
||||
file(GLOB CRT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.c")
|
||||
set(OBJECT_FILES "")
|
||||
foreach(source ${CRT_SOURCES})
|
||||
get_filename_component(name ${source} NAME_WE)
|
||||
set(obj "${CMAKE_BINARY_DIR}/${name}.o")
|
||||
add_custom_command(
|
||||
OUTPUT ${obj}
|
||||
COMMAND ${COMPILER_PATH} -c ${source} -o ${obj}
|
||||
DEPENDS ${source}
|
||||
)
|
||||
list(APPEND OBJECT_FILES ${obj})
|
||||
endforeach()
|
||||
|
||||
if(OBJECT_FILES)
|
||||
add_custom_target(crt_objects ALL DEPENDS ${OBJECT_FILES})
|
||||
install(FILES ${OBJECT_FILES} DESTINATION lib)
|
||||
endif()
|
43
Userspace/libc/runtime/linux/x86_64/CMakeLists.txt
Normal file
43
Userspace/libc/runtime/linux/x86_64/CMakeLists.txt
Normal file
@ -0,0 +1,43 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(FennixRuntime_${TARGET_OS}_${TARGET_ARCH})
|
||||
|
||||
find_program(COMPILER_PATH NAMES $ENV{CC} gcc REQUIRED)
|
||||
|
||||
set(BUILD_OUTPUT_DIR "${CMAKE_BINARY_DIR}/lib")
|
||||
set(INSTALL_OUTPUT_DIR "${CMAKE_INSTALL_PREFIX}/lib")
|
||||
|
||||
file(MAKE_DIRECTORY ${BUILD_OUTPUT_DIR})
|
||||
|
||||
execute_process(COMMAND ${COMPILER_PATH} -print-file-name=crtbegin.o OUTPUT_VARIABLE CRTBEGIN_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND ${COMPILER_PATH} -print-file-name=crtend.o OUTPUT_VARIABLE CRTEND_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND ${COMPILER_PATH} -print-file-name=crti.o OUTPUT_VARIABLE CRTI_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND ${COMPILER_PATH} -print-file-name=crtn.o OUTPUT_VARIABLE CRTN_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
add_custom_target(copy_crt_files ALL
|
||||
COMMAND cp ${CRTBEGIN_PATH} ${CRTEND_PATH} ${CRTI_PATH} ${CRTN_PATH} ${BUILD_OUTPUT_DIR}
|
||||
COMMENT "Copying CRT files"
|
||||
)
|
||||
|
||||
file(GLOB CRT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.c")
|
||||
set(OBJECT_FILES "")
|
||||
|
||||
foreach(source ${CRT_SOURCES})
|
||||
get_filename_component(name ${source} NAME_WE)
|
||||
set(obj "${BUILD_OUTPUT_DIR}/${name}.o")
|
||||
add_custom_command(
|
||||
OUTPUT ${obj}
|
||||
COMMAND ${COMPILER_PATH} -c ${source} -o ${obj}
|
||||
DEPENDS ${source}
|
||||
)
|
||||
list(APPEND OBJECT_FILES ${obj})
|
||||
endforeach()
|
||||
|
||||
if(OBJECT_FILES)
|
||||
add_custom_target(crt_objects ALL DEPENDS ${OBJECT_FILES})
|
||||
endif()
|
||||
|
||||
install(FILES ${BUILD_OUTPUT_DIR}/crtbegin.o ${BUILD_OUTPUT_DIR}/crtend.o ${BUILD_OUTPUT_DIR}/crti.o ${BUILD_OUTPUT_DIR}/crtn.o
|
||||
DESTINATION lib
|
||||
)
|
||||
|
||||
install(FILES ${OBJECT_FILES} DESTINATION lib)
|
33
Userspace/libc/src/CMakeLists.txt
Normal file
33
Userspace/libc/src/CMakeLists.txt
Normal file
@ -0,0 +1,33 @@
|
||||
file(GLOB_RECURSE SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.c ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
|
||||
file(GLOB_RECURSE SYSDEPS_SOURCES ${SYSDEPS_PATH}/*.c ${SYSDEPS_GENERIC}/*.c ${SYSDEPS_PATH}/*.cpp ${SYSDEPS_GENERIC}/*.cpp)
|
||||
list(APPEND SRC_FILES ${SYSDEPS_SOURCES})
|
||||
|
||||
add_library(libc_obj OBJECT ${SRC_FILES})
|
||||
set_target_properties(libc_obj PROPERTIES POSITION_INDEPENDENT_CODE 1)
|
||||
|
||||
message(STATUS "Adding sysdeps sources: ${SYSDEPS_SOURCES}")
|
||||
|
||||
add_library(libc_shared SHARED $<TARGET_OBJECTS:libc_obj>)
|
||||
set_target_properties(libc_shared PROPERTIES OUTPUT_NAME "c")
|
||||
target_compile_definitions(libc_shared PRIVATE PROGRAM_VERSION="${PROJECT_VERSION}")
|
||||
|
||||
execute_process(
|
||||
COMMAND git rev-parse HEAD
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE GIT_COMMIT
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
if(GIT_COMMIT)
|
||||
target_compile_definitions(libc_shared PRIVATE LIBC_GIT_COMMIT="${GIT_COMMIT}")
|
||||
endif()
|
||||
|
||||
target_compile_options(libc_shared PRIVATE -fvisibility=hidden -fPIC)
|
||||
target_link_options(libc_shared PRIVATE -nostdlib -shared -fPIC -fPIE -e _start -Wl,-soname,libc.so -lgcc)
|
||||
|
||||
add_library(libc_static STATIC $<TARGET_OBJECTS:libc_obj>)
|
||||
set_target_properties(libc_static PROPERTIES OUTPUT_NAME "c")
|
||||
target_compile_options(libc_static PRIVATE -fvisibility=hidden -fPIC)
|
||||
|
||||
install(TARGETS libc_shared libc_static DESTINATION lib)
|
@ -1,48 +0,0 @@
|
||||
default:
|
||||
$(error Do not run this Makefile directly!)
|
||||
|
||||
DYNAMIC_NAME := libc.so
|
||||
STATIC_NAME := libc.a
|
||||
|
||||
OUTPUT_DIR=$(WORKSPACE_DIR)/out/lib/
|
||||
SYSROOT = --sysroot=$(WORKSPACE_DIR)/out/
|
||||
|
||||
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||
CXX_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||
OBJ = ${S_SOURCES:.S=.o} ${C_SOURCES:.c=.o} ${CXX_SOURCES:.cpp=.o}
|
||||
|
||||
CFLAGS := -fvisibility=hidden -fPIC -I../include -I$(WORKSPACE_DIR)/out/include -DLIBC_GIT_COMMIT='"$(shell git rev-parse HEAD)"'
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always
|
||||
endif
|
||||
|
||||
build: $(DYNAMIC_NAME) $(STATIC_NAME)
|
||||
|
||||
.PHONY: $(DYNAMIC_NAME) $(STATIC_NAME)
|
||||
|
||||
$(DYNAMIC_NAME): $(OBJ)
|
||||
$(info Linking $@)
|
||||
$(CC) -nostdlib -shared -fPIC -fPIE -e _start -Wl,-soname,$(DYNAMIC_NAME) $(SYSROOT) $(OBJ) -o $(DYNAMIC_NAME) -lgcc
|
||||
cp $(DYNAMIC_NAME) $(OUTPUT_DIR)$(DYNAMIC_NAME)
|
||||
|
||||
$(STATIC_NAME): $(OBJ)
|
||||
$(info Linking $@)
|
||||
$(AR) -rcs $(STATIC_NAME) $(OBJ)
|
||||
cp $(STATIC_NAME) $(OUTPUT_DIR)$(STATIC_NAME)
|
||||
|
||||
%.o: %.c
|
||||
$(info Compiling $<)
|
||||
$(CC) $(CFLAGS) -std=c17 -c $< -o $@
|
||||
|
||||
%.o: %.cpp
|
||||
$(info Compiling $<)
|
||||
$(CC) $(CFLAGS) -std=c++20 -c $< -o $@
|
||||
|
||||
%.o: %.S
|
||||
$(info Compiling $<)
|
||||
$(AS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(OBJ) $(DYNAMIC_NAME) $(STATIC_NAME)
|
@ -15,8 +15,7 @@
|
||||
along with Fennix Userspace. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <fennix/syscalls.h>
|
||||
|
||||
#include <bits/libc.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int __init_pthread(void);
|
||||
@ -34,7 +33,7 @@ __attribute__((visibility("default"))) void _exit(int Code)
|
||||
{
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
call_exit(Code);
|
||||
sysdep(Exit)(Code);
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
@ -15,8 +15,6 @@
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../runtime/crt1.c"
|
||||
|
||||
const char __interp[] __attribute__((section(".interp"))) = "/lib/ld.so";
|
||||
|
||||
#ifndef LIBC_GIT_COMMIT
|
||||
@ -47,6 +45,23 @@ const char __interp[] __attribute__((section(".interp"))) = "/lib/ld.so";
|
||||
CONVERT_TO_BYTE(hex[36], hex[37]), \
|
||||
CONVERT_TO_BYTE(hex[38], hex[39])}
|
||||
|
||||
typedef struct Elf_Nhdr
|
||||
{
|
||||
__UINT32_TYPE__ n_namesz;
|
||||
__UINT32_TYPE__ n_descsz;
|
||||
__UINT32_TYPE__ n_type;
|
||||
char n_name[];
|
||||
} __attribute__((packed)) Elf_Nhdr;
|
||||
|
||||
/* These are declared in GNU ld */
|
||||
enum
|
||||
{
|
||||
NT_FNX_ABI_TAG = 1,
|
||||
NT_FNX_VERSION = 2,
|
||||
NT_FNX_BUILD_ID = 3,
|
||||
NT_FNX_ARCH = 4
|
||||
};
|
||||
|
||||
const struct
|
||||
{
|
||||
Elf_Nhdr header;
|
||||
|
@ -15,6 +15,7 @@
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <bits/libc.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
@ -15,10 +15,15 @@
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <bits/libc.h>
|
||||
#include <sys/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef EOK
|
||||
#define EOK 0
|
||||
#endif
|
||||
|
||||
__iptr __check_errno(__iptr status, __iptr err)
|
||||
{
|
||||
if ((int)status >= EOK)
|
||||
@ -37,9 +42,6 @@ export char *strerror(int errnum)
|
||||
if (errnum < 0)
|
||||
errnum = -errnum;
|
||||
|
||||
if (errnum > __ERRNO_MAX)
|
||||
return (char *)"Not a valid error number";
|
||||
|
||||
switch (errnum)
|
||||
{
|
||||
case EOK:
|
||||
|
@ -15,8 +15,8 @@
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <bits/libc.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
@ -37,7 +37,7 @@ export int open(const char *path, int oflag, ...)
|
||||
mode = va_arg(args, mode_t);
|
||||
va_end(args);
|
||||
}
|
||||
return __check_errno(call_open(path, oflag, mode), -1);
|
||||
return __check_errno(sysdep(Open)(path, oflag, mode), -1);
|
||||
}
|
||||
|
||||
export int openat(int fd, const char *path, int oflag, ...);
|
||||
|
@ -15,6 +15,7 @@
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <bits/libc.h>
|
||||
#include <sys/types.h>
|
||||
#include <fenv.h>
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <float.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <bits/libc.h>
|
||||
#include <fenv.h>
|
||||
|
||||
export int signgam;
|
||||
|
@ -15,6 +15,7 @@
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <bits/libc.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
@ -15,13 +15,14 @@
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <bits/libc.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
||||
export int kill(pid_t pid, int sig)
|
||||
{
|
||||
return call_kill(pid, sig);
|
||||
return sysdep(Kill)(pid, sig);
|
||||
}
|
||||
|
||||
export int killpg(pid_t, int);
|
||||
|
@ -19,7 +19,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fennix/syscalls.h>
|
||||
#include <bits/libc.h>
|
||||
#include <fcntl.h>
|
||||
#include "../print/printf.h"
|
||||
|
||||
struct _IO_FILE *_i_open_files[256];
|
||||
@ -74,7 +75,7 @@ export int fclose(FILE *stream)
|
||||
if (stream->buffer)
|
||||
free(stream->buffer);
|
||||
|
||||
call_close(stream->fd);
|
||||
sysdep(Close)(stream->fd);
|
||||
_i_open_files[stream->fd] = NULL;
|
||||
free(stream);
|
||||
return 0;
|
||||
@ -105,7 +106,7 @@ export int fflush(FILE *stream)
|
||||
{
|
||||
if (stream->buffer_pos > 0)
|
||||
{
|
||||
ssize_t written = call_write(stream->fd, stream->buffer, stream->buffer_pos);
|
||||
ssize_t written = sysdep(Write)(stream->fd, stream->buffer, stream->buffer_pos);
|
||||
if (written < 0)
|
||||
{
|
||||
stream->error = 1;
|
||||
@ -129,7 +130,7 @@ export int fgetc(FILE *stream)
|
||||
|
||||
if (stream->buffer_pos >= stream->buffer_size)
|
||||
{
|
||||
int res = call_read(stream->fd, stream->buffer, 4096);
|
||||
int res = sysdep(Read)(stream->fd, stream->buffer, 4096);
|
||||
if (res <= 0)
|
||||
{
|
||||
if (res == 0)
|
||||
@ -180,33 +181,33 @@ export FILE *fopen(const char *restrict pathname, const char *restrict mode)
|
||||
mode_t perm = 0;
|
||||
|
||||
if (strcmp(mode, "r") == 0)
|
||||
flags = __SYS_O_RDONLY;
|
||||
flags = O_RDONLY;
|
||||
else if (strcmp(mode, "r+") == 0)
|
||||
flags = __SYS_O_RDWR;
|
||||
flags = O_RDWR;
|
||||
else if (strcmp(mode, "w") == 0)
|
||||
{
|
||||
flags = __SYS_O_WRONLY | __SYS_O_CREAT | __SYS_O_TRUNC;
|
||||
flags = O_WRONLY | O_CREAT | O_TRUNC;
|
||||
perm = 0644;
|
||||
}
|
||||
else if (strcmp(mode, "w+") == 0)
|
||||
{
|
||||
flags = __SYS_O_RDWR | __SYS_O_CREAT | __SYS_O_TRUNC;
|
||||
flags = O_RDWR | O_CREAT | O_TRUNC;
|
||||
perm = 0644;
|
||||
}
|
||||
else if (strcmp(mode, "a") == 0)
|
||||
{
|
||||
flags = __SYS_O_WRONLY | __SYS_O_CREAT | __SYS_O_APPEND;
|
||||
flags = O_WRONLY | O_CREAT | O_APPEND;
|
||||
perm = 0644;
|
||||
}
|
||||
else if (strcmp(mode, "a+") == 0)
|
||||
{
|
||||
flags = __SYS_O_RDWR | __SYS_O_CREAT | __SYS_O_APPEND;
|
||||
flags = O_RDWR | O_CREAT | O_APPEND;
|
||||
perm = 0644;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
|
||||
int fd = call_open(pathname, flags, perm);
|
||||
int fd = sysdep(Open)(pathname, flags, perm);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
@ -274,7 +275,7 @@ export size_t fread(void *restrict ptr, size_t size, size_t nitems, FILE *restri
|
||||
{
|
||||
if (stream->buffer_pos >= stream->buffer_size)
|
||||
{
|
||||
int res = call_read(stream->fd, stream->buffer, stream->buffer_size);
|
||||
int res = sysdep(Read)(stream->fd, stream->buffer, stream->buffer_size);
|
||||
if (res <= 0)
|
||||
{
|
||||
if (res == 0)
|
||||
@ -305,7 +306,7 @@ export int fscanf(FILE *restrict, const char *restrict, ...);
|
||||
|
||||
export int fseek(FILE *stream, long offset, int whence)
|
||||
{
|
||||
int res = call_seek(stream->fd, offset, whence);
|
||||
int res = sysdep(Seek)(stream->fd, offset, whence);
|
||||
if (res < 0)
|
||||
{
|
||||
stream->error = 1;
|
||||
@ -321,7 +322,7 @@ export int fsetpos(FILE *, const fpos_t *);
|
||||
|
||||
export long ftell(FILE *stream)
|
||||
{
|
||||
return call_tell(stream->fd);
|
||||
return sysdep(Tell)(stream->fd);
|
||||
}
|
||||
|
||||
export off_t ftello(FILE *);
|
||||
@ -347,7 +348,7 @@ export size_t fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE
|
||||
|
||||
if (stream->buffer_pos == stream->buffer_size)
|
||||
{
|
||||
if (call_write(stream->fd, stream->buffer, stream->buffer_size) != stream->buffer_size)
|
||||
if (sysdep(Write)(stream->fd, stream->buffer, stream->buffer_size) != stream->buffer_size)
|
||||
{
|
||||
stream->error = 1;
|
||||
break;
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <fennix/syscalls.h>
|
||||
#include <bits/libc.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <fennix/syscalls.h>
|
||||
#include <bits/libc.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
|
||||
@ -27,6 +27,6 @@ export int ioctl(int fd, unsigned long op, ...)
|
||||
va_start(args, op);
|
||||
arg = va_arg(args, void *);
|
||||
va_end(args);
|
||||
int ret = call_ioctl(fd, op, arg);
|
||||
int ret = sysdep(IOControl)(fd, op, arg);
|
||||
return __check_errno(ret, -1);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <fennix/syscalls.h>
|
||||
#include <bits/libc.h>
|
||||
#include <errno.h>
|
||||
|
||||
export int mlock(const void *, size_t);
|
||||
@ -24,12 +24,12 @@ export int mlockall(int);
|
||||
|
||||
export void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off)
|
||||
{
|
||||
return (void *)__check_errno((__iptr)call_mmap(addr, len, prot, flags, fildes, off), (__iptr)MAP_FAILED);
|
||||
return (void *)__check_errno((__iptr)sysdep(MemoryMap)(addr, len, prot, flags, fildes, off), (__iptr)MAP_FAILED);
|
||||
}
|
||||
|
||||
export int mprotect(void *addr, size_t len, int prot)
|
||||
{
|
||||
return __check_errno(call_mprotect(addr, len, prot), -1);
|
||||
return __check_errno(sysdep(MemoryProtect)(addr, len, prot), -1);
|
||||
}
|
||||
|
||||
export int msync(void *, size_t, int);
|
||||
@ -38,7 +38,7 @@ export int munlockall(void);
|
||||
|
||||
export int munmap(void *addr, size_t len)
|
||||
{
|
||||
return __check_errno(call_munmap(addr, len), -1);
|
||||
return __check_errno(sysdep(MemoryUnmap)(addr, len), -1);
|
||||
}
|
||||
|
||||
export int posix_madvise(void *, size_t, int);
|
||||
|
@ -17,23 +17,23 @@
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
#include <fennix/syscalls.h>
|
||||
#include <bits/libc.h>
|
||||
|
||||
export int accept(int socket, struct sockaddr *restrict address, socklen_t *restrict address_len)
|
||||
{
|
||||
return __check_errno(call_accept(socket, address, address_len), -1);
|
||||
return __check_errno(sysdep(Accept)(socket, address, address_len), -1);
|
||||
}
|
||||
|
||||
export int accept4(int socket, struct sockaddr *restrict address, socklen_t *restrict address_len, int flag);
|
||||
|
||||
export int bind(int socket, const struct sockaddr *address, socklen_t address_len)
|
||||
{
|
||||
return __check_errno(call_bind(socket, address, address_len), -1);
|
||||
return __check_errno(sysdep(Bind)(socket, address, address_len), -1);
|
||||
}
|
||||
|
||||
export int connect(int socket, const struct sockaddr *address, socklen_t address_len)
|
||||
{
|
||||
return __check_errno(call_connect(socket, address, address_len), -1);
|
||||
return __check_errno(sysdep(Connect)(socket, address, address_len), -1);
|
||||
}
|
||||
|
||||
export int getpeername(int, struct sockaddr *restrict, socklen_t *restrict);
|
||||
@ -42,7 +42,7 @@ export int getsockopt(int, int, int, void *restrict, socklen_t *restrict);
|
||||
|
||||
export int listen(int socket, int backlog)
|
||||
{
|
||||
return __check_errno(call_listen(socket, backlog), -1);
|
||||
return __check_errno(sysdep(Listen)(socket, backlog), -1);
|
||||
}
|
||||
|
||||
export ssize_t recv(int, void *, size_t, int);
|
||||
@ -57,7 +57,7 @@ export int sockatmark(int);
|
||||
|
||||
export int socket(int domain, int type, int protocol)
|
||||
{
|
||||
return __check_errno(call_socket(domain, type, protocol), -1);
|
||||
return __check_errno(sysdep(Socket)(domain, type, protocol), -1);
|
||||
}
|
||||
|
||||
export int socketpair(int, int, int, int[2]);
|
||||
|
@ -15,6 +15,7 @@
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <bits/libc.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
@ -31,7 +32,7 @@ export int fstat(int fildes, struct stat *buf)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return __check_errno(call_fstat(fildes, buf), -1);
|
||||
return __check_errno(sysdep(FStat)(fildes, buf), -1);
|
||||
}
|
||||
|
||||
export int fstatat(int fd, const char *restrict path, struct stat *restrict buf, int flag)
|
||||
@ -58,12 +59,12 @@ export int lstat(const char *restrict path, struct stat *restrict buf)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return __check_errno(call_lstat(path, buf), -1);
|
||||
return __check_errno(sysdep(LStat)(path, buf), -1);
|
||||
}
|
||||
|
||||
export int mkdir(const char *path, mode_t mode)
|
||||
{
|
||||
return __check_errno(call_mkdir(path, mode), -1);
|
||||
return __check_errno(sysdep(MakeDirectory)(path, mode), -1);
|
||||
}
|
||||
|
||||
export int mkdirat(int fd, const char *path, mode_t mode)
|
||||
@ -85,7 +86,7 @@ export int stat(const char *restrict path, struct stat *restrict buf)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return __check_errno(call_stat(path, buf), -1);
|
||||
return __check_errno(sysdep(Stat)(path, buf), -1);
|
||||
}
|
||||
|
||||
export mode_t umask(mode_t);
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <fennix/syscalls.h>
|
||||
#include <bits/libc.h>
|
||||
|
||||
export int uname(struct utsname *name)
|
||||
{
|
||||
@ -31,16 +31,8 @@ export int uname(struct utsname *name)
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct kutsname kname;
|
||||
int result = call_uname(&kname);
|
||||
if (result == 0)
|
||||
{
|
||||
strcpy(name->sysname, kname.sysname);
|
||||
strcpy(name->release, kname.release);
|
||||
strcpy(name->version, kname.version);
|
||||
strcpy(name->machine, kname.machine);
|
||||
}
|
||||
else
|
||||
int result = sysdep(UnixName)(name);
|
||||
if (result != 0)
|
||||
{
|
||||
errno = result;
|
||||
return -1;
|
||||
|
@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/wait.h>
|
||||
#include <fennix/syscalls.h>
|
||||
#include <bits/libc.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
@ -34,5 +34,5 @@ export int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options)
|
||||
|
||||
export pid_t waitpid(pid_t pid, int *stat_loc, int options)
|
||||
{
|
||||
return __check_errno(call_waitpid(pid, stat_loc, options), -1);
|
||||
return __check_errno(sysdep(WaitProcessID)(pid, stat_loc, options), -1);
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <bits/libc.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <termios.h>
|
||||
#include <errno.h>
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <fennix/syscalls.h>
|
||||
#include <bits/libc.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
export char *optarg;
|
||||
@ -44,7 +44,7 @@ export int chown(const char *, uid_t, gid_t);
|
||||
|
||||
export int close(int fildes)
|
||||
{
|
||||
return __check_errno(call_close(fildes), -1);
|
||||
return __check_errno(sysdep(Close)(fildes), -1);
|
||||
}
|
||||
|
||||
export size_t confstr(int, char *, size_t);
|
||||
@ -130,7 +130,7 @@ export int execv(const char *path, char *const argv[])
|
||||
|
||||
export int execve(const char *path, char *const argv[], char *const envp[])
|
||||
{
|
||||
return __check_errno(call_execve(path, argv, envp), -1);
|
||||
return __check_errno(sysdep(Execve)(path, argv, envp), -1);
|
||||
}
|
||||
|
||||
export int execvp(const char *file, char *const argv[])
|
||||
@ -167,7 +167,7 @@ export int fdatasync(int);
|
||||
|
||||
export pid_t fork(void)
|
||||
{
|
||||
return __check_errno(call_fork(), -1);
|
||||
return __check_errno(sysdep(Fork)(), -1);
|
||||
}
|
||||
|
||||
export long int fpathconf(int, int);
|
||||
@ -225,12 +225,12 @@ export pid_t getpgrp(void);
|
||||
|
||||
export pid_t getpid(void)
|
||||
{
|
||||
return call_getpid();
|
||||
return sysdep(GetProcessID)();
|
||||
}
|
||||
|
||||
export pid_t getppid(void)
|
||||
{
|
||||
return call_getppid();
|
||||
return sysdep(GetParentProcessID)();
|
||||
}
|
||||
|
||||
export pid_t getsid(pid_t);
|
||||
@ -261,19 +261,19 @@ export int pipe(int[2]);
|
||||
|
||||
export ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset)
|
||||
{
|
||||
return __check_errno(call_pread(fildes, buf, nbyte, offset), -1);
|
||||
return __check_errno(sysdep(PRead)(fildes, buf, nbyte, offset), -1);
|
||||
}
|
||||
|
||||
export int pthread_atfork(void (*)(void), void (*)(void), void (*)(void));
|
||||
|
||||
export ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset)
|
||||
{
|
||||
return __check_errno(call_pwrite(fildes, buf, nbyte, offset), -1);
|
||||
return __check_errno(sysdep(PWrite)(fildes, buf, nbyte, offset), -1);
|
||||
}
|
||||
|
||||
export ssize_t read(int fildes, void *buf, size_t nbyte)
|
||||
{
|
||||
return __check_errno(call_read(fildes, buf, nbyte), -1);
|
||||
return __check_errno(sysdep(Read)(fildes, buf, nbyte), -1);
|
||||
}
|
||||
|
||||
export int readlink(const char *, char *, size_t);
|
||||
@ -324,5 +324,5 @@ export pid_t vfork(void);
|
||||
|
||||
export ssize_t write(int fildes, const void *buf, size_t nbyte)
|
||||
{
|
||||
return __check_errno(call_write(fildes, buf, nbyte), -1);
|
||||
return __check_errno(sysdep(Write)(fildes, buf, nbyte), -1);
|
||||
}
|
||||
|
58
Userspace/libc/sysdeps/fennix/generic/dl_start.c
Normal file
58
Userspace/libc/sysdeps/fennix/generic/dl_start.c
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
This file is part of Fennix C Library.
|
||||
|
||||
Fennix C Library is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef FENNIX_DYNAMIC_LOADER
|
||||
__attribute__((naked, used, no_stack_protector)) void _dl_start()
|
||||
{
|
||||
#if defined(__amd64__)
|
||||
__asm__(
|
||||
"xorq %rbp, %rbp\n" /* Clear rbp */
|
||||
|
||||
"push %rdi\n"
|
||||
"push %rsi\n"
|
||||
"push %rdx\n"
|
||||
"push %rcx\n"
|
||||
"push %r8\n"
|
||||
"push %r9\n"
|
||||
|
||||
"call __init_print_buffer\n" /* Call __init_print_buffer */
|
||||
"call _dl_preload\n" /* Call _dl_preload */
|
||||
"movl %eax, %edi\n" /* Move return value to edi */
|
||||
"cmp $0, %edi\n" /* Check if return value is 0 */
|
||||
"jne _exit\n" /* If not, jump to _exit */
|
||||
|
||||
"pop %r9\n"
|
||||
"pop %r8\n"
|
||||
"pop %rcx\n"
|
||||
"pop %rdx\n"
|
||||
"pop %rsi\n"
|
||||
"pop %rdi\n"
|
||||
|
||||
"call main\n" /* Call _dl_main */
|
||||
"movl %eax, %edi\n" /* Move return value to edi */
|
||||
"call _exit\n"); /* Call _exit */
|
||||
#elif defined(__i386__)
|
||||
#warning "i386 _start not implemented"
|
||||
#elif defined(__arm__)
|
||||
#warning "arm _start not implemented"
|
||||
#elif defined(__aarch64__)
|
||||
#warning "aarch64 _start not implemented"
|
||||
#else
|
||||
#error "Unsupported architecture"
|
||||
#endif
|
||||
}
|
||||
#endif
|
@ -15,7 +15,7 @@
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <fennix/syscalls.h>
|
||||
#include <bits/syscalls.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
@ -38,7 +38,7 @@ static_assert(__SYS_W_OK == W_OK);
|
||||
static_assert(__SYS_X_OK == X_OK);
|
||||
|
||||
static_assert(sizeof(__SYS_clockid_t) == sizeof(clockid_t));
|
||||
// static_assert(sizeof(__SYS_socklen_t) == sizeof(socklen_t));
|
||||
static_assert(sizeof(__SYS_socklen_t) == sizeof(socklen_t));
|
||||
|
||||
static_assert(__SYS_SEEK_SET == SEEK_SET);
|
||||
static_assert(__SYS_SEEK_CUR == SEEK_CUR);
|
191
Userspace/libc/sysdeps/fennix/generic/syscalls.c
Normal file
191
Userspace/libc/sysdeps/fennix/generic/syscalls.c
Normal file
@ -0,0 +1,191 @@
|
||||
/*
|
||||
This file is part of Fennix C Library.
|
||||
|
||||
Fennix C Library is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <bits/syscalls.h>
|
||||
#include <bits/libc.h>
|
||||
#include <string.h>
|
||||
|
||||
void sysdep(Exit)(int Status)
|
||||
{
|
||||
call_exit(Status);
|
||||
}
|
||||
|
||||
int sysdep(Accept)(int Socket, struct sockaddr *restrict Address, socklen_t *restrict AddressLength)
|
||||
{
|
||||
return call_accept(Socket, Address, AddressLength);
|
||||
}
|
||||
|
||||
int sysdep(Bind)(int Socket, const struct sockaddr *Address, socklen_t AddressLength)
|
||||
{
|
||||
return call_bind(Socket, Address, AddressLength);
|
||||
}
|
||||
|
||||
int sysdep(Connect)(int Socket, const struct sockaddr *Address, socklen_t AddressLength)
|
||||
{
|
||||
return call_connect(Socket, Address, AddressLength);
|
||||
}
|
||||
|
||||
int sysdep(Listen)(int Socket, int Backlog)
|
||||
{
|
||||
return call_listen(Socket, Backlog);
|
||||
}
|
||||
|
||||
int sysdep(Socket)(int Domain, int Type, int Protocol)
|
||||
{
|
||||
return call_socket(Domain, Type, Protocol);
|
||||
}
|
||||
|
||||
int sysdep(UnixName)(struct utsname *Name)
|
||||
{
|
||||
struct kutsname kname;
|
||||
int result = call_uname(&kname);
|
||||
if (result == 0)
|
||||
{
|
||||
strcpy(Name->sysname, kname.sysname);
|
||||
strcpy(Name->release, kname.release);
|
||||
strcpy(Name->version, kname.version);
|
||||
strcpy(Name->machine, kname.machine);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int sysdep(WaitProcessID)(pid_t ProcessID, int *Status, int Options)
|
||||
{
|
||||
return call_waitpid(ProcessID, Status, Options);
|
||||
}
|
||||
|
||||
int sysdep(IOControl)(int Descriptor, unsigned long Operation, void *Argument)
|
||||
{
|
||||
return call_ioctl(Descriptor, Operation, Argument);
|
||||
}
|
||||
|
||||
void *sysdep(MemoryMap)(void *Address, size_t Length, int Protection, int Flags, int Descriptor, off_t Offset)
|
||||
{
|
||||
return (void *)call_mmap(Address, Length, Protection, Flags, Descriptor, Offset);
|
||||
}
|
||||
|
||||
int sysdep(MemoryUnmap)(void *Address, size_t Length)
|
||||
{
|
||||
return call_munmap(Address, Length);
|
||||
}
|
||||
|
||||
int sysdep(MemoryProtect)(void *Address, size_t Length, int Protection)
|
||||
{
|
||||
return call_mprotect(Address, Length, Protection);
|
||||
}
|
||||
|
||||
int sysdep(Fork)(void)
|
||||
{
|
||||
return call_fork();
|
||||
}
|
||||
|
||||
int sysdep(Read)(int Descriptor, void *Buffer, size_t Size)
|
||||
{
|
||||
return call_read(Descriptor, Buffer, Size);
|
||||
}
|
||||
|
||||
int sysdep(Write)(int Descriptor, const void *Buffer, size_t Size)
|
||||
{
|
||||
return call_write(Descriptor, Buffer, Size);
|
||||
}
|
||||
|
||||
int sysdep(PRead)(int Descriptor, void *Buffer, size_t Size, off_t Offset)
|
||||
{
|
||||
return call_pread(Descriptor, Buffer, Size, Offset);
|
||||
}
|
||||
|
||||
int sysdep(PWrite)(int Descriptor, const void *Buffer, size_t Size, off_t Offset)
|
||||
{
|
||||
return call_pwrite(Descriptor, Buffer, Size, Offset);
|
||||
}
|
||||
|
||||
int sysdep(Open)(const char *Pathname, int Flags, mode_t Mode)
|
||||
{
|
||||
return call_open(Pathname, Flags, Mode);
|
||||
}
|
||||
|
||||
int sysdep(Close)(int Descriptor)
|
||||
{
|
||||
return call_close(Descriptor);
|
||||
}
|
||||
|
||||
int sysdep(Access)(const char *Pathname, int Mode)
|
||||
{
|
||||
return call_access(Pathname, Mode);
|
||||
}
|
||||
|
||||
int sysdep(Tell)(int Descriptor)
|
||||
{
|
||||
return call_tell(Descriptor);
|
||||
}
|
||||
|
||||
int sysdep(Seek)(int Descriptor, off_t Offset, int Whence)
|
||||
{
|
||||
return call_seek(Descriptor, Offset, Whence);
|
||||
}
|
||||
|
||||
pid_t sysdep(GetProcessID)(void)
|
||||
{
|
||||
return call_getpid();
|
||||
}
|
||||
|
||||
pid_t sysdep(GetParentProcessID)(void)
|
||||
{
|
||||
return call_getppid();
|
||||
}
|
||||
|
||||
int sysdep(Execve)(const char *Pathname, char *const *Argv, char *const *Envp)
|
||||
{
|
||||
return call_execve(Pathname, Argv, Envp);
|
||||
}
|
||||
|
||||
int sysdep(Kill)(pid_t ProcessID, int Signal)
|
||||
{
|
||||
return call_kill(ProcessID, Signal);
|
||||
}
|
||||
|
||||
int sysdep(Stat)(const char *Pathname, struct stat *Statbuf)
|
||||
{
|
||||
return call_stat(Pathname, Statbuf);
|
||||
}
|
||||
|
||||
int sysdep(FStat)(int Descriptor, struct stat *Statbuf)
|
||||
{
|
||||
return call_fstat(Descriptor, Statbuf);
|
||||
}
|
||||
|
||||
int sysdep(LStat)(const char *Pathname, struct stat *Statbuf)
|
||||
{
|
||||
return call_lstat(Pathname, Statbuf);
|
||||
}
|
||||
|
||||
int sysdep(Truncate)(const char *Pathname, off_t Length)
|
||||
{
|
||||
return call_truncate(Pathname, Length);
|
||||
}
|
||||
|
||||
int sysdep(MakeDirectory)(const char *Pathname, mode_t Mode)
|
||||
{
|
||||
return call_mkdir(Pathname, Mode);
|
||||
}
|
||||
|
||||
int sysdep(ProcessControl)(unsigned long Option, unsigned long Arg1, unsigned long Arg2, unsigned long Arg3, unsigned long Arg4)
|
||||
{
|
||||
return call_prctl(Option, Arg1, Arg2, Arg3, Arg4);
|
||||
}
|
@ -15,13 +15,14 @@
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <fennix/syscalls.h>
|
||||
#include <bits/syscalls.h>
|
||||
#include <bits/libc.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <inttypes.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <fennix/syscalls.h>
|
||||
|
||||
#ifndef FENNIX_DYNAMIC_LOADER
|
||||
export __attribute__((naked, used, no_stack_protector)) void *__tls_get_addr(void *__data)
|
||||
{
|
||||
#warning "__tls_get_addr not implemented"
|
||||
@ -34,11 +35,12 @@ int __init_pthread(void)
|
||||
{
|
||||
__pthread *ptr = (__pthread *)call_mmap(0,
|
||||
0x1000,
|
||||
__SYS_PROT_READ | __SYS_PROT_WRITE,
|
||||
__SYS_MAP_ANONYMOUS | __SYS_MAP_PRIVATE,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_ANONYMOUS | MAP_PRIVATE,
|
||||
-1, 0);
|
||||
call_prctl(__SYS_SET_FS, ptr, 0, 0, 0);
|
||||
ptr->Self = ptr;
|
||||
ptr->CurrentError = 0;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
22
Userspace/libc/workspace_test.c
Normal file
22
Userspace/libc/workspace_test.c
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
This file is part of Fennix C Library.
|
||||
|
||||
Fennix C Library is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __fennix__
|
||||
#error "Macro __fennix__ is not defined."
|
||||
#endif
|
||||
|
||||
int main() { return 0; }
|
@ -1,12 +1,8 @@
|
||||
build:
|
||||
cp -a $(CURDIR)/include/. $(WORKSPACE_DIR)/out/include
|
||||
make -C libgcc build
|
||||
make -C libm build
|
||||
make -C libstdc++ build
|
||||
make -C libexample build
|
||||
|
||||
clean:
|
||||
make -C libgcc clean
|
||||
make -C libm clean
|
||||
make -C libstdc++ clean
|
||||
make -C libexample clean
|
||||
|
@ -15,7 +15,7 @@
|
||||
along with Fennix Userspace. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <bits/libc.h>
|
||||
|
||||
export int foo()
|
||||
{
|
||||
|
@ -1,48 +0,0 @@
|
||||
default:
|
||||
$(error Do not run this Makefile directly!)
|
||||
|
||||
DYNAMIC_NAME := $(notdir $(shell pwd)).so
|
||||
STATIC_NAME := $(notdir $(shell pwd)).a
|
||||
|
||||
OUTPUT_DIR=$(WORKSPACE_DIR)/out/lib/
|
||||
SYSROOT = --sysroot=$(WORKSPACE_DIR)/out/
|
||||
|
||||
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||
CXX_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||
OBJ = ${S_SOURCES:.S=.o} ${C_SOURCES:.c=.o} ${CXX_SOURCES:.cpp=.o}
|
||||
|
||||
CFLAGS := -fvisibility=hidden -fPIC -I../include -I$(WORKSPACE_DIR)/out/include -DLIBC_GIT_COMMIT='"$(shell git rev-parse HEAD)"'
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always
|
||||
endif
|
||||
|
||||
build: $(DYNAMIC_NAME) $(STATIC_NAME)
|
||||
|
||||
.PHONY: $(DYNAMIC_NAME) $(STATIC_NAME)
|
||||
|
||||
$(DYNAMIC_NAME): $(OBJ)
|
||||
$(info Linking $@)
|
||||
$(CC) -nostdlib -shared -fPIC -fPIE -Wl,-soname,$(DYNAMIC_NAME) $(SYSROOT) $(OBJ) -o $(DYNAMIC_NAME)
|
||||
cp $(DYNAMIC_NAME) $(OUTPUT_DIR)$(DYNAMIC_NAME)
|
||||
|
||||
$(STATIC_NAME): $(OBJ)
|
||||
$(info Linking $@)
|
||||
$(AR) -rcs $(STATIC_NAME) $(OBJ)
|
||||
cp $(STATIC_NAME) $(OUTPUT_DIR)$(STATIC_NAME)
|
||||
|
||||
%.o: %.c
|
||||
$(info Compiling $<)
|
||||
$(CC) $(CFLAGS) -std=c17 -c $< -o $@
|
||||
|
||||
%.o: %.cpp
|
||||
$(info Compiling $<)
|
||||
$(CC) $(CFLAGS) -std=c++20 -c $< -o $@
|
||||
|
||||
%.o: %.S
|
||||
$(info Compiling $<)
|
||||
$(AS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(OBJ) $(DYNAMIC_NAME) $(STATIC_NAME)
|
@ -1,48 +0,0 @@
|
||||
default:
|
||||
$(error Do not run this Makefile directly!)
|
||||
|
||||
DYNAMIC_NAME := $(notdir $(shell pwd)).so
|
||||
STATIC_NAME := $(notdir $(shell pwd)).a
|
||||
|
||||
OUTPUT_DIR=$(WORKSPACE_DIR)/out/lib/
|
||||
SYSROOT = --sysroot=$(WORKSPACE_DIR)/out/
|
||||
|
||||
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||
CXX_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||
OBJ = ${S_SOURCES:.S=.o} ${C_SOURCES:.c=.o} ${CXX_SOURCES:.cpp=.o}
|
||||
|
||||
CFLAGS := -fvisibility=hidden -fPIC -I../include -I$(WORKSPACE_DIR)/out/include -DLIBC_GIT_COMMIT='"$(shell git rev-parse HEAD)"'
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always
|
||||
endif
|
||||
|
||||
build: $(DYNAMIC_NAME) $(STATIC_NAME)
|
||||
|
||||
.PHONY: $(DYNAMIC_NAME) $(STATIC_NAME)
|
||||
|
||||
$(DYNAMIC_NAME): $(OBJ)
|
||||
$(info Linking $@)
|
||||
$(CC) -nostdlib -shared -fPIC -fPIE -Wl,-soname,$(DYNAMIC_NAME) $(SYSROOT) $(OBJ) -o $(DYNAMIC_NAME)
|
||||
cp $(DYNAMIC_NAME) $(OUTPUT_DIR)$(DYNAMIC_NAME)
|
||||
|
||||
$(STATIC_NAME): $(OBJ)
|
||||
$(info Linking $@)
|
||||
$(AR) -rcs $(STATIC_NAME) $(OBJ)
|
||||
cp $(STATIC_NAME) $(OUTPUT_DIR)$(STATIC_NAME)
|
||||
|
||||
%.o: %.c
|
||||
$(info Compiling $<)
|
||||
$(CC) $(CFLAGS) -std=c17 -c $< -o $@
|
||||
|
||||
%.o: %.cpp
|
||||
$(info Compiling $<)
|
||||
$(CC) $(CFLAGS) -std=c++20 -c $< -o $@
|
||||
|
||||
%.o: %.S
|
||||
$(info Compiling $<)
|
||||
$(AS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(OBJ) $(DYNAMIC_NAME) $(STATIC_NAME)
|
Loading…
x
Reference in New Issue
Block a user