diff --git a/game/kernel/common/kprint.cpp b/game/kernel/common/kprint.cpp index 75960e47e8..1f2bc4df49 100644 --- a/game/kernel/common/kprint.cpp +++ b/game/kernel/common/kprint.cpp @@ -32,6 +32,7 @@ Ptr OutputBufArea; // Pointer to print buffer, the buffer for printing and string formatting. Ptr PrintBufArea; +size_t PrintBufSize = 0; // integer printing conversion table char ConvertTable[16]; @@ -49,6 +50,7 @@ void kprint_init_globals_common() { MessBufArea.offset = 0; OutputBufArea.offset = 0; PrintBufArea.offset = 0; + PrintBufSize = 0; memcpy(ConvertTable, "0123456789abcdef", 16); memset(AckBufArea, 0, sizeof(AckBufArea)); } @@ -83,6 +85,7 @@ void init_output() { KMALLOC_MEMSET | KMALLOC_ALIGN_256, "output-buf"); PrintBufArea = kmalloc(kdebugheap, DEBUG_PRINT_BUFFER_SIZE, KMALLOC_MEMSET | KMALLOC_ALIGN_256, "print-buf"); + PrintBufSize = DEBUG_PRINT_BUFFER_SIZE; } else { // no compiler connection, so we do not allocate buffers MessBufArea = Ptr(0); @@ -91,6 +94,7 @@ void init_output() { // we still need a (small) print buffer for string maniuplation and debugging prints. PrintBufArea = kmalloc(kglobalheap, PRINT_BUFFER_SIZE, KMALLOC_MEMSET | KMALLOC_ALIGN_256, "print-buf"); + PrintBufSize = PRINT_BUFFER_SIZE; } } @@ -574,3 +578,10 @@ char* kitoa(char* buffer, s64 value, u64 base, s32 length, char pad, u32 flag) { void kqtoa() { ASSERT(false); } + +void assert_print_buffer_has_room(const u8* ptr) { + const size_t size_used = ptr - PrintBufArea.c(); + if (size_used > (PrintBufSize - 1024)) { + lg::die("Print Buffer Overflow: size 0x{:x} of 0x{:x}", size_used, PrintBufSize); + } +} diff --git a/game/kernel/common/kprint.h b/game/kernel/common/kprint.h index 765497efcf..2215f5b69a 100644 --- a/game/kernel/common/kprint.h +++ b/game/kernel/common/kprint.h @@ -15,11 +15,12 @@ extern char ConvertTable[16]; // todo rm extern Ptr MessBufArea; extern Ptr OutputBufArea; extern Ptr PrintBufArea; +extern size_t PrintBufSize; // added constexpr u32 DEBUG_MESSAGE_BUFFER_SIZE = 0x80000; constexpr u32 DEBUG_OUTPUT_BUFFER_SIZE = 0x80000; constexpr u32 DEBUG_PRINT_BUFFER_SIZE = 0x200000; -constexpr u32 PRINT_BUFFER_SIZE = 0x8000; // upped from 0x2000 on PS2 because we ran out of memory +constexpr u32 PRINT_BUFFER_SIZE = 0x10000; // upped from 0x2000 on PS2 because we ran out of memory struct format_struct { char data[0x40]; @@ -142,3 +143,8 @@ char* kitoa(char* buffer, s64 value, u64 base, s32 length, char pad, u32 flag); * getting a 128-bit integer in PS2 gcc's varargs doesn't work. */ void kqtoa(); + +/*! + * Make sure we have at least 1024 bytes left in the print buffer. + */ +void assert_print_buffer_has_room(const u8* ptr); \ No newline at end of file diff --git a/game/kernel/jak1/kprint.cpp b/game/kernel/jak1/kprint.cpp index 6abeb8e2d4..ee714a3986 100644 --- a/game/kernel/jak1/kprint.cpp +++ b/game/kernel/jak1/kprint.cpp @@ -54,6 +54,7 @@ s32 format_impl_jak1(uint64_t* args) { print_temp = PrintBufArea.cast().c() + sizeof(ListenerMessageHeader); } PrintPending = make_ptr(strend(print_temp)).cast(); + assert_print_buffer_has_room(PrintPending.c()); // what we write to char* output_ptr = PrintPending.cast().c(); @@ -498,6 +499,7 @@ s32 format_impl_jak1(uint64_t* args) { // end *output_ptr = 0; output_ptr++; + assert_print_buffer_has_room((const u8*)output_ptr); if (original_dest == s7.offset + FIX_SYM_TRUE) { // do nothing, we're done diff --git a/game/kernel/jak2/kprint.cpp b/game/kernel/jak2/kprint.cpp index c1e7fc5363..4abb0406dd 100644 --- a/game/kernel/jak2/kprint.cpp +++ b/game/kernel/jak2/kprint.cpp @@ -77,6 +77,7 @@ s32 format_impl_jak2(uint64_t* args) { print_temp = PrintBufArea.cast().c() + sizeof(ListenerMessageHeader); } PrintPending = make_ptr(strend(print_temp)).cast(); + assert_print_buffer_has_room(PrintPending.c()); // what we write to char* output_ptr = PrintPending.cast().c(); @@ -535,6 +536,7 @@ s32 format_impl_jak2(uint64_t* args) { // end *output_ptr = 0; output_ptr++; + assert_print_buffer_has_room((const u8*)output_ptr); if (original_dest == s7.offset + FIX_SYM_TRUE) { // #t means to put it in the print buffer diff --git a/game/kernel/jak3/kprint.cpp b/game/kernel/jak3/kprint.cpp index 532b024f5d..f0dee86a87 100644 --- a/game/kernel/jak3/kprint.cpp +++ b/game/kernel/jak3/kprint.cpp @@ -47,6 +47,7 @@ s32 format_impl_jak3(uint64_t* args) { print_temp = PrintBufArea.cast().c() + sizeof(ListenerMessageHeader); } PrintPending = make_ptr(strend(print_temp)).cast(); + assert_print_buffer_has_room(PrintPending.c()); // what we write to char* output_ptr = PrintPending.cast().c(); @@ -505,6 +506,7 @@ s32 format_impl_jak3(uint64_t* args) { // end *output_ptr = 0; output_ptr++; + assert_print_buffer_has_room((const u8*)output_ptr); if (original_dest == s7.offset + FIX_SYM_TRUE) { // #t means to put it in the print buffer