commit
a8eb7a6b66
@ -7,6 +7,8 @@
|
|||||||
#include "memory/VMM.h"
|
#include "memory/VMM.h"
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
// FIXME: Round size up instead of down. (use get_blocks_from_size)
|
||||||
|
|
||||||
#define MAP_FAIL(errno) 0xffffffffffffff00 | (unsigned char)(errno)
|
#define MAP_FAIL(errno) 0xffffffffffffff00 | (unsigned char)(errno)
|
||||||
|
|
||||||
void sys_mmap(Context* context, void* address, size_t size, int flags)
|
void sys_mmap(Context* context, void* address, size_t size, int flags)
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
#ifndef _ERRNO_H
|
#ifndef _ERRNO_H
|
||||||
#define _ERRNO_H
|
#define _ERRNO_H
|
||||||
|
|
||||||
|
/* The last error encountered during a call to a library or system function. */
|
||||||
extern int errno;
|
extern int errno;
|
||||||
|
|
||||||
#define EPERM 1
|
#define EPERM 1 // Operation not permitted
|
||||||
#define ENOENT 2
|
#define ENOENT 2 // No such file or directory
|
||||||
#define EBADF 9
|
#define EBADF 9 // Bad file descriptor
|
||||||
#define ENOMEM 12
|
#define ENOMEM 12 // Cannot allocate memory
|
||||||
#define EISDIR 21
|
#define EISDIR 21 // Is a directory
|
||||||
#define EINVAL 22
|
#define EINVAL 22 // Invalid argument
|
||||||
#define EMFILE 24
|
#define EMFILE 24 // Too many open files
|
||||||
#define ENOSYS 38
|
#define ENOSYS 38 // Function not implemented
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -1,8 +1,11 @@
|
|||||||
#ifndef _FCNTL_H
|
#ifndef _FCNTL_H
|
||||||
#define _FCNTL_H
|
#define _FCNTL_H
|
||||||
|
|
||||||
|
/* Open for reading only. */
|
||||||
#define O_RDONLY 1
|
#define O_RDONLY 1
|
||||||
|
/* Open for writing only. */
|
||||||
#define O_WRONLY 2
|
#define O_WRONLY 2
|
||||||
|
/* Open for reading and writing. */
|
||||||
#define O_RDWR 3
|
#define O_RDWR 3
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -10,7 +13,8 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#endif
|
#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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,13 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Returns the current program's thread identifier. */
|
||||||
pid_t gettid();
|
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);
|
noreturn void __luna_abort(const char* message);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -13,8 +13,8 @@ typedef struct
|
|||||||
int f_err;
|
int f_err;
|
||||||
} FILE;
|
} FILE;
|
||||||
|
|
||||||
extern FILE* __stderr;
|
extern FILE* __stderr; // The standard error stream.
|
||||||
extern FILE* __stdout;
|
extern FILE* __stdout; // The standard output stream.
|
||||||
#define stderr __stderr
|
#define stderr __stderr
|
||||||
#define stdout __stdout
|
#define stdout __stdout
|
||||||
|
|
||||||
@ -22,31 +22,80 @@ extern FILE* __stdout;
|
|||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
int fclose(FILE*);
|
|
||||||
int fflush(FILE*);
|
/* Closes the file handle stream. */
|
||||||
FILE* fopen(const char*, const char*);
|
int fclose(FILE* stream);
|
||||||
int fprintf(FILE*, const char*, ...);
|
|
||||||
size_t fread(void*, size_t, size_t, FILE*);
|
/* 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.
|
int fseek(FILE*, long, int); // Not implemented.
|
||||||
long ftell(FILE*); // Not implemented.
|
long ftell(FILE*); // Not implemented.
|
||||||
size_t fwrite(const void*, size_t, size_t, FILE*);
|
|
||||||
int ferror(FILE*);
|
/* Writes nmemb items of size size from buf into the file stream. */
|
||||||
int feof(FILE*);
|
size_t fwrite(const void* buf, size_t size, size_t nmemb, FILE* stream);
|
||||||
void clearerr(FILE*);
|
|
||||||
|
/* 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.
|
void setbuf(FILE*, char*); // Not implemented.
|
||||||
int vfprintf(FILE*, const char*, va_list);
|
|
||||||
int printf(const char*, ...);
|
/* Writes formatted output according to the string format to the file stream. */
|
||||||
int vprintf(const char*, va_list);
|
int vfprintf(FILE* stream, const char* format, va_list ap);
|
||||||
int sprintf(char*, const char*, ...);
|
|
||||||
int snprintf(char*, size_t, const char*, ...);
|
/* Writes formatted output according to the string format to standard output. */
|
||||||
int vsprintf(char*, const char*, va_list);
|
int printf(const char* format, ...);
|
||||||
int vsnprintf(char*, size_t, const char*, va_list);
|
|
||||||
int puts(const char*);
|
/* Writes formatted output according to the string format to standard output. */
|
||||||
int fputs(const char*, FILE*);
|
int vprintf(const char* format, va_list ap);
|
||||||
int fputc(int, FILE*);
|
|
||||||
int putc(int, FILE*);
|
/* Writes formatted output according to the string format to the string str. This function is unsafe, use snprintf
|
||||||
int putchar(int);
|
* instead. */
|
||||||
void perror(const char*);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -9,13 +9,37 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Aborts the program. */
|
||||||
noreturn void abort();
|
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));
|
int atexit(void (*)(void));
|
||||||
|
|
||||||
|
/* Not implemented.*/
|
||||||
int atoi(const char*);
|
int atoi(const char*);
|
||||||
void free(void*);
|
|
||||||
|
/* Not implemented. */
|
||||||
char* getenv(const char*);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -9,21 +9,37 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void* memcpy(void*, const void*, size_t);
|
/* Copies n bytes from src to dst. */
|
||||||
void* memset(void*, int, size_t);
|
void* memcpy(void* dest, const void* src, size_t n);
|
||||||
void* memclr(void*, size_t);
|
|
||||||
|
|
||||||
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*);
|
/* Clears n bytes of buf. */
|
||||||
char* strncpy(char*, const char*, size_t);
|
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*);
|
/* Copies the string src into dest. This function is unsafe, use strncpy instead. */
|
||||||
char* strncat(char*, const char*, size_t);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
typedef unsigned long off_t;
|
typedef unsigned long off_t;
|
||||||
|
|
||||||
|
/* Address returned by mmap when it fails. */
|
||||||
#define MAP_FAILED (void*)-1
|
#define MAP_FAILED (void*)-1
|
||||||
|
|
||||||
#define PROT_READ_WRITE 1
|
#define PROT_READ_WRITE 1
|
||||||
@ -16,8 +17,13 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void* mmap(void*, size_t, int, int, int, off_t);
|
/* Maps size bytes of memory (rounded down to the nearest page-aligned size) into the current process's address
|
||||||
int munmap(void* addr, size_t len);
|
* 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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
#ifndef _SYS_TYPES_H
|
#ifndef _SYS_TYPES_H
|
||||||
#define _SYS_TYPES_H
|
#define _SYS_TYPES_H
|
||||||
|
|
||||||
|
/* The type of a process identifier. */
|
||||||
typedef long int pid_t;
|
typedef long int pid_t;
|
||||||
|
|
||||||
|
/* The type returned by sizeof(). */
|
||||||
typedef unsigned long int size_t;
|
typedef unsigned long int size_t;
|
||||||
|
|
||||||
|
/* Signed version of size_t. */
|
||||||
typedef long int ssize_t;
|
typedef long int ssize_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -8,16 +8,29 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Not implemented. */
|
||||||
int execv(const char*, char* const[]);
|
int execv(const char*, char* const[]);
|
||||||
|
/* Not implemented. */
|
||||||
int execve(const char*, char* const[], char* const[]);
|
int execve(const char*, char* const[], char* const[]);
|
||||||
|
/* Not implemented. */
|
||||||
int execvp(const char*, char* const[]);
|
int execvp(const char*, char* const[]);
|
||||||
|
/* Not implemented. */
|
||||||
pid_t fork(void);
|
pid_t fork(void);
|
||||||
long syscall(long, ...);
|
|
||||||
unsigned int sleep(unsigned int);
|
|
||||||
|
|
||||||
ssize_t read(int, void*, size_t);
|
/* Calls the kernel for a specific service, determined by number. */
|
||||||
ssize_t write(int, const void*, size_t);
|
long syscall(long number, ...);
|
||||||
int close(int);
|
|
||||||
|
/* 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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,6 @@
|
|||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#define noreturn __attribute__((noreturn))
|
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
pid_t gettid()
|
pid_t gettid()
|
||||||
@ -21,7 +19,7 @@ extern "C"
|
|||||||
|
|
||||||
noreturn void __luna_abort(const char* message)
|
noreturn void __luna_abort(const char* message)
|
||||||
{
|
{
|
||||||
fwrite(message, strlen(message), 1, stdout);
|
fputs(message, stderr);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,11 +3,6 @@
|
|||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#define noreturn __attribute__((noreturn))
|
|
||||||
|
|
||||||
#define maybe_unused __attribute__((maybe_unused))
|
|
||||||
#define unused __attribute__((unused))
|
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
noreturn void abort()
|
noreturn void abort()
|
||||||
@ -25,10 +20,12 @@ extern "C"
|
|||||||
{
|
{
|
||||||
NOT_IMPLEMENTED("atexit");
|
NOT_IMPLEMENTED("atexit");
|
||||||
}
|
}
|
||||||
|
|
||||||
int atoi(const char*)
|
int atoi(const char*)
|
||||||
{
|
{
|
||||||
NOT_IMPLEMENTED("atoi");
|
NOT_IMPLEMENTED("atoi");
|
||||||
}
|
}
|
||||||
|
|
||||||
char* getenv(const char*)
|
char* getenv(const char*)
|
||||||
{
|
{
|
||||||
NOT_IMPLEMENTED("getenv");
|
NOT_IMPLEMENTED("getenv");
|
||||||
|
@ -10,18 +10,18 @@ extern "C"
|
|||||||
return dest;
|
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; }
|
for (size_t i = 0; i < n; ++i) { *((char*)buf + i) = (char)c; }
|
||||||
return dest;
|
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)
|
for (; *i; ++i)
|
||||||
;
|
;
|
||||||
return (i - s);
|
return (i - str);
|
||||||
}
|
}
|
||||||
|
|
||||||
char* strcpy(char* dest, const char* src)
|
char* strcpy(char* dest, const char* src)
|
||||||
@ -30,10 +30,10 @@ extern "C"
|
|||||||
return dest;
|
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
|
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;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,40 +49,40 @@ extern "C"
|
|||||||
return dest;
|
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 dest_len = strlen(dest);
|
||||||
size_t i;
|
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';
|
*(char*)(dest + dest_len + i) = '\0';
|
||||||
|
|
||||||
return dest;
|
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);
|
if (*str) return const_cast<char*>(str);
|
||||||
return NULL;
|
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
|
// "i" is our counter of how many bytes we've cleared
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
// find out if "m_start" is aligned on a SSE_XMM_SIZE boundary
|
// 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;
|
i = 0;
|
||||||
|
|
||||||
// we need to clear byte-by-byte until "m_start" is aligned on an SSE_XMM_SIZE boundary
|
// 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)
|
// ... 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++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -93,42 +93,42 @@ extern "C"
|
|||||||
}
|
}
|
||||||
|
|
||||||
// clear 64-byte chunks of memory (4 16-byte operations)
|
// 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
|
asm volatile(" pxor %%xmm0, %%xmm0; " // set XMM0 to 0
|
||||||
" movdqa %%xmm0, 0(%0); " // move 16 bytes from XMM0 to %0 + 0
|
" movdqa %%xmm0, 0(%0); " // move 16 bytes from XMM0 to %0 + 0
|
||||||
" movdqa %%xmm0, 16(%0); "
|
" movdqa %%xmm0, 16(%0); "
|
||||||
" movdqa %%xmm0, 32(%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)
|
// 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" 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
|
// 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 push_options
|
||||||
#pragma GCC diagnostic ignored "-Wwrite-strings"
|
#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 EPERM: return "Operation not permitted";
|
||||||
case EINVAL: return "Invalid argument";
|
case EINVAL: return "Invalid argument";
|
||||||
case ENOMEM: return "Out of memory";
|
case ENOMEM: return "Cannot allocate memory";
|
||||||
case ENOSYS: return "Function not implemented";
|
case ENOSYS: return "Function not implemented";
|
||||||
case ENOENT: return "No such file or directory";
|
case ENOENT: return "No such file or directory";
|
||||||
case EBADF: return "Bad file descriptor";
|
case EBADF: return "Bad file descriptor";
|
||||||
case EMFILE: return "Too many open files";
|
case EMFILE: return "Too many open files";
|
||||||
case EISDIR: return "Is a directory";
|
case EISDIR: return "Is a directory";
|
||||||
case 0: return "Success";
|
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