commit
a8eb7a6b66
@ -7,6 +7,8 @@
|
||||
#include "memory/VMM.h"
|
||||
#include <stddef.h>
|
||||
|
||||
// FIXME: Round size up instead of down. (use get_blocks_from_size)
|
||||
|
||||
#define MAP_FAIL(errno) 0xffffffffffffff00 | (unsigned char)(errno)
|
||||
|
||||
void sys_mmap(Context* context, void* address, size_t size, int flags)
|
||||
|
@ -1,15 +1,16 @@
|
||||
#ifndef _ERRNO_H
|
||||
#define _ERRNO_H
|
||||
|
||||
/* The last error encountered during a call to a library or system function. */
|
||||
extern int errno;
|
||||
|
||||
#define EPERM 1
|
||||
#define ENOENT 2
|
||||
#define EBADF 9
|
||||
#define ENOMEM 12
|
||||
#define EISDIR 21
|
||||
#define EINVAL 22
|
||||
#define EMFILE 24
|
||||
#define ENOSYS 38
|
||||
#define EPERM 1 // Operation not permitted
|
||||
#define ENOENT 2 // No such file or directory
|
||||
#define EBADF 9 // Bad file descriptor
|
||||
#define ENOMEM 12 // Cannot allocate memory
|
||||
#define EISDIR 21 // Is a directory
|
||||
#define EINVAL 22 // Invalid argument
|
||||
#define EMFILE 24 // Too many open files
|
||||
#define ENOSYS 38 // Function not implemented
|
||||
|
||||
#endif
|
@ -1,8 +1,11 @@
|
||||
#ifndef _FCNTL_H
|
||||
#define _FCNTL_H
|
||||
|
||||
/* Open for reading only. */
|
||||
#define O_RDONLY 1
|
||||
/* Open for writing only. */
|
||||
#define O_WRONLY 2
|
||||
/* Open for reading and writing. */
|
||||
#define O_RDWR 3
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -10,7 +13,8 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
int open(const char*, int);
|
||||
/* Opens the file specified by pathname. Returns a file descriptor on success, or -1 on error. */
|
||||
int open(const char* pathname, int flags);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -9,8 +9,13 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* Returns the current program's thread identifier. */
|
||||
pid_t gettid();
|
||||
unsigned int msleep(unsigned int);
|
||||
|
||||
/* Sleeps for ms milliseconds. */
|
||||
unsigned int msleep(unsigned int ms);
|
||||
|
||||
/* Prints a message to standard error and aborts the program. */
|
||||
noreturn void __luna_abort(const char* message);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -13,8 +13,8 @@ typedef struct
|
||||
int f_err;
|
||||
} FILE;
|
||||
|
||||
extern FILE* __stderr;
|
||||
extern FILE* __stdout;
|
||||
extern FILE* __stderr; // The standard error stream.
|
||||
extern FILE* __stdout; // The standard output stream.
|
||||
#define stderr __stderr
|
||||
#define stdout __stdout
|
||||
|
||||
@ -22,31 +22,80 @@ extern FILE* __stdout;
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
int fclose(FILE*);
|
||||
int fflush(FILE*);
|
||||
FILE* fopen(const char*, const char*);
|
||||
int fprintf(FILE*, const char*, ...);
|
||||
size_t fread(void*, size_t, size_t, FILE*);
|
||||
|
||||
/* Closes the file handle stream. */
|
||||
int fclose(FILE* stream);
|
||||
|
||||
/* Does not do anything for now, since buffered IO is not implemented yet. */
|
||||
int fflush(FILE* stream);
|
||||
|
||||
/* Opens the file specified by pathname. Returns the file handle on success, or NULL on error. */
|
||||
FILE* fopen(const char* pathname, const char* mode);
|
||||
|
||||
/* Writes formatted output according to the string format to the file stream. */
|
||||
int fprintf(FILE* stream, const char* format, ...);
|
||||
|
||||
/* Reads nmemb items of size size from the file stream into buf. */
|
||||
size_t fread(void* buf, size_t size, size_t nmemb, FILE* stream);
|
||||
|
||||
int fseek(FILE*, long, int); // Not implemented.
|
||||
long ftell(FILE*); // Not implemented.
|
||||
size_t fwrite(const void*, size_t, size_t, FILE*);
|
||||
int ferror(FILE*);
|
||||
int feof(FILE*);
|
||||
void clearerr(FILE*);
|
||||
|
||||
/* Writes nmemb items of size size from buf into the file stream. */
|
||||
size_t fwrite(const void* buf, size_t size, size_t nmemb, FILE* stream);
|
||||
|
||||
/* Returns nonzero if the error flag in stream was set. */
|
||||
int ferror(FILE* stream);
|
||||
|
||||
/* Returns nonzero if the end-of-file flag in stream was set. */
|
||||
int feof(FILE* stream);
|
||||
|
||||
/* Clears the error and end-of-file flags from stream. */
|
||||
void clearerr(FILE* stream);
|
||||
|
||||
void setbuf(FILE*, char*); // Not implemented.
|
||||
int vfprintf(FILE*, const char*, va_list);
|
||||
int printf(const char*, ...);
|
||||
int vprintf(const char*, va_list);
|
||||
int sprintf(char*, const char*, ...);
|
||||
int snprintf(char*, size_t, const char*, ...);
|
||||
int vsprintf(char*, const char*, va_list);
|
||||
int vsnprintf(char*, size_t, const char*, va_list);
|
||||
int puts(const char*);
|
||||
int fputs(const char*, FILE*);
|
||||
int fputc(int, FILE*);
|
||||
int putc(int, FILE*);
|
||||
int putchar(int);
|
||||
void perror(const char*);
|
||||
|
||||
/* Writes formatted output according to the string format to the file stream. */
|
||||
int vfprintf(FILE* stream, const char* format, va_list ap);
|
||||
|
||||
/* Writes formatted output according to the string format to standard output. */
|
||||
int printf(const char* format, ...);
|
||||
|
||||
/* Writes formatted output according to the string format to standard output. */
|
||||
int vprintf(const char* format, va_list ap);
|
||||
|
||||
/* Writes formatted output according to the string format to the string str. This function is unsafe, use snprintf
|
||||
* instead. */
|
||||
int sprintf(char* str, const char* format, ...);
|
||||
|
||||
/* Writes at most max bytes of formatted output according to the string format to the string str.*/
|
||||
int snprintf(char* str, size_t max, const char* format, ...);
|
||||
|
||||
/* Writes formatted output according to the string format to the string str. This function is unsafe, use vsnprintf
|
||||
* instead. */
|
||||
int vsprintf(char* str, const char* format, va_list ap);
|
||||
|
||||
/* Writes at most max bytes of formatted output according to the string format to the string str. */
|
||||
int vsnprintf(char* str, size_t max, const char* format, va_list ap);
|
||||
|
||||
/* Writes the string str followed by a trailing newline to stdout. */
|
||||
int puts(const char* str);
|
||||
|
||||
/* Writes the string str to the file stream. */
|
||||
int fputs(const char* str, FILE* stream);
|
||||
|
||||
/* Writes the character c to the file stream. */
|
||||
int fputc(int c, FILE* stream);
|
||||
|
||||
/* Writes the character c to the file stream. */
|
||||
int putc(int c, FILE* stream);
|
||||
|
||||
/* Writes the character c to standard output. */
|
||||
int putchar(int c);
|
||||
|
||||
/* Prints a message to standard error consisting of the string str followed by a colon and the string representation
|
||||
* of the last error encountered during a call to a system or library function. */
|
||||
void perror(const char* str);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -9,13 +9,37 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* Aborts the program. */
|
||||
noreturn void abort();
|
||||
noreturn void exit(int);
|
||||
|
||||
/* Exits the program with the specified status code. */
|
||||
noreturn void exit(int status);
|
||||
|
||||
/* Not implemented. */
|
||||
int atexit(void (*)(void));
|
||||
|
||||
/* Not implemented.*/
|
||||
int atoi(const char*);
|
||||
void free(void*);
|
||||
|
||||
/* Not implemented. */
|
||||
char* getenv(const char*);
|
||||
void* malloc(size_t);
|
||||
|
||||
/* Allocates n bytes of memory and returns a pointer to it. This memory should be freed by calling free() when it is
|
||||
* not in use anymore. */
|
||||
void* malloc(size_t n);
|
||||
|
||||
/* Allocates enough bytes of memory for an array containing nmemb items of size n and returns a pointer to it. This
|
||||
* memory should be freed by calling free() when it is not in use anymore. */
|
||||
void* calloc(size_t nmemb, size_t n);
|
||||
|
||||
/* Resizes memory allocated by malloc() or calloc() to n bytes. Returns a pointer to the new resized region of
|
||||
* memory, which should be used instead of the old one. This memory should be freed by calling free() when it is not
|
||||
* in use anymore. */
|
||||
void* realloc(void* ptr, size_t n);
|
||||
|
||||
/* Frees a pointer to memory allocated by malloc(), calloc() or realloc(). Accessing the contents of ptr afterwards
|
||||
* is undefined behavior. */
|
||||
void free(void* ptr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -9,21 +9,37 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void* memcpy(void*, const void*, size_t);
|
||||
void* memset(void*, int, size_t);
|
||||
void* memclr(void*, size_t);
|
||||
/* Copies n bytes from src to dst. */
|
||||
void* memcpy(void* dest, const void* src, size_t n);
|
||||
|
||||
size_t strlen(const char*);
|
||||
/* Sets n bytes of buf to c, cast to a character. */
|
||||
void* memset(void* buf, int c, size_t n);
|
||||
|
||||
deprecated("strcpy is unsafe and should not be used; use strncpy instead") char* strcpy(char*, const char*);
|
||||
char* strncpy(char*, const char*, size_t);
|
||||
/* Clears n bytes of buf. */
|
||||
void* memclr(void* buf, size_t n);
|
||||
|
||||
char* strchr(const char*, int);
|
||||
/* Returns the length of the string str. */
|
||||
size_t strlen(const char* str);
|
||||
|
||||
deprecated("strcat is unsafe and should not be used; use strncat instead") char* strcat(char*, const char*);
|
||||
char* strncat(char*, const char*, size_t);
|
||||
/* Copies the string src into dest. This function is unsafe, use strncpy instead. */
|
||||
deprecated("strcpy is unsafe and should not be used; use strncpy instead") char* strcpy(char* dest,
|
||||
const char* src);
|
||||
|
||||
char* strerror(int);
|
||||
/* Copies at most max bytes from the string src into dest. */
|
||||
char* strncpy(char* dest, const char* src, size_t max);
|
||||
|
||||
/* Returns a pointer to the first occurrence of the character c in str, or NULL if it is not found. */
|
||||
char* strchr(const char* str, int c);
|
||||
|
||||
/* Concatenates the string src into dest. This function is unsafe, use strncat instead. */
|
||||
deprecated("strcat is unsafe and should not be used; use strncat instead") char* strcat(char* dest,
|
||||
const char* src);
|
||||
|
||||
/* Concatenates at most max bytes of the string src into dest. */
|
||||
char* strncat(char* dest, const char* src, size_t max);
|
||||
|
||||
/* Returns the error string associated with the error number err. */
|
||||
char* strerror(int err);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
typedef unsigned long off_t;
|
||||
|
||||
/* Address returned by mmap when it fails. */
|
||||
#define MAP_FAILED (void*)-1
|
||||
|
||||
#define PROT_READ_WRITE 1
|
||||
@ -16,8 +17,13 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void* mmap(void*, size_t, int, int, int, off_t);
|
||||
int munmap(void* addr, size_t len);
|
||||
/* Maps size bytes of memory (rounded down to the nearest page-aligned size) into the current process's address
|
||||
* space at addr. If addr is null, the kernel will choose an address. */
|
||||
void* mmap(void* addr, size_t size, int prot, int flags, int fd, off_t offset);
|
||||
|
||||
/* Unmaps size bytes of memory (rounded down to the nearest page-aligned size) at addr from the current process's
|
||||
* address space. */
|
||||
int munmap(void* addr, size_t size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1,8 +1,13 @@
|
||||
#ifndef _SYS_TYPES_H
|
||||
#define _SYS_TYPES_H
|
||||
|
||||
/* The type of a process identifier. */
|
||||
typedef long int pid_t;
|
||||
|
||||
/* The type returned by sizeof(). */
|
||||
typedef unsigned long int size_t;
|
||||
|
||||
/* Signed version of size_t. */
|
||||
typedef long int ssize_t;
|
||||
|
||||
#endif
|
@ -8,16 +8,29 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* Not implemented. */
|
||||
int execv(const char*, char* const[]);
|
||||
/* Not implemented. */
|
||||
int execve(const char*, char* const[], char* const[]);
|
||||
/* Not implemented. */
|
||||
int execvp(const char*, char* const[]);
|
||||
/* Not implemented. */
|
||||
pid_t fork(void);
|
||||
long syscall(long, ...);
|
||||
unsigned int sleep(unsigned int);
|
||||
|
||||
ssize_t read(int, void*, size_t);
|
||||
ssize_t write(int, const void*, size_t);
|
||||
int close(int);
|
||||
/* Calls the kernel for a specific service, determined by number. */
|
||||
long syscall(long number, ...);
|
||||
|
||||
/* Suspends execution for a chosen amount of seconds. */
|
||||
unsigned int sleep(unsigned int seconds);
|
||||
|
||||
/* Reads count bytes from the file descriptor fd into the memory at buf. */
|
||||
ssize_t read(int fd, void* buf, size_t count);
|
||||
|
||||
/* Writes count bytes of the memory at buf to the file descriptor fd. */
|
||||
ssize_t write(int fd, const void* buf, size_t count);
|
||||
|
||||
/* Closes the file descriptor fd. */
|
||||
int close(int fd);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -5,8 +5,6 @@
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define noreturn __attribute__((noreturn))
|
||||
|
||||
extern "C"
|
||||
{
|
||||
pid_t gettid()
|
||||
@ -21,7 +19,7 @@ extern "C"
|
||||
|
||||
noreturn void __luna_abort(const char* message)
|
||||
{
|
||||
fwrite(message, strlen(message), 1, stdout);
|
||||
fputs(message, stderr);
|
||||
abort();
|
||||
}
|
||||
}
|
@ -3,11 +3,6 @@
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define noreturn __attribute__((noreturn))
|
||||
|
||||
#define maybe_unused __attribute__((maybe_unused))
|
||||
#define unused __attribute__((unused))
|
||||
|
||||
extern "C"
|
||||
{
|
||||
noreturn void abort()
|
||||
@ -25,10 +20,12 @@ extern "C"
|
||||
{
|
||||
NOT_IMPLEMENTED("atexit");
|
||||
}
|
||||
|
||||
int atoi(const char*)
|
||||
{
|
||||
NOT_IMPLEMENTED("atoi");
|
||||
}
|
||||
|
||||
char* getenv(const char*)
|
||||
{
|
||||
NOT_IMPLEMENTED("getenv");
|
||||
|
@ -10,18 +10,18 @@ extern "C"
|
||||
return dest;
|
||||
}
|
||||
|
||||
void* memset(void* dest, int c, size_t n)
|
||||
void* memset(void* buf, int c, size_t n)
|
||||
{
|
||||
for (size_t i = 0; i < n; ++i) { *((char*)dest + i) = (char)c; }
|
||||
return dest;
|
||||
for (size_t i = 0; i < n; ++i) { *((char*)buf + i) = (char)c; }
|
||||
return buf;
|
||||
}
|
||||
|
||||
size_t strlen(const char* s)
|
||||
size_t strlen(const char* str)
|
||||
{
|
||||
const char* i = s;
|
||||
const char* i = str;
|
||||
for (; *i; ++i)
|
||||
;
|
||||
return (i - s);
|
||||
return (i - str);
|
||||
}
|
||||
|
||||
char* strcpy(char* dest, const char* src)
|
||||
@ -30,10 +30,10 @@ extern "C"
|
||||
return dest;
|
||||
}
|
||||
|
||||
char* strncpy(char* dest, const char* src, size_t n)
|
||||
char* strncpy(char* dest, const char* src, size_t max) // FIXME: Implement strncpy according to the specification.
|
||||
{
|
||||
size_t src_len = strlen(src) + 1; // NULL byte
|
||||
memcpy(dest, src, src_len > n ? n : src_len);
|
||||
memcpy(dest, src, src_len > max ? max : src_len);
|
||||
return dest;
|
||||
}
|
||||
|
||||
@ -49,40 +49,40 @@ extern "C"
|
||||
return dest;
|
||||
}
|
||||
|
||||
char* strncat(char* dest, const char* src, size_t n)
|
||||
char* strncat(char* dest, const char* src, size_t max)
|
||||
{
|
||||
size_t dest_len = strlen(dest);
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < n && *(src + i); i++) *(char*)(dest + dest_len + i) = *(const char*)(src + i);
|
||||
for (i = 0; i < max && *(src + i); i++) *(char*)(dest + dest_len + i) = *(const char*)(src + i);
|
||||
|
||||
*(char*)(dest + dest_len + i) = '\0';
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
char* strchr(const char* str, int chr)
|
||||
char* strchr(const char* str, int c)
|
||||
{
|
||||
while (*str && *str != (char)chr) str++;
|
||||
while (*str && *str != (char)c) str++;
|
||||
if (*str) return const_cast<char*>(str);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* memclr(void* start, size_t count)
|
||||
void* memclr(void* buf, size_t n)
|
||||
{
|
||||
// "i" is our counter of how many bytes we've cleared
|
||||
size_t i;
|
||||
|
||||
// find out if "m_start" is aligned on a SSE_XMM_SIZE boundary
|
||||
if ((size_t)start & (15))
|
||||
if ((size_t)buf & (15))
|
||||
{
|
||||
i = 0;
|
||||
|
||||
// we need to clear byte-by-byte until "m_start" is aligned on an SSE_XMM_SIZE boundary
|
||||
// ... and lets make sure we don't copy 'too' many bytes (i < m_count)
|
||||
while (((size_t)start + i) & (15) && i < count)
|
||||
while (((size_t)buf + i) & (15) && i < n)
|
||||
{
|
||||
asm("stosb;" ::"D"((size_t)start + i), "a"(0));
|
||||
asm("stosb;" ::"D"((size_t)buf + i), "a"(0));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
@ -93,42 +93,42 @@ extern "C"
|
||||
}
|
||||
|
||||
// clear 64-byte chunks of memory (4 16-byte operations)
|
||||
for (; i + 64 <= count; i += 64)
|
||||
for (; i + 64 <= n; i += 64)
|
||||
{
|
||||
asm volatile(" pxor %%xmm0, %%xmm0; " // set XMM0 to 0
|
||||
" movdqa %%xmm0, 0(%0); " // move 16 bytes from XMM0 to %0 + 0
|
||||
" movdqa %%xmm0, 16(%0); "
|
||||
" movdqa %%xmm0, 32(%0); "
|
||||
" movdqa %%xmm0, 48(%0); " ::"r"((size_t)start + i));
|
||||
" movdqa %%xmm0, 48(%0); " ::"r"((size_t)buf + i));
|
||||
}
|
||||
|
||||
// copy the remaining bytes (if any)
|
||||
asm(" rep stosb; " ::"a"((size_t)(0)), "D"(((size_t)start) + i), "c"(count - i));
|
||||
asm(" rep stosb; " ::"a"((size_t)(0)), "D"(((size_t)buf) + i), "c"(n - i));
|
||||
|
||||
// "i" will contain the total amount of bytes that were actually transfered
|
||||
i += count - i;
|
||||
i += n - i;
|
||||
|
||||
// we return "m_start" + the amount of bytes that were transfered
|
||||
return (void*)(((size_t)start) + i);
|
||||
return (void*)(((size_t)buf) + i);
|
||||
}
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC diagnostic ignored "-Wwrite-strings"
|
||||
|
||||
char* strerror(int errnum)
|
||||
char* strerror(int err)
|
||||
{
|
||||
switch (errnum)
|
||||
switch (err)
|
||||
{
|
||||
case EPERM: return "Operation not permitted";
|
||||
case EINVAL: return "Invalid argument";
|
||||
case ENOMEM: return "Out of memory";
|
||||
case ENOMEM: return "Cannot allocate memory";
|
||||
case ENOSYS: return "Function not implemented";
|
||||
case ENOENT: return "No such file or directory";
|
||||
case EBADF: return "Bad file descriptor";
|
||||
case EMFILE: return "Too many open files";
|
||||
case EISDIR: return "Is a directory";
|
||||
case 0: return "Success";
|
||||
default: return (char*)(unsigned long int)errnum;
|
||||
default: return (char*)(unsigned long int)err;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user