From e939fc0ced4d445c24696636fe660dddbe035b1c Mon Sep 17 00:00:00 2001 From: John Hodge Date: Thu, 3 Jun 2010 11:23:19 +0800 Subject: [PATCH] Bugfixing - Fixing bug in module loader with x86_64 - Fixed debug reusing a va_list --- Kernel/arch/x86_64/include/arch.h | 1 + Kernel/arch/x86_64/link.ld | 15 ++---- Kernel/arch/x86_64/mm_phys.c | 2 +- Kernel/arch/x86_64/mm_virt.c | 5 -- Kernel/debug.c | 14 ++--- Kernel/drv/proc.c | 21 ++++---- Kernel/heap.c | 32 +++++++++-- Kernel/include/heap.h | 2 +- Kernel/include/modules.h | 3 +- Kernel/lib.c | 5 +- Kernel/logging.c | 4 +- Kernel/modules.c | 90 ++++++++++++++++++++++++++----- Modules/IPStack/ipv4.h | 2 +- Modules/IPStack/ipv6.h | 2 +- Modules/IPStack/link.c | 5 +- Modules/USB/Core/main.c | 6 +-- Modules/USB/Core/usb.h | 4 +- 17 files changed, 147 insertions(+), 66 deletions(-) diff --git a/Kernel/arch/x86_64/include/arch.h b/Kernel/arch/x86_64/include/arch.h index 5ea3d886..9b3801bb 100644 --- a/Kernel/arch/x86_64/include/arch.h +++ b/Kernel/arch/x86_64/include/arch.h @@ -24,6 +24,7 @@ typedef signed long long int Sint64; typedef unsigned long long int Uint64; #endif +typedef Sint64 Sint; typedef Uint64 Uint; typedef Uint64 tPAddr; typedef Uint64 tVAddr; diff --git a/Kernel/arch/x86_64/link.ld b/Kernel/arch/x86_64/link.ld index 451bb306..b688c7ad 100644 --- a/Kernel/arch/x86_64/link.ld +++ b/Kernel/arch/x86_64/link.ld @@ -34,25 +34,16 @@ SECTIONS { *(.initpd) *(.rodata) *(.rdata) + + . = ALIGN(0x10); gKernelModules = .; *(KMODULES) gKernelModulesEnd = .; - . = ALIGN(4); + . = ALIGN(0x10); gKernelSymbols = .; *(KEXPORT) gKernelSymbolsEnd = .; } - /* - .debug_abbrev : { *(.debug_abbrev) } - .debug_info : { *(.debug_info) } - .debug_line : { *(.debug_line) } - .debug_loc : { *(.debug_loc) } - .debug_pubnames : { *(.debug_pubnames) } - .debug_aranges : { *(.debug_aranges) } - .debug_ranges : { *(.debug_ranges) } - .debug_str : { *(.debug_str) } - .debug_frame : { *(.debug_frame) } - */ .padata ALIGN (0x1000) : AT(ADDR(.padata) - _kernel_base) { *(.padata) diff --git a/Kernel/arch/x86_64/mm_phys.c b/Kernel/arch/x86_64/mm_phys.c index c67a28e8..a5f6f276 100644 --- a/Kernel/arch/x86_64/mm_phys.c +++ b/Kernel/arch/x86_64/mm_phys.c @@ -3,7 +3,7 @@ * * Physical Memory Manager */ -#define DEBUG 1 +#define DEBUG 0 #include #include #include diff --git a/Kernel/arch/x86_64/mm_virt.c b/Kernel/arch/x86_64/mm_virt.c index 4ec08471..538f6ca9 100644 --- a/Kernel/arch/x86_64/mm_virt.c +++ b/Kernel/arch/x86_64/mm_virt.c @@ -335,19 +335,14 @@ void MM_Deallocate(tVAddr VAddr) */ tPAddr MM_GetPhysAddr(tVAddr Addr) { - Log("MM_GetPhysAddr: (Addr=0x%x)", Addr); if( !(PAGEMAPLVL4(Addr >> 39) & 1) ) return 0; - Log(" MM_GetPhysAddr: PDP Valid"); if( !(PAGEDIRPTR(Addr >> 30) & 1) ) return 0; - Log(" MM_GetPhysAddr: PD Valid"); if( !(PAGEDIR(Addr >> 21) & 1) ) return 0; - Log(" MM_GetPhysAddr: PT Valid"); if( !(PAGETABLE(Addr >> PTAB_SHIFT) & 1) ) return 0; - Log(" MM_GetPhysAddr: Page Valid"); return (PAGETABLE(Addr >> PTAB_SHIFT) & ~0xFFF) | (Addr & 0xFFF); } diff --git a/Kernel/debug.c b/Kernel/debug.c index b9e5cdc6..06fb0709 100644 --- a/Kernel/debug.c +++ b/Kernel/debug.c @@ -9,7 +9,7 @@ #define DEBUG_TO_SERIAL 1 #define SERIAL_PORT 0x3F8 #define GDB_SERIAL_PORT 0x2F8 -#define DEBUG_USE_VSNPRINTF 1 +#define DEBUG_USE_VSNPRINTF 0 #define DEBUG_MAX_LINE_LEN 256 // === IMPORTS === @@ -144,6 +144,7 @@ void Debug_Fmt(const char *format, va_list args) #if DEBUG_USE_VSNPRINTF char buf[DEBUG_MAX_LINE_LEN]; int len; + buf[DEBUG_MAX_LINE_LEN-1] = 0; len = vsnprintf(buf, DEBUG_MAX_LINE_LEN-1, format, args); //if( len < DEBUG_MAX_LINE ) // do something @@ -176,7 +177,7 @@ void Debug_Fmt(const char *format, va_list args) // Pointer if(c == 'p') { - Uint ptr = va_arg(*args, Uint); + Uint ptr = va_arg(args, Uint); Debug_Putchar('*'); Debug_Putchar('0'); Debug_Putchar('x'); p = tmpBuf; itoa(p, ptr, 16, BITS/4, '0'); @@ -184,7 +185,7 @@ void Debug_Fmt(const char *format, va_list args) } // Get Argument - arg = va_arg(*args, Uint); + arg = va_arg(args, Uint); // - Padding Side Flag if(c == '+') { @@ -218,7 +219,7 @@ void Debug_Fmt(const char *format, va_list args) c = *format++; if(c == 'l') { #if BITS == 32 - arg |= va_arg(*args, Uint); + arg |= va_arg(args, Uint); #endif c = *format++; isLongLong = 1; @@ -389,9 +390,8 @@ void Debug_Enter(char *FuncName, char *ArgTypes, ...) case 'u': Debug_Fmt("%u", args); break; case 'x': Debug_Fmt("0x%x", args); break; case 'b': Debug_Fmt("0b%b", args); break; - // Extended (64-Bit) - case 'X': Debug_Fmt("0x%llx", args); break; - case 'B': Debug_Fmt("0b%llb", args); break; + case 'X': Debug_Fmt("0x%llx", args); break; // Extended (64-Bit) + case 'B': Debug_Fmt("0b%llb", args); break; // Extended (64-Bit) } if(pos != -1) { Debug_Putchar(','); Debug_Putchar(' '); diff --git a/Kernel/drv/proc.c b/Kernel/drv/proc.c index c007c326..521bb055 100644 --- a/Kernel/drv/proc.c +++ b/Kernel/drv/proc.c @@ -18,8 +18,8 @@ typedef struct sSysFS_Ent struct sSysFS_Ent *Next; struct sSysFS_Ent *ListNext; struct sSysFS_Ent *Parent; - char *Name; tVFS_Node Node; + char Name[]; } tSysFS_Ent; // === PROTOTYPES === @@ -42,7 +42,6 @@ MODULE_DEFINE(0, VERSION, SysFS, SysFS_Install, NULL, NULL); tSysFS_Ent gSysFS_Version_Kernel = { NULL, NULL, // Nexts &gSysFS_Version, // Parent - "Kernel", { .Inode = 1, // File #1 .ImplPtr = KERNEL_VERSION_STRING, @@ -51,12 +50,12 @@ tSysFS_Ent gSysFS_Version_Kernel = { .NumACLs = 1, .ACLs = &gVFS_ACL_EveryoneRO, .Read = SysFS_Comm_ReadFile - } + }, + "Kernel" }; tSysFS_Ent gSysFS_Version = { NULL, NULL, &gSysFS_Root, - "Version", { .Size = 1, .ImplPtr = &gSysFS_Version_Kernel, @@ -66,18 +65,19 @@ tSysFS_Ent gSysFS_Version = { .Flags = VFS_FFLAG_DIRECTORY, .ReadDir = SysFS_Comm_ReadDir, .FindDir = SysFS_Comm_FindDir - } + }, + "Version" }; // Root of the SysFS tree (just used to keep the code clean) tSysFS_Ent gSysFS_Root = { NULL, NULL, NULL, - "/", { .Size = 1, .ImplPtr = &gSysFS_Version, .ImplInt = (Uint)&gSysFS_Root // Self-Link - } + }, + "/" }; tDevFS_Driver gSysFS_DriverInfo = { NULL, "system", @@ -139,9 +139,8 @@ int SysFS_RegisterFile(char *Path, char *Data, int Length) // Need a new directory? if( !child ) { - child = calloc( 1, sizeof(tSysFS_Ent) ); + child = calloc( 1, sizeof(tSysFS_Ent)+tmp+1 ); child->Next = NULL; - child->Name = malloc(tmp+1); memcpy(child->Name, &Path[start], tmp); child->Name[tmp] = '\0'; child->Parent = ent; @@ -194,9 +193,9 @@ int SysFS_RegisterFile(char *Path, char *Data, int Length) } // Create new node - child = calloc( 1, sizeof(tSysFS_Ent) ); + child = calloc( 1, sizeof(tSysFS_Ent)+strlen(&Path[start])+1 ); child->Next = NULL; - child->Name = strdup(&Path[start]); + strcpy(child->Name, &Path[start]); child->Parent = ent; child->Node.Inode = giSysFS_NextFileID++; diff --git a/Kernel/heap.c b/Kernel/heap.c index 75854b39..920e9b68 100644 --- a/Kernel/heap.c +++ b/Kernel/heap.c @@ -11,7 +11,7 @@ // === CONSTANTS === #define HEAP_INIT_SIZE 0x8000 // 32 KiB -#define BLOCK_SIZE (sizeof(void*)) // 8 Machine Words +#define BLOCK_SIZE (sizeof(void*))*8 // 8 Machine Words #define COMPACT_HEAP 0 // Use 4 byte header? #define FIRST_FIT 0 @@ -345,8 +345,15 @@ void *realloc(void *__ptr, size_t __size) if(nextHead->Magic == MAGIC_FREE && nextHead->Size+head->Size >= newSize) { Uint size = nextHead->Size + head->Size; + // Inexact fit, split things up + if(size > newSize) + { + // TODO + Warning("[Heap ] TODO: Space efficient realloc when new size is smaller"); + } + // Exact fit - if(size == newSize) + if(size >= newSize) { Uint oldDataSize; // Set 1st (new/lower) header @@ -360,11 +367,27 @@ void *realloc(void *__ptr, size_t __size) // Clear old header head->Size = 0; head->Magic = 0; + // Copy data memcpy(nextHead->Data, __ptr, oldDataSize); + // Return + return nextHead->Data; } + // On to the expensive then } - return NULL; + // Well, darn + nextHead = malloc( __size ); + nextHead -= 1; + + memcpy( + nextHead->Data, + __ptr, + head->Size - sizeof(tHeapFoot) - sizeof(tHeapHead) + ); + + free(__ptr); + + return nextHead->Data; } /** @@ -411,7 +434,8 @@ void Heap_Dump() while( (Uint)head < (Uint)gHeapEnd ) { foot = (void*)( (Uint)head + head->Size - sizeof(tHeapFoot) ); - Log_Log("Heap", "%p (0x%x): 0x%08lx 0x%lx", head, MM_GetPhysAddr((Uint)head), head->Size, head->Magic); + Log_Log("Heap", "%p (0x%x): 0x%08lx 0x%lx", + head, MM_GetPhysAddr((Uint)head), head->Size, head->Magic); Log_Log("Heap", "%p 0x%lx", foot->Head, foot->Magic); Log_Log("Heap", ""); diff --git a/Kernel/include/heap.h b/Kernel/include/heap.h index c793c874..8765a96b 100644 --- a/Kernel/include/heap.h +++ b/Kernel/include/heap.h @@ -14,7 +14,7 @@ typedef struct { typedef struct { Uint Magic; tHeapHead *Head; - tHeapHead NextHead[]; // Array to make it act like a pointer, but have no size + tHeapHead NextHead[]; // Array to make it act like a pointer, but have no size and refer to the next block } tHeapFoot; #endif diff --git a/Kernel/include/modules.h b/Kernel/include/modules.h index 8862112c..d4fb49c5 100644 --- a/Kernel/include/modules.h +++ b/Kernel/include/modules.h @@ -36,7 +36,7 @@ #if ARCHDIR == x86 # define MODULE_ARCH_ID 1 // IA64 - Architecture 2 -#elif ARCHDIR == x64 +#elif ARCHDIR == x86_64 # define MODULE_ARCH_ID 2 #else # error "Unknown architecture when determining MODULE_ARCH_ID ('" #ARCHDIR "')" @@ -87,6 +87,7 @@ enum eModuleErrors MODULE_ERR_NOTNEEDED, //!< Module not needed MODULE_ERR_MALLOC, //!< Error with malloc/realloc/calloc + MODULE_ERR_BADMODULE, //!< Bad module (only used by loader) MODULE_ERR_MAX //!< Maximum defined error code }; diff --git a/Kernel/lib.c b/Kernel/lib.c index 116dce61..5decb9fb 100644 --- a/Kernel/lib.c +++ b/Kernel/lib.c @@ -270,7 +270,11 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args) { case 'd': case 'i': + #if BITS == 32 if( (isLongLong && val >> 63) || (!isLongLong && val >> 31) ) { + #else + if( (Sint)val < 0 ) { + #endif PUTCH('-'); val = -val; } @@ -308,7 +312,6 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args) case 'C': // Non-Null Terminated Character Array p = (char*)(Uint)val; if(!p) goto printString; - //while(minSize--) PUTCH(*p++); while(minSize--) PUTCH(*p++); break; diff --git a/Kernel/logging.c b/Kernel/logging.c index 54f16cad..8ca5fd43 100644 --- a/Kernel/logging.c +++ b/Kernel/logging.c @@ -77,10 +77,12 @@ void Log_AddEvent(char *Ident, int Level, char *Format, va_list Args) { int len; tLogEntry *ent; + va_list args_tmp; if( Level >= NUM_LOG_LEVELS ) return; - len = vsnprintf(NULL, 256, Format, Args); + va_copy(args_tmp, Args); + len = vsnprintf(NULL, 256, Format, args_tmp); //Log("len = %i", len); diff --git a/Kernel/modules.c b/Kernel/modules.c index 4b095bc5..68948739 100644 --- a/Kernel/modules.c +++ b/Kernel/modules.c @@ -2,7 +2,7 @@ * Acess2 * - Module Loader */ -#define DEBUG 0 +#define DEBUG 1 #include #include @@ -27,7 +27,7 @@ EXPORT(Module_RegisterLoader); extern int UDI_LoadDriver(void *Base); #endif extern void StartupPrint(char *Str); -extern tModule gKernelModules[]; +extern void gKernelModules; extern void gKernelModulesEnd; // === GLOBALS === @@ -36,6 +36,7 @@ tSpinlock glModuleSpinlock; tModule *gLoadedModules = NULL; tModuleLoader *gModule_Loaders = NULL; tModule *gLoadingModules = NULL; +tModule **gapBuiltinModules = NULL; char **gasBuiltinModuleArgs; // === CODE === @@ -57,6 +58,25 @@ int Module_int_Initialise(tModule *Module, char *ArgString) tModule *mod; ENTER("pModule", Module); + LOG("Module->Magic = 0x%x", Module->Magic); + if(Module->Magic != MODULE_MAGIC) { + Log_Warning( + "Module", + "Module %p is no a valid Acess2 module (0x%08x != 0x%08x)", + Module, Module->Magic, MODULE_MAGIC + ); + LEAVE('i', MODULE_ERR_BADMODULE); + return MODULE_ERR_BADMODULE; + } + LOG("Module->Name = %p \"%s\"", Module->Name, Module->Name); + + if(Module->Arch != MODULE_ARCH_ID) { + Log_Warning( + "Module", + "Module %p (%s) is for another architecture (%i)", + Module, Module->Name, Module->Arch + ); + } deps = Module->Dependencies; @@ -96,7 +116,7 @@ int Module_int_Initialise(tModule *Module, char *ArgString) // So, if it's not loaded, we better load it then for( i = 0; i < giNumBuiltinModules; i ++ ) { - if( strcmp(deps[j], gKernelModules[i].Name) == 0 ) + if( strcmp(deps[j], gapBuiltinModules[i]->Name) == 0 ) break; } if( i == giNumBuiltinModules ) { @@ -107,7 +127,7 @@ int Module_int_Initialise(tModule *Module, char *ArgString) // Dependency is not loaded, so load it ret = Module_int_Initialise( - &gKernelModules[i], + gapBuiltinModules[i], gasBuiltinModuleArgs ? gasBuiltinModuleArgs[i] : NULL ); if( ret ) @@ -167,6 +187,48 @@ int Module_int_Initialise(tModule *Module, char *ArgString) LEAVE_RET('i', 0); } +/** + * \brief Scans the builtin modules and creates an array of them + */ +void Modules_int_GetBuiltinArray(void) +{ + int i; + tModule *module; + + // Count + module = &gKernelModules; + i = 0; + while( (tVAddr)module < (tVAddr)&gKernelModulesEnd ) + { + if(module->Magic == MODULE_MAGIC) { + i ++; + module ++; + } + else + module = (void*)( (tVAddr)module + 4 ); + } + + // Create + giNumBuiltinModules = i; + gasBuiltinModuleArgs = calloc( giNumBuiltinModules, sizeof(char*) ); + gapBuiltinModules = malloc( giNumBuiltinModules * sizeof(tModule*) ); + + + // Fill + module = &gKernelModules; + i = 0; + while( (tVAddr)module < (tVAddr)&gKernelModulesEnd ) + { + if(module->Magic == MODULE_MAGIC) { + gapBuiltinModules[i] = module; + i ++; + module ++; + } + else + module = (void*)( (tVAddr)module + 4 ); + } +} + /** * \brief Initialises builtin modules */ @@ -174,14 +236,13 @@ void Modules_LoadBuiltins() { int i; - // Count modules - giNumBuiltinModules = (Uint)&gKernelModulesEnd - (Uint)&gKernelModules; - giNumBuiltinModules /= sizeof(tModule); + if( !gapBuiltinModules ) + Modules_int_GetBuiltinArray(); for( i = 0; i < giNumBuiltinModules; i++ ) { Module_int_Initialise( - &gKernelModules[i], + gapBuiltinModules[i], (gasBuiltinModuleArgs ? gasBuiltinModuleArgs[i] : NULL) ); } @@ -196,15 +257,16 @@ void Modules_LoadBuiltins() void Modules_SetBuiltinParams(char *Name, char *ArgString) { int i; - if( gasBuiltinModuleArgs == NULL ) { - giNumBuiltinModules = (Uint)&gKernelModulesEnd - (Uint)&gKernelModules; - giNumBuiltinModules /= sizeof(tModule); - gasBuiltinModuleArgs = calloc( giNumBuiltinModules, sizeof(char*) ); + + if( gasBuiltinModuleArgs == NULL ) + { + Modules_int_GetBuiltinArray(); } - for( i = 0; i < giNumBuiltinModules; i ++ ) + // I hate expensive scans + for( i = 0; i < giNumBuiltinModules; i++ ) { - if(strcmp( gKernelModules[i].Name, Name ) == 0) { + if(strcmp( gapBuiltinModules[i]->Name, Name ) == 0) { gasBuiltinModuleArgs[i] = ArgString; return ; } diff --git a/Modules/IPStack/ipv4.h b/Modules/IPStack/ipv4.h index e8c2bc38..b40caa70 100644 --- a/Modules/IPStack/ipv4.h +++ b/Modules/IPStack/ipv4.h @@ -28,7 +28,7 @@ struct sIPv4Header } __attribute__((packed)); Uint8 FragOffHi; // Number of 8-byte blocks from the original start - Uint8 TTL; // Max number of hops effectively + Uint8 TTL; // Max number of hops, effectively Uint8 Protocol; Uint16 HeaderChecksum; // One's Complement Sum of the entire header must equal zero diff --git a/Modules/IPStack/ipv6.h b/Modules/IPStack/ipv6.h index c2810a38..f2f14f44 100644 --- a/Modules/IPStack/ipv6.h +++ b/Modules/IPStack/ipv6.h @@ -21,7 +21,7 @@ struct sIPv6Header unsigned Version: 4; unsigned TrafficClass: 8; unsigned FlowLabel: 20; - }; + } __attribute__((packed)); #endif Uint16 PayloadLength; Uint8 NextHeader; // Type of payload data diff --git a/Modules/IPStack/link.c b/Modules/IPStack/link.c index 6cdb2bc4..d9145704 100644 --- a/Modules/IPStack/link.c +++ b/Modules/IPStack/link.c @@ -52,7 +52,10 @@ void Link_RegisterType(Uint16 Type, tPacketCallback Callback) { tmp = realloc(gaRegisteredTypes, (giRegisteredTypes+1)*sizeof(*gaRegisteredTypes)); if(!tmp) { - Log_Warning("NET", "Out of heap space!"); + Log_Warning("NET", + "Out of heap space! (Attempted to allocate %i)", + (giRegisteredTypes+1)*sizeof(*gaRegisteredTypes) + ); return ; } i = giRegisteredTypes; diff --git a/Modules/USB/Core/main.c b/Modules/USB/Core/main.c index 5744c29d..51cd38ea 100644 --- a/Modules/USB/Core/main.c +++ b/Modules/USB/Core/main.c @@ -11,11 +11,11 @@ #include "usb.h" // === IMPORTS === - int UHCI_Initialise(); +extern int UHCI_Initialise(void); // === PROTOTYPES === int USB_Install(char **Arguments); -void USB_Cleanup(); +void USB_Cleanup(void); char *USB_ReadDir(tVFS_Node *Node, int Pos); tVFS_Node *USB_FindDir(tVFS_Node *Node, char *Name); int USB_IOCtl(tVFS_Node *Node, int Id, void *Data); @@ -43,7 +43,7 @@ tUSBHost *gUSB_Hosts = NULL; int USB_Install(char **Arguments) { UHCI_Initialise(); - Warning("[USB ] Not Complete - Devel Only"); + Log_Warning("USB", "Not Complete - Devel Only"); return MODULE_ERR_OK; } diff --git a/Modules/USB/Core/usb.h b/Modules/USB/Core/usb.h index 397e4d70..207c1561 100644 --- a/Modules/USB/Core/usb.h +++ b/Modules/USB/Core/usb.h @@ -65,11 +65,11 @@ enum eUSB_PIDs /** * \note 00101 - X^5+X^2+1 */ -Uint8 USB_TokenCRC(void *Data, int len); +extern Uint8 USB_TokenCRC(void *Data, int len); /** * \note X^16 + X15 + X^2 + 1 */ -Uint16 USB_DataCRC(void *Data, int len); +extern Uint16 USB_DataCRC(void *Data, int len); // === STRUCTURES === /** -- 2.20.1