Files
Lints/efi-port/core/src/compat.c
2025-11-29 13:34:21 +01:00

320 lines
8.0 KiB
C

#include <Uefi.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PrintLib.h>
#include <Library/UefiBootServicesTableLib.h>
// EDK2 CRT Support Header
#include <CrtLibSupport.h>
// Global variables required by CrtLibSupport.h
int errno = 0;
FILE *stderr = NULL;
// Better malloc/free with size tracking
typedef struct {
size_t size;
char data[];
} AllocHeader;
void *my_malloc(size_t size) {
AllocHeader *hdr;
if (gBS->AllocatePool(EfiLoaderData, size + sizeof(AllocHeader), (void**)&hdr) != EFI_SUCCESS) {
return NULL;
}
hdr->size = size;
return hdr->data;
}
void my_free(void *ptr) {
if (ptr) {
AllocHeader *hdr = (AllocHeader*)((char*)ptr - sizeof(AllocHeader));
gBS->FreePool(hdr);
}
}
void *my_realloc(void *ptr, size_t size) {
if (!ptr) return my_malloc(size);
if (size == 0) {
my_free(ptr);
return NULL;
}
AllocHeader *old_hdr = (AllocHeader*)((char*)ptr - sizeof(AllocHeader));
size_t old_size = old_hdr->size;
void *new_ptr = my_malloc(size);
if (!new_ptr) return NULL;
CopyMem(new_ptr, ptr, old_size < size ? old_size : size);
my_free(ptr);
return new_ptr;
}
// Redirect standard malloc/free/realloc to our versions
#undef malloc
#undef free
#undef realloc
void *malloc(size_t size) { return my_malloc(size); }
void free(void *ptr) { my_free(ptr); }
void *realloc(void *ptr, size_t size) { return my_realloc(ptr, size); }
void *calloc(size_t nmemb, size_t size) {
size_t total = nmemb * size;
void *ptr = malloc(total);
if (ptr) {
SetMem(ptr, total, 0);
}
return ptr;
}
// IO
int printf(const char *format, ...) {
return 0;
}
int vsnprintf(char *str, size_t size, const char *format, va_list ap) {
return (int)AsciiVSPrint(str, size, format, ap);
}
int snprintf(char *str, size_t size, const char *format, ...) {
VA_LIST Marker;
VA_START(Marker, format);
UINTN Return = AsciiVSPrint(str, size, format, Marker);
VA_END(Marker);
return (int)Return;
}
// sprintf is a macro in CrtLibSupport.h, so we don't define it.
// Math
// Duktape needs math. EDK2 doesn't provide standard math lib.
// We might need to implement simple versions or pull in a math lib.
// For now, stubs.
double floor(double x) { return (double)(int)x; } // Very wrong for negative/large
double ceil(double x) { return (double)(int)x + 1; }
double fabs(double x) { return x < 0 ? -x : x; }
double pow(double x, double y) { return 0; } // TODO
double sqrt(double x) { return 0; }
double sin(double x) { return 0; }
double cos(double x) { return 0; }
double tan(double x) { return 0; }
double asin(double x) { return 0; }
double acos(double x) { return 0; }
double atan(double x) { return 0; }
double atan2(double y, double x) { return 0; }
double exp(double x) { return 0; }
double log(double x) { return 0; }
double log10(double x) { return 0; }
double fmod(double x, double y) { return 0; }
// Other
void abort(void) {
// CpuDeadLoop();
while(1);
}
void exit(int status) {
// CpuDeadLoop();
while(1);
}
// Global gBS
EFI_BOOT_SERVICES *gBS = NULL;
int _fltused = 0;
// Stack probe (needed for MSVC ABI)
void __chkstk(void) { return; }
// Memory functions
#undef memset
#undef memcpy
#undef memcmp
void *memset(void *s, int c, size_t n) {
unsigned char *p = s;
while (n--) {
*p++ = (unsigned char)c;
}
return s;
}
void *memcpy(void *dest, const void *src, size_t n) {
char *d = dest;
const char *s = src;
while (n--) {
*d++ = *s++;
}
return dest;
}
int memcmp(const void *s1, const void *s2, size_t n) {
const unsigned char *p1 = s1, *p2 = s2;
while (n--) {
if (*p1 != *p2) {
return *p1 - *p2;
}
p1++;
p2++;
}
return 0;
}
void *SetMem(void *Buffer, UINTN Length, UINT8 Value) {
return memset(Buffer, Value, Length);
}
void *CopyMem(void *Destination, const void *Source, UINTN Length) {
return memcpy(Destination, Source, Length);
}
INTN CompareMem(const void *Destination, const void *Source, UINTN Length) {
return (INTN)memcmp(Destination, Source, Length);
}
// String functions
UINTN AsciiStrnLenS(const CHAR8 *String, UINTN MaxSize) {
UINTN len = 0;
while (len < MaxSize && String[len] != 0) {
len++;
}
return len;
}
INTN AsciiStrnCmp(const CHAR8 *FirstString, const CHAR8 *SecondString, UINTN Length) {
if (Length == 0) return 0;
while (Length > 0 && *FirstString && *SecondString) {
if (*FirstString != *SecondString) break;
FirstString++;
SecondString++;
Length--;
}
if (Length == 0) return 0;
return *FirstString - *SecondString;
}
int strcmp(const char *s1, const char *s2) {
while (*s1 && (*s1 == *s2)) {
s1++;
s2++;
}
return *(const unsigned char *)s1 - *(const unsigned char *)s2;
}
// Print functions
// Minimal vsnprintf implementation
#include <stdarg.h>
static void simple_append(char **str, size_t *size, char c) {
if (*size > 1) {
**str = c;
(*str)++;
(*size)--;
}
}
static void simple_append_str(char **str, size_t *size, const char *s) {
while (*s) {
simple_append(str, size, *s++);
}
}
static void simple_append_hex(char **str, size_t *size, UINT64 num) {
char buf[17];
const char *digits = "0123456789ABCDEF";
int i = 0;
if (num == 0) {
simple_append(str, size, '0');
return;
}
while (num > 0) {
buf[i++] = digits[num % 16];
num /= 16;
}
while (i > 0) {
simple_append(str, size, buf[--i]);
}
}
static void simple_append_dec(char **str, size_t *size, INT64 num) {
char buf[21];
int i = 0;
int neg = 0;
if (num < 0) {
neg = 1;
num = -num;
}
if (num == 0) {
simple_append(str, size, '0');
return;
}
while (num > 0) {
buf[i++] = (num % 10) + '0';
num /= 10;
}
if (neg) simple_append(str, size, '-');
while (i > 0) {
simple_append(str, size, buf[--i]);
}
}
UINTN AsciiVSPrint(CHAR8 *StartOfBuffer, UINTN BufferSize, CONST CHAR8 *FormatString, VA_LIST Marker) {
char *str = StartOfBuffer;
size_t size = BufferSize;
const char *fmt = FormatString;
while (*fmt) {
if (*fmt == '%') {
fmt++;
if (*fmt == 's') {
char *s = VA_ARG(Marker, char*);
simple_append_str(&str, &size, s ? s : "(null)");
} else if (*fmt == 'd') {
int d = VA_ARG(Marker, int);
simple_append_dec(&str, &size, d);
} else if (*fmt == 'x' || *fmt == 'X') {
unsigned int x = VA_ARG(Marker, unsigned int);
simple_append_hex(&str, &size, x);
} else if (*fmt == 'p') {
void *p = VA_ARG(Marker, void*);
simple_append_hex(&str, &size, (UINT64)p);
} else if (*fmt == '%') {
simple_append(&str, &size, '%');
} else {
simple_append(&str, &size, '%');
simple_append(&str, &size, *fmt);
}
} else {
simple_append(&str, &size, *fmt);
}
fmt++;
}
*str = 0;
return (UINTN)(str - StartOfBuffer);
}
UINTN AsciiSPrint(CHAR8 *StartOfBuffer, UINTN BufferSize, CONST CHAR8 *FormatString, ...) {
VA_LIST Marker;
VA_START(Marker, FormatString);
UINTN ret = AsciiVSPrint(StartOfBuffer, BufferSize, FormatString, Marker);
VA_END(Marker);
return ret;
}
// Time functions
struct tm *gmtime(const time_t *timep) { return NULL; }
time_t mktime(struct tm *tm) { return 0; }
int sscanf(const char *str, const char *format, ...) { return 0; }
time_t time(time_t *tloc) { return 0; }
double difftime(time_t time1, time_t time0) { return (double)(time1 - time0); }
double cbrt(double x) { return 0; }
double log2(double x) { return 0; }
double trunc(double x) { return (double)(int)x; }
// Needed for CrtLibSupport headers to work?
// They use VA_LIST etc which are in Base.h