Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/stdarg.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

// Custom stdarg implementation for freestanding environments (GCC/Clang)

typedef char* va_list;
typedef __builtin_va_list va_list;

#define va_start(v,l) __builtin_va_start(v,l)
#define va_arg(v,t) __builtin_va_arg(v,t)
Expand Down
89 changes: 55 additions & 34 deletions kernel/etc/Console.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
// kernel/etc/Console.c - PATCHED VERSION WITH VBE SUPPORT
#include "Console.h"

#include "Format.h"
#include "Io.h"
#include "Serial.h"
#include "Spinlock.h"
#include "VBEConsole.h"
#include "VesaBIOSExtension.h"
#include "stdarg.h"
#include "stdbool.h"
#include "stdint.h"

Expand All @@ -13,7 +16,7 @@ static uint8_t use_vbe = 0;
// Original VGA implementation preserved
static void UpdateCursor(void) {
if (use_vbe) return; // VBE handles cursor internally

uint16_t pos = console.line * VGA_WIDTH + console.column;
outb(0x3D4, 0x0F);
outb(0x3D5, (uint8_t)(pos & 0xFF));
Expand All @@ -33,31 +36,6 @@ static volatile int lock = 0;
static uint32_t vbe_fg_color = 0xFFFFFF; // White
static uint32_t vbe_bg_color = 0x000000; // Black

// static void SetVBEColors(uint8_t vga_color) {
// // Convert VGA color attributes to RGB
// static const uint32_t vga_to_rgb[16] = {
// 0x000000, // Black
// 0x0000AA, // Blue
// 0x00AA00, // Green
// 0x00AAAA, // Cyan
// 0xAA0000, // Red
// 0xAA00AA, // Magenta
// 0xAA5500, // Brown
// 0xAAAAAA, // Light Gray
// 0x555555, // Dark Gray
// 0x5555FF, // Light Blue
// 0x55FF55, // Light Green
// 0x55FFFF, // Light Cyan (This might be your cyan flash!)
// 0xFF5555, // Light Red
// 0xFF55FF, // Light Magenta
// 0xFFFF55, // Yellow
// 0xFFFFFF // White
// };
//
// vbe_fg_color = vga_to_rgb[vga_color & 0x0F];
// vbe_bg_color = vga_to_rgb[(vga_color >> 4) & 0x0F];
// }

// Initialize console - auto-detect VBE or VGA
void ConsoleInit(void) {
if (VBEIsInitialized()) {
Expand All @@ -76,20 +54,20 @@ static inline uint16_t MakeVGAEntry(char c, uint8_t color) {

static void ConsolePutcharAt(char c, uint32_t x, uint32_t y, uint8_t color) {
if (use_vbe) return; // VBE handles this differently

if (x >= VGA_WIDTH || y >= VGA_HEIGHT) return;
const uint32_t index = y * VGA_WIDTH + x;
console.buffer[index] = MakeVGAEntry(c, color);
}

void ClearScreen(void) {
SpinLock(&lock);

if (use_vbe) {
VBEConsoleClear();
} else {
if (!console.buffer) console.buffer = (volatile uint16_t*)VGA_BUFFER_ADDR;

const uint16_t blank = MakeVGAEntry(' ', VGA_COLOR_DEFAULT);
volatile uint32_t* buffer32 = (volatile uint32_t*)console.buffer;
const uint32_t blank32 = ((uint32_t)blank << 16) | blank;
Expand All @@ -103,13 +81,13 @@ void ClearScreen(void) {
console.column = 0;
UpdateCursor();
}

SpinUnlock(&lock);
}

static void ConsoleScroll(void) {
if (use_vbe) return; // VBE handles scrolling internally

for (uint32_t i = 0; i < (VGA_HEIGHT - 1) * VGA_WIDTH; i++) {
console.buffer[i] = console.buffer[i + VGA_WIDTH];
}
Expand Down Expand Up @@ -173,7 +151,7 @@ void ConsoleSetColor(uint8_t color) {
void PrintKernel(const char* str) {
if (!str) return;
SpinLock(&lock);

if (use_vbe) {
VBEConsolePrint(str);
} else {
Expand All @@ -183,7 +161,7 @@ void PrintKernel(const char* str) {
}
console.color = original_color;
}

SpinUnlock(&lock);
SerialWrite(str);
}
Expand All @@ -196,20 +174,27 @@ void PrintKernelChar(const char c) {
PrintKernel(str);
}

void PrintKernelBadge(const char * str) {
PrintKernelF("[ %s ] ", str);
}

void PrintKernelSuccess(const char* str) {
ConsoleSetColor(VGA_COLOR_WHITE);
PrintKernelBadge("SUCCESS");
PrintKernel(str);
ConsoleSetColor(VGA_COLOR_DEFAULT);
}

void PrintKernelError(const char* str) {
ConsoleSetColor(VGA_COLOR_ERROR);
PrintKernelBadge("ERROR");
PrintKernel(str);
ConsoleSetColor(VGA_COLOR_DEFAULT);
}

void PrintKernelWarning(const char* str) {
ConsoleSetColor(VGA_COLOR_WARNING);
PrintKernelBadge("WARNING");
PrintKernel(str);
ConsoleSetColor(VGA_COLOR_DEFAULT);
}
Expand Down Expand Up @@ -240,6 +225,42 @@ void PrintKernelHex(uint64_t num) {
PrintKernel(&buffer[pos + 1]);
}

void PrintKernelF(const char* format, ...) {
va_list args;
va_start(args, format);
char* formatted = Format(format, args);
va_end(args);

PrintKernel(formatted);
}

void PrintKernelWarningF(const char* format, ...) {
va_list args;
va_start(args, format);
char* formatted = Format(format, args);
va_end(args);

PrintKernelWarning(formatted);
}

void PrintKernelErrorF(const char* format, ...) {
va_list args;
va_start(args, format);
char* formatted = Format(format, args);
va_end(args);

PrintKernelError(formatted);
}

void SerialWriteF(const char* format, ...) {
va_list args;
va_start(args, format);
char* formatted = Format(format, args);
va_end(args);

SerialWrite(formatted);
}
Comment on lines +228 to +262
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

Use-after-return: Format() result is invalid; format into a local buffer and pass it on

All four variadic wrappers pass the pointer returned by Format() to printers. With the current implementation, that pointer refers to a stack buffer that no longer exists, leading to undefined behavior, random output, and potential faults under optimization.

Switch to caller-allocated buffers and use a bounded va_list-based formatter.

Apply this diff (assumes the refactored VFormat API in Format.h/Format.c):

 void PrintKernelF(const char* format, ...) {
-    va_list args;
-    va_start(args, format);
-    char* formatted = Format(format, args);
-    va_end(args);
-
-    PrintKernel(formatted);
+    char buf[CHAR_BUFF];
+    va_list args;
+    va_start(args, format);
+    VFormat(buf, (int)sizeof(buf), format, args);
+    va_end(args);
+    PrintKernel(buf);
 }
 
 void PrintKernelWarningF(const char* format, ...) {
-    va_list args;
-    va_start(args, format);
-    char* formatted = Format(format, args);
-    va_end(args);
-
-    PrintKernelWarning(formatted);
+    char buf[CHAR_BUFF];
+    va_list args;
+    va_start(args, format);
+    VFormat(buf, (int)sizeof(buf), format, args);
+    va_end(args);
+    PrintKernelWarning(buf);
 }
 
 void PrintKernelErrorF(const char* format, ...) {
-    va_list args;
-    va_start(args, format);
-    char* formatted = Format(format, args);
-    va_end(args);
-
-    PrintKernelError(formatted);
+    char buf[CHAR_BUFF];
+    va_list args;
+    va_start(args, format);
+    VFormat(buf, (int)sizeof(buf), format, args);
+    va_end(args);
+    PrintKernelError(buf);
 }
 
 void SerialWriteF(const char* format, ...) {
-    va_list args;
-    va_start(args, format);
-    char* formatted = Format(format, args);
-    va_end(args);
-
-    SerialWrite(formatted);
+    char buf[CHAR_BUFF];
+    va_list args;
+    va_start(args, format);
+    VFormat(buf, (int)sizeof(buf), format, args);
+    va_end(args);
+    SerialWrite(buf);
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
void PrintKernelF(const char* format, ...) {
va_list args;
va_start(args, format);
char* formatted = Format(format, args);
va_end(args);
PrintKernel(formatted);
}
void PrintKernelWarningF(const char* format, ...) {
va_list args;
va_start(args, format);
char* formatted = Format(format, args);
va_end(args);
PrintKernelWarning(formatted);
}
void PrintKernelErrorF(const char* format, ...) {
va_list args;
va_start(args, format);
char* formatted = Format(format, args);
va_end(args);
PrintKernelError(formatted);
}
void SerialWriteF(const char* format, ...) {
va_list args;
va_start(args, format);
char* formatted = Format(format, args);
va_end(args);
SerialWrite(formatted);
}
void PrintKernelF(const char* format, ...) {
char buf[CHAR_BUFF];
va_list args;
va_start(args, format);
VFormat(buf, (int)sizeof(buf), format, args);
va_end(args);
PrintKernel(buf);
}
void PrintKernelWarningF(const char* format, ...) {
char buf[CHAR_BUFF];
va_list args;
va_start(args, format);
VFormat(buf, (int)sizeof(buf), format, args);
va_end(args);
PrintKernelWarning(buf);
}
void PrintKernelErrorF(const char* format, ...) {
char buf[CHAR_BUFF];
va_list args;
va_start(args, format);
VFormat(buf, (int)sizeof(buf), format, args);
va_end(args);
PrintKernelError(buf);
}
void SerialWriteF(const char* format, ...) {
char buf[CHAR_BUFF];
va_list args;
va_start(args, format);
VFormat(buf, (int)sizeof(buf), format, args);
va_end(args);
SerialWrite(buf);
}
🤖 Prompt for AI Agents
In kernel/etc/Console.c around lines 228-262, the wrappers call Format() which
returns a pointer into a stack buffer that is no longer valid; replace that
pattern by allocating a caller-owned buffer on the stack (e.g. char
buf[BUFFER_SIZE]), start the va_list, call the refactored VFormat(buffer, sizeof
buffer, format, args) to write into the bounded buffer, end the va_list, then
pass the buffer to PrintKernel/PrintKernelWarning/PrintKernelError/SerialWrite;
ensure you use va_start and va_end correctly and choose a safe buffer size to
avoid overflow.


void PrintKernelInt(int64_t num) {
char buffer[21];

Expand Down Expand Up @@ -276,7 +297,7 @@ void PrintKernelAt(const char* str, uint32_t line, uint32_t col) {
VBEConsolePrint(str);
} else {
if (line >= VGA_HEIGHT || col >= VGA_WIDTH) return;

const uint32_t saved_line = console.line;
const uint32_t saved_col = console.column;

Expand Down
33 changes: 28 additions & 5 deletions kernel/etc/Console.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,29 @@
#define VGA_HEIGHT 25
#define VGA_BUFFER_SIZE (VGA_WIDTH * VGA_HEIGHT)

#define VGA_COLOR_DEFAULT 0x07
#define VGA_COLOR_SUCCESS 0x0B
#define VGA_COLOR_ERROR 0x0C
#define VGA_COLOR_WARNING 0x0E
#define VGA_COLOR_WHITE 0x0F
#define VGA_COLOR_BLACK 0x00
#define VGA_COLOR_BLUE 0x01
#define VGA_COLOR_GREEN 0x02
#define VGA_COLOR_CYAN 0x03
#define VGA_COLOR_RED 0x04
#define VGA_COLOR_MAGENTA 0x05
#define VGA_COLOR_BROWN 0x06
#define VGA_COLOR_LIGHT_GREY 0x07
#define VGA_COLOR_DARK_GREY 0x08
#define VGA_COLOR_LIGHT_BLUE 0x09
#define VGA_COLOR_LIGHT_GREEN 0x0A
#define VGA_COLOR_LIGHT_CYAN 0x0B
#define VGA_COLOR_LIGHT_RED 0x0C
#define VGA_COLOR_LIGHT_MAGENTA 0x0D
#define VGA_COLOR_LIGHT_YELLOW 0x0E
#define VGA_COLOR_WHITE 0x0F

#define VGA_COLOR_DEFAULT VGA_COLOR_LIGHT_GREY
#define VGA_COLOR_SUCCESS VGA_COLOR_LIGHT_GREEN
#define VGA_COLOR_ERROR VGA_COLOR_LIGHT_RED
#define VGA_COLOR_WARNING VGA_COLOR_LIGHT_YELLOW



#include "stdint.h"
// Console state
Expand Down Expand Up @@ -45,5 +63,10 @@ void PrintKernelAt(const char* str, uint32_t line, uint32_t col);
void ClearScreen();
void ConsoleSetColor(uint8_t color);
void ConsoleInit(void);
// formated functions
void PrintKernelF(const char* format, ...);
void SerialWriteF(const char* format, ...);
void PrintKernelErrorF(const char* format, ...);
void PrintKernelWarningF(const char* format, ...);

#endif // VOIDFRAME_CONSOLE_H
Loading