diff --git a/reactos/ChangeLog b/reactos/ChangeLog index 6223e030a8d..998263c7aab 100644 --- a/reactos/ChangeLog +++ b/reactos/ChangeLog @@ -1,3 +1,61 @@ +2002-07-13 Casper S. Hornstrup + + * rules.mak (RSYM): Define. + * include/ddk/zwtypes.h (DebugDbgLoadSymbols): Add to enum + _DEBUG_CONTROL_CODE. + * include/ntdll/ldr.h (LDR_SYMBOL_INFO, LdrpLoadUserModuleSymbols): Add. + (LdrLoadModuleSymbols): Remove. + * include/ntos/kdbgsyms.h (ST_FILENAME, ST_FUNCTION, + ST_LINENUMBER): Add. + (SYMBOL). Make Name an ANSI_STRING. + (IMAGE_SYMBOL_INFO, AreSymbolsParsed): Add. + * lib/ntdll/ldr/startup.c (LdrInitializeThunk): Call + LdrpLoadUserModuleSymbols() not LdrLoadModuleSymbols(). + * lib/ntdll/ldr/utils.c (LdrLoadModuleSymbols): Rename to + LdrpLoadUserModuleSymbols. + (LdrpLoadUserModuleSymbols): Use DebugDbgLoadSymbols debug control code. + (LdrLoadDll): assert if out of memory. + (LdrLoadDll): Call + LdrpLoadUserModuleSymbols(), not LdrLoadModuleSymbols(). + * lib/ntdll/string/ctype.c (_pctype): #undef. + * ntoskrnl/dbg/dbgctrl.c (NtSystemDebugControl): Call + LdrLoadUserModuleSymbols on DebugDbgLoadSymbols. + * ntoskrnl/include/internal/ldr.h (LdrGetAddressInformation): Add. + * ntoskrnl/include/internal/module.h (MODULE_TEXT_SECTION): Make SymbolInfo + an IMAGE_SYMBOL_INFO. + * ntoskrnl/ke/i386/exp.c (LdrGetAddressInformation): Add prototype. + (print_address): Change #ifdef KDBG to #ifdef DBG. + (KiDoubleFaultHandler, KiDumpTrapFrame, KeDumpStackFrames): Dump + one stack frame per line. + * ntoskrnl/ke/i386/multiboot.S: Create pagetables for more kernel + address space so larger modules can be passed from the boot loader. + * ntoskrnl/ke/i386/usertrap.c (LdrGetAddressInformation): Add prototype. + (print_user_address): Print symbols using LdrGetAddressInformation(). + * ntoskrnl/ldr/loader.c (SYMBOLFILE_HEADER, IMAGE_SYMBOL_INFO_CACHE, + STAB_ENTRY, N_FUN, N_SLINE, N_SO, SymbolListHead): Add. + (TAG_SYM_BUF): Remove. + (LdrInitDebug): Remove unneeded code. + (LdrInit1): Prepare for loading symbols. + (LdrpReadLine, HexL, LdrpParseLine, LdrpLoadModuleSymbolsFromBuffer, + LdrpLoadUserModuleSymbolsFromBuffer): Remove. + (LdrpParseImageSymbols, LdrpGetFileName, LdrpGetFunctionName, + LdrpGetLineNumber, LdrGetAddressInformation, LdrpLookupUserSymbolInfo): Add. + (LdrpLoadModuleSymbols, LdrInitializeBootStartDriver): Change to use new + symbol structures. + (LdrLoadUserModuleSymbols): Cache symbol buffers. + (LdrUnloadModuleSymbols): Implement. + (LdrLoadModule, LdrUnloadModule): Change #ifdef KDBG to #ifdef DBG. + (LdrPEProcessModule): Split a line into two lines. + (LdrPEProcessModule): Setup for loading symbols. + * ntoskrnl/ldr/sysdll.c (LdrpMapSystemDll): Open with FILE_SHARE_READ. + * ntoskrnl/ps/process.c (PiFreeSymbols): Call LdrUnloadModuleSymbols() to + free symbols. + (PiDeleteProcess): Change #ifdef KDBG to #ifdef DBG. + * ntoskrnl/rtl/ctype.c (_pctype): #undef. + * ntoskrnl/rtl/string.c (strncpy): Terminate destination string. + * tools/Makefile (rsym): Add target. + * tools/helper.mk: Include config and use -g if DBG = 1. + 2002-07-13 Casper S. Hornstrup * Makefile (install_before): Install system.hiv to correct location. diff --git a/reactos/include/ddk/zwtypes.h b/reactos/include/ddk/zwtypes.h index 23eac0e36e5..d2d3ca6d3a5 100644 --- a/reactos/include/ddk/zwtypes.h +++ b/reactos/include/ddk/zwtypes.h @@ -8,7 +8,8 @@ typedef enum _DEBUG_CONTROL_CODE DebugSetSpecialCalls, DebugClearSpecialCalls, DebugQuerySpecialCalls, - DebugDbgBreakPoint + DebugDbgBreakPoint, + DebugDbgLoadSymbols } DEBUG_CONTROL_CODE; typedef enum _KPROFILE_SOURCE diff --git a/reactos/include/ntdll/ldr.h b/reactos/include/ntdll/ldr.h index 2e84869ba96..d8f735023a6 100644 --- a/reactos/include/ntdll/ldr.h +++ b/reactos/include/ntdll/ldr.h @@ -19,11 +19,20 @@ typedef struct _LDR_MODULE HANDLE SectionHandle; ULONG CheckSum; ULONG TimeDateStamp; -#ifdef KDBG - SYMBOL_TABLE Symbols; -#endif /* KDBG */ +#ifdef DBG + IMAGE_SYMBOL_INFO SymbolInfo; +#endif /* DBG */ } LDR_MODULE, *PLDR_MODULE; +typedef struct _LDR_SYMBOL_INFO { + PLDR_MODULE ModuleObject; + ULONG_PTR ImageBase; + PVOID SymbolsBuffer; + ULONG SymbolsBufferLength; + PVOID SymbolStringsBuffer; + ULONG SymbolStringsBufferLength; +} LDR_SYMBOL_INFO, *PLDR_SYMBOL_INFO; + #define RVA(m, b) ((ULONG)b + m) @@ -48,7 +57,12 @@ typedef struct _MODULE_INFORMATION MODULE_ENTRY ModuleEntry[1]; } MODULE_INFORMATION, *PMODULE_INFORMATION; +#ifdef DBG +VOID +LdrpLoadUserModuleSymbols(PLDR_MODULE LdrModule); + +#endif PEPFUNC LdrPEStartup(PVOID ImageBase, HANDLE SectionHandle); NTSTATUS LdrMapSections(HANDLE ProcessHandle, @@ -58,9 +72,6 @@ NTSTATUS LdrMapSections(HANDLE ProcessHandle, NTSTATUS LdrMapNTDllForProcess(HANDLE ProcessHandle, PHANDLE NTDllSectionHandle); -VOID LdrLoadModuleSymbols(PLDR_MODULE ModuleObject); - - NTSTATUS STDCALL LdrDisableThreadCalloutsForDll(IN PVOID BaseAddress); diff --git a/reactos/include/ntos/kdbgsyms.h b/reactos/include/ntos/kdbgsyms.h index f5f6847d6c4..79c19ec4f90 100644 --- a/reactos/include/ntos/kdbgsyms.h +++ b/reactos/include/ntos/kdbgsyms.h @@ -4,12 +4,18 @@ #include +#define ST_FILENAME 0x00 +#define ST_FUNCTION 0x01 +#define ST_LINENUMBER 0x02 + typedef struct _SYMBOL { struct _SYMBOL *Next; /* Address relative to module base address */ ULONG RelativeAddress; - UNICODE_STRING Name; + ULONG SymbolType; + ANSI_STRING Name; + ULONG LineNumber; } SYMBOL, *PSYMBOL; typedef struct _SYMBOL_TABLE @@ -18,5 +24,23 @@ typedef struct _SYMBOL_TABLE PSYMBOL Symbols; } SYMBOL_TABLE, *PSYMBOL_TABLE; +typedef struct _IMAGE_SYMBOL_INFO +{ + SYMBOL_TABLE FileNameSymbols; + SYMBOL_TABLE FunctionSymbols; + SYMBOL_TABLE LineNumberSymbols; + ULONG_PTR ImageBase; + ULONG_PTR ImageSize; + PVOID FileBuffer; + PVOID SymbolsBase; + ULONG SymbolsLength; + PVOID SymbolStringsBase; + ULONG SymbolStringsLength; +} IMAGE_SYMBOL_INFO, *PIMAGE_SYMBOL_INFO; + +#define AreSymbolsParsed(si)((si)->FileNameSymbols.Symbols \ + || (si)->FunctionSymbols.Symbols \ + || (si)->LineNumberSymbols.Symbols) + #endif diff --git a/reactos/lib/ntdll/ldr/startup.c b/reactos/lib/ntdll/ldr/startup.c index db4f77580f9..615f1979563 100644 --- a/reactos/lib/ntdll/ldr/startup.c +++ b/reactos/lib/ntdll/ldr/startup.c @@ -1,4 +1,4 @@ -/* $Id: startup.c,v 1.37 2002/04/26 13:08:18 ekohl Exp $ +/* $Id: startup.c,v 1.38 2002/07/13 12:44:06 chorns Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -183,10 +183,11 @@ LdrInitializeThunk (ULONG Unknown1, InsertTailList(&Peb->Ldr->InInitializationOrderModuleList, &NtModule->InInitializationOrderModuleList); -#ifdef KDBG - LdrLoadModuleSymbols(NtModule); -#endif /* KDBG */ +#ifdef DBG + LdrpLoadUserModuleSymbols(NtModule); + +#endif /* DBG */ /* add entry for executable (becomes first list entry) */ ExeModule = (PLDR_MODULE)RtlAllocateHeap (Peb->ProcessHeap, @@ -229,9 +230,11 @@ LdrInitializeThunk (ULONG Unknown1, InsertHeadList(&Peb->Ldr->InLoadOrderModuleList, &ExeModule->InLoadOrderModuleList); -#ifdef KDBG - LdrLoadModuleSymbols(ExeModule); -#endif /* KDBG */ +#ifdef DBG + + LdrpLoadUserModuleSymbols(ExeModule); + +#endif /* DBG */ EntryPoint = LdrPEStartup((PVOID)ImageBase, NULL); ExeModule->EntryPoint = (ULONG)EntryPoint; diff --git a/reactos/lib/ntdll/ldr/utils.c b/reactos/lib/ntdll/ldr/utils.c index 969794d026e..4c06bfe69b6 100644 --- a/reactos/lib/ntdll/ldr/utils.c +++ b/reactos/lib/ntdll/ldr/utils.c @@ -1,4 +1,4 @@ -/* $Id: utils.c,v 1.50 2002/04/26 13:08:18 ekohl Exp $ +/* $Id: utils.c,v 1.51 2002/07/13 12:44:06 chorns Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -48,20 +48,21 @@ static PVOID LdrGetExportByName(PVOID BaseAddress, PUCHAR SymbolName, USHORT Hin /* FUNCTIONS *****************************************************************/ -#ifdef KDBG +#ifdef DBG -VOID LdrLoadModuleSymbols(PLDR_MODULE ModuleObject) +VOID +LdrpLoadUserModuleSymbols(PLDR_MODULE LdrModule) { NtSystemDebugControl( - 0xffffffff, - (PVOID)ModuleObject, + DebugDbgLoadSymbols, + (PVOID)LdrModule, 0, NULL, 0, NULL); } -#endif /* KDBG */ +#endif /* DBG */ /*************************************************************************** @@ -364,6 +365,7 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL, Module = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof (LDR_MODULE)); + assert(Module); Module->BaseAddress = (PVOID)ImageBase; Module->EntryPoint = NTHeaders->OptionalHeader.AddressOfEntryPoint; if (Module->EntryPoint != 0) @@ -400,9 +402,11 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL, &Module->InInitializationOrderModuleList); /* FIXME: release loader lock */ -#ifdef KDBG - LdrLoadModuleSymbols(Module); -#endif /* KDBG */ +#ifdef DBG + + LdrpLoadUserModuleSymbols(Module); + +#endif /* DBG */ /* initialize dll */ if ((NTHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL) == diff --git a/reactos/lib/ntdll/string/ctype.c b/reactos/lib/ntdll/string/ctype.c index abdbce34efd..88f521a137c 100644 --- a/reactos/lib/ntdll/string/ctype.c +++ b/reactos/lib/ntdll/string/ctype.c @@ -1,4 +1,4 @@ -/* $Id: ctype.c,v 1.7 2000/01/10 20:30:15 ekohl Exp $ +/* $Id: ctype.c,v 1.8 2002/07/13 12:44:06 chorns Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -13,6 +13,7 @@ #include +#undef _pctype #define upalpha ('A' - 'a') diff --git a/reactos/ntoskrnl/Makefile b/reactos/ntoskrnl/Makefile index f3686d090e0..9167dd23643 100644 --- a/reactos/ntoskrnl/Makefile +++ b/reactos/ntoskrnl/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.72 2002/07/04 19:56:35 dwelch Exp $ +# $Id: Makefile,v 1.73 2002/07/13 12:44:07 chorns Exp $ # # ReactOS Operating System # @@ -617,7 +617,7 @@ $(TARGETNAME).dbg: $(TARGETNAME).dbg.o $(TARGETNAME).a $(TARGETNAME).dbg.lnk - $(RM) temp.exp $(TARGETNAME).sym: $(TARGETNAME).nostrip.exe - $(NM) --numeric-sort $(TARGETNAME).nostrip.exe > $(TARGETNAME).sym + $(RSYM) $(TARGETNAME).nostrip.exe $(TARGETNAME).sym $(TARGETNAME).o: $(OBJECTS) $(LD) \ diff --git a/reactos/ntoskrnl/dbg/dbgctrl.c b/reactos/ntoskrnl/dbg/dbgctrl.c index e2adfc7f1cc..33e25f308cc 100644 --- a/reactos/ntoskrnl/dbg/dbgctrl.c +++ b/reactos/ntoskrnl/dbg/dbgctrl.c @@ -50,10 +50,12 @@ NtSystemDebugControl(DEBUG_CONTROL_CODE ControlCode, case DebugQuerySpecialCalls: case DebugDbgBreakPoint: break; +#ifdef DBG + case DebugDbgLoadSymbols: + LdrLoadUserModuleSymbols((PLDR_MODULE) InputBuffer); +#endif /* DBG */ + break; default: -#ifdef KDBG - LdrLoadUserModuleSymbols((PLDR_MODULE)InputBuffer); -#endif /* KDBG */ break; } return STATUS_SUCCESS; diff --git a/reactos/ntoskrnl/include/internal/ldr.h b/reactos/ntoskrnl/include/internal/ldr.h index cc3e6c522d0..207e6358023 100644 --- a/reactos/ntoskrnl/include/internal/ldr.h +++ b/reactos/ntoskrnl/include/internal/ldr.h @@ -112,13 +112,22 @@ LdrUnloadModule(PMODULE_OBJECT ModuleObject); PMODULE_OBJECT LdrGetModuleObject(PUNICODE_STRING ModuleName); +NTSTATUS +LdrGetAddressInformation(IN PIMAGE_SYMBOL_INFO SymbolInfo, + IN ULONG_PTR RelativeAddress, + OUT PULONG LineNumber, + OUT PCH FileName OPTIONAL, + OUT PCH FunctionName OPTIONAL); -#ifdef KDBG -VOID -LdrpLoadModuleSymbols(PMODULE_OBJECT ModuleObject); + +#ifdef DBG VOID -LdrLoadUserModuleSymbols(PLDR_MODULE ModuleObject); -#endif /* KDBG */ +LdrLoadUserModuleSymbols(PLDR_MODULE LdrModule); + +VOID +LdrUnloadModuleSymbols(PIMAGE_SYMBOL_INFO SymbolInfo); + +#endif /* DBG */ #endif /* __INCLUDE_INTERNAL_LDR_H */ diff --git a/reactos/ntoskrnl/include/internal/module.h b/reactos/ntoskrnl/include/internal/module.h index 1ef3ba3a25f..31808f956ae 100644 --- a/reactos/ntoskrnl/include/internal/module.h +++ b/reactos/ntoskrnl/include/internal/module.h @@ -13,11 +13,9 @@ typedef struct _MODULE_TEXT_SECTION ULONG Length; LIST_ENTRY ListEntry; PWCH Name; -#ifdef KDBG - SYMBOL_TABLE Symbols; -#endif /* KDBG */ - PVOID SymbolsBase; - ULONG SymbolsLength; +#ifdef DBG + IMAGE_SYMBOL_INFO SymbolInfo; +#endif /* DBG */ } MODULE_TEXT_SECTION, *PMODULE_TEXT_SECTION; typedef struct _MODULE_OBJECT diff --git a/reactos/ntoskrnl/ke/i386/exp.c b/reactos/ntoskrnl/ke/i386/exp.c index e802ce69088..038003b60a4 100644 --- a/reactos/ntoskrnl/ke/i386/exp.c +++ b/reactos/ntoskrnl/ke/i386/exp.c @@ -45,6 +45,17 @@ /* GLOBALS *****************************************************************/ +#ifdef DBG + +NTSTATUS +LdrGetAddressInformation(IN PIMAGE_SYMBOL_INFO SymbolInfo, + IN ULONG_PTR RelativeAddress, + OUT PULONG LineNumber, + OUT PCH FileName OPTIONAL, + OUT PCH FunctionName OPTIONAL); + +#endif /* DBG */ + #define _STR(x) #x #define STR(x) _STR(x) @@ -124,16 +135,17 @@ extern unsigned int _text_start__, _text_end__; STATIC BOOLEAN print_address(PVOID address) { -#ifdef KDBG - ULONG Offset; - PSYMBOL Symbol, NextSymbol; - BOOLEAN Printed = FALSE; - ULONG NextAddress; -#endif /* KDBG */ PLIST_ENTRY current_entry; MODULE_TEXT_SECTION* current; extern LIST_ENTRY ModuleTextListHead; - + ULONG_PTR RelativeAddress; +#ifdef DBG + NTSTATUS Status; + ULONG LineNumber; + CHAR FileName[256]; + CHAR FunctionName[256]; +#endif + current_entry = ModuleTextListHead.Flink; while (current_entry != &ModuleTextListHead && @@ -141,46 +153,31 @@ print_address(PVOID address) { current = CONTAINING_RECORD(current_entry, MODULE_TEXT_SECTION, ListEntry); - + if (address >= (PVOID)current->Base && address < (PVOID)(current->Base + current->Length)) { - -#ifdef KDBG - - Offset = (ULONG)((ULONG)address - current->Base); - Symbol = current->Symbols.Symbols; - while (Symbol != NULL) - { - NextSymbol = Symbol->Next; - if (NextSymbol != NULL) - NextAddress = NextSymbol->RelativeAddress; - else - NextAddress = current->Length; - - if ((Offset >= Symbol->RelativeAddress) && - (Offset < NextAddress)) - { - DbgPrint("<%ws: %x (%wZ)>", current->Name, Offset, - &Symbol->Name); - Printed = TRUE; - break; - } - Symbol = NextSymbol; - } - if (!Printed) - DbgPrint("<%ws: %x>", current->Name, Offset); - -#else /* KDBG */ - - DbgPrint("<%ws: %x>", current->Name, - address - current->Base); - -#endif /* KDBG */ - + RelativeAddress = (ULONG_PTR) address - current->Base; +#ifdef DBG + Status = LdrGetAddressInformation(¤t->SymbolInfo, + RelativeAddress, + &LineNumber, + FileName, + FunctionName); + if (NT_SUCCESS(Status)) + { + DbgPrint("<%ws: %x (%s:%d (%s))>", + current->Name, RelativeAddress, FileName, LineNumber, FunctionName); + } + else + { + DbgPrint("<%ws: %x>", current->Name, RelativeAddress); + } +#else /* !DBG */ + DbgPrint("<%ws: %x>", current->Name, RelativeAddress); +#endif /* !DBG */ return(TRUE); } - current_entry = current_entry->Flink; } return(FALSE); @@ -338,6 +335,7 @@ KiDoubleFaultHandler(VOID) { print_address((PVOID)Frame[1]); Frame = (PULONG)Frame[0]; + DbgPrint("\n"); } #else DbgPrint("Frames: "); @@ -504,9 +502,6 @@ KiDumpTrapFrame(PKTRAP_FRAME Tf, ULONG ExceptionNr, ULONG cr2) print_address((PVOID)Frame[1]); Frame = (PULONG)Frame[0]; i++; - } - if ((i % 8) != 0) - { DbgPrint("\n"); } } @@ -592,9 +587,6 @@ KeDumpStackFrames(PULONG Frame) print_address((PVOID)Frame[1]); Frame = (PULONG)Frame[0]; i++; - } - if ((i % 8) != 0) - { DbgPrint("\n"); } } diff --git a/reactos/ntoskrnl/ke/i386/multiboot.S b/reactos/ntoskrnl/ke/i386/multiboot.S index d350be4f404..c6123945658 100644 --- a/reactos/ntoskrnl/ke/i386/multiboot.S +++ b/reactos/ntoskrnl/ke/i386/multiboot.S @@ -114,6 +114,31 @@ _multiboot_entry: movl $(V2P(kernel_pagetable+5*4096) + 0x7), 0xC14(%esi) movl $(V2P(kernel_pagetable+6*4096) + 0x7), 0xC18(%esi) movl $(V2P(kernel_pagetable+7*4096) + 0x7), 0xC1c(%esi) + movl $(V2P(kernel_pagetable+8*4096) + 0x7), 0xC20(%esi) + movl $(V2P(kernel_pagetable+9*4096) + 0x7), 0xC24(%esi) + movl $(V2P(kernel_pagetable+10*4096) + 0x7), 0xC28(%esi) + movl $(V2P(kernel_pagetable+11*4096) + 0x7), 0xC2c(%esi) + movl $(V2P(kernel_pagetable+12*4096) + 0x7), 0xC30(%esi) + movl $(V2P(kernel_pagetable+13*4096) + 0x7), 0xC34(%esi) + movl $(V2P(kernel_pagetable+14*4096) + 0x7), 0xC38(%esi) + movl $(V2P(kernel_pagetable+15*4096) + 0x7), 0xC3c(%esi) + movl $(V2P(kernel_pagetable+16*4096) + 0x7), 0xC40(%esi) + movl $(V2P(kernel_pagetable+17*4096) + 0x7), 0xC44(%esi) + movl $(V2P(kernel_pagetable+18*4096) + 0x7), 0xC48(%esi) + movl $(V2P(kernel_pagetable+19*4096) + 0x7), 0xC4c(%esi) + movl $(V2P(kernel_pagetable+20*4096) + 0x7), 0xC50(%esi) + movl $(V2P(kernel_pagetable+21*4096) + 0x7), 0xC54(%esi) + movl $(V2P(kernel_pagetable+22*4096) + 0x7), 0xC58(%esi) + movl $(V2P(kernel_pagetable+23*4096) + 0x7), 0xC5c(%esi) + movl $(V2P(kernel_pagetable+24*4096) + 0x7), 0xC60(%esi) + movl $(V2P(kernel_pagetable+25*4096) + 0x7), 0xC64(%esi) + movl $(V2P(kernel_pagetable+26*4096) + 0x7), 0xC68(%esi) + movl $(V2P(kernel_pagetable+27*4096) + 0x7), 0xC6c(%esi) + movl $(V2P(kernel_pagetable+28*4096) + 0x7), 0xC70(%esi) + movl $(V2P(kernel_pagetable+29*4096) + 0x7), 0xC74(%esi) + movl $(V2P(kernel_pagetable+30*4096) + 0x7), 0xC78(%esi) + movl $(V2P(kernel_pagetable+31*4096) + 0x7), 0xC7c(%esi) + movl $(V2P(lowmem_pagetable) + 0x7), 0xD00(%esi) movl $(V2P(startup_pagedirectory) + 0x7), 0xF00(%esi) #ifdef MP @@ -144,7 +169,7 @@ _multiboot_entry: movl %eax, (%esi, %edi) addl $0x1000, %eax addl $4, %edi - cmpl $2048, %edi + cmpl $8192, %edi jl .l4 #ifdef MP @@ -315,7 +340,7 @@ lowmem_pagetable: .fill 4096, 1, 0 kernel_pagetable: - .fill 8*4096, 1, 0 + .fill 32*4096, 1, 0 #ifdef MP apic_pagetable: diff --git a/reactos/ntoskrnl/ke/i386/usertrap.c b/reactos/ntoskrnl/ke/i386/usertrap.c index 4b2f46bb408..576f91d9a4a 100644 --- a/reactos/ntoskrnl/ke/i386/usertrap.c +++ b/reactos/ntoskrnl/ke/i386/usertrap.c @@ -45,6 +45,17 @@ /* GLOBALS *****************************************************************/ +#ifdef DBG + +NTSTATUS +LdrGetAddressInformation(IN PIMAGE_SYMBOL_INFO SymbolInfo, + IN ULONG_PTR RelativeAddress, + OUT PULONG LineNumber, + OUT PCH FileName OPTIONAL, + OUT PCH FunctionName OPTIONAL); + +#endif /* DBG */ + static char *ExceptionTypeStrings[] = { "Divide Error", @@ -72,16 +83,17 @@ static char *ExceptionTypeStrings[] = STATIC BOOLEAN print_user_address(PVOID address) { -#ifdef KDBG - ULONG Offset; - PSYMBOL Symbol, NextSymbol; - BOOLEAN Printed = FALSE; - ULONG NextAddress; -#endif /* KDBG */ PLIST_ENTRY current_entry; PLDR_MODULE current; PEPROCESS CurrentProcess; PPEB Peb = NULL; + ULONG_PTR RelativeAddress; +#ifdef DBG + NTSTATUS Status; + ULONG LineNumber; + CHAR FileName[256]; + CHAR FunctionName[256]; +#endif CurrentProcess = PsGetCurrentProcess(); if (NULL != CurrentProcess) @@ -106,37 +118,25 @@ print_user_address(PVOID address) if (address >= (PVOID)current->BaseAddress && address < (PVOID)(current->BaseAddress + current->SizeOfImage)) { -#ifdef KDBG - - Offset = (ULONG)(address - current->BaseAddress); - Symbol = current->Symbols.Symbols; - while (Symbol != NULL) - { - NextSymbol = Symbol->Next; - if (NextSymbol != NULL) - NextAddress = NextSymbol->RelativeAddress; - else - NextAddress = current->SizeOfImage; - - if ((Offset >= Symbol->RelativeAddress) && - (Offset < NextAddress)) - { - DbgPrint("<%wZ: %x (%wZ)>", - ¤t->BaseDllName, Offset, &Symbol->Name); - Printed = TRUE; - break; - } - Symbol = NextSymbol; - } - if (!Printed) - DbgPrint("<%wZ: %x>", ¤t->BaseDllName, Offset); - -#else /* KDBG */ - - DbgPrint("<%wZ: %x>", ¤t->BaseDllName, - address - current->BaseAddress); - -#endif /* KDBG */ + RelativeAddress = (ULONG_PTR) address - (ULONG_PTR)current->BaseAddress; +#ifdef DBG + Status = LdrGetAddressInformation(¤t->SymbolInfo, + RelativeAddress, + &LineNumber, + FileName, + FunctionName); + if (NT_SUCCESS(Status)) + { + DbgPrint("<%wZ: %x (%s:%d (%s))>", + ¤t->BaseDllName, RelativeAddress, FileName, LineNumber, FunctionName); + } + else + { + DbgPrint("<%wZ: %x>", ¤t->BaseDllName, RelativeAddress); + } +#else /* !DBG */ + DbgPrint("<%wZ: %x>", ¤t->BaseDllName, RelativeAddress); +#endif /* !DBG */ return(TRUE); } diff --git a/reactos/ntoskrnl/ldr/loader.c b/reactos/ntoskrnl/ldr/loader.c index 8bd85565119..969a8c5c65e 100644 --- a/reactos/ntoskrnl/ldr/loader.c +++ b/reactos/ntoskrnl/ldr/loader.c @@ -1,4 +1,4 @@ -/* $Id: loader.c,v 1.114 2002/06/27 17:52:32 ekohl Exp $ +/* $Id: loader.c,v 1.115 2002/07/13 12:44:08 chorns Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -46,6 +46,56 @@ /* GLOBALS *******************************************************************/ +#ifdef DBG + +typedef struct _SYMBOLFILE_HEADER { + unsigned long StabsOffset; + unsigned long StabsLength; + unsigned long StabstrOffset; + unsigned long StabstrLength; +} SYMBOLFILE_HEADER, *PSYMBOLFILE_HEADER; + +typedef struct _IMAGE_SYMBOL_INFO_CACHE { + LIST_ENTRY ListEntry; + UNICODE_STRING FullName; + PVOID FileBuffer; + PVOID SymbolsBase; + ULONG SymbolsLength; + PVOID SymbolStringsBase; + ULONG SymbolStringsLength; +} IMAGE_SYMBOL_INFO_CACHE, *PIMAGE_SYMBOL_INFO_CACHE; + + +typedef struct _STAB_ENTRY { + unsigned long n_strx; /* index into string table of name */ + unsigned char n_type; /* type of symbol */ + unsigned char n_other; /* misc info (usually empty) */ + unsigned short n_desc; /* description field */ + unsigned long n_value; /* value of symbol */ +} _STAB_ENTRY, *PSTAB_ENTRY; + +/* + * Desc - Line number + * Value - Relative virtual address + */ +#define N_FUN 0x24 + +/* + * Desc - Line number + * Value - Relative virtual address + */ +#define N_SLINE 0x44 + +/* + * String - First containing a '/' is the compillation directory (CD) + * Not containing a '/' is a source file relative to CD + */ +#define N_SO 0x64 + +LIST_ENTRY SymbolListHead; + +#endif /* DBG */ + LIST_ENTRY ModuleListHead; KSPIN_LOCK ModuleListLock; @@ -55,7 +105,6 @@ STATIC MODULE_TEXT_SECTION LdrHalTextSection; ULONG_PTR LdrHalBase; #define TAG_DRIVER_MEM TAG('D', 'R', 'V', 'M') -#define TAG_SYM_BUF TAG('S', 'Y', 'M', 'B') /* FORWARD DECLARATIONS ******************************************************/ @@ -120,9 +169,6 @@ LdrInitDebug(PLOADER_MODULE Module, PWCH Name) { return; } - - current->SymbolsBase = (PVOID)Module->ModStart; - current->SymbolsLength = Module->ModEnd - Module->ModStart; } VOID @@ -148,8 +194,11 @@ LdrInit1(VOID) NtoskrnlTextSection.Length = SectionList[0].Misc.VirtualSize + SectionList[0].VirtualAddress; NtoskrnlTextSection.Name = KERNEL_MODULE_NAME; - NtoskrnlTextSection.SymbolsBase = NULL; - NtoskrnlTextSection.SymbolsLength = 0; +#ifdef DBG + RtlZeroMemory(&NtoskrnlTextSection.SymbolInfo, sizeof(NtoskrnlTextSection.SymbolInfo)); + NtoskrnlTextSection.SymbolInfo.ImageBase = OptionalHeader->ImageBase; + NtoskrnlTextSection.SymbolInfo.ImageSize = NtoskrnlTextSection.Length; +#endif InsertTailList(&ModuleTextListHead, &NtoskrnlTextSection.ListEntry); /* Setup hal.dll text section */ @@ -165,9 +214,16 @@ LdrInit1(VOID) LdrHalTextSection.Length = SectionList[0].Misc.VirtualSize + SectionList[0].VirtualAddress; LdrHalTextSection.Name = HAL_MODULE_NAME; - LdrHalTextSection.SymbolsBase = NULL; - LdrHalTextSection.SymbolsLength = 0; +#ifdef DBG + RtlZeroMemory(&LdrHalTextSection.SymbolInfo, sizeof(LdrHalTextSection.SymbolInfo)); + LdrHalTextSection.SymbolInfo.ImageBase = OptionalHeader->ImageBase; + LdrHalTextSection.SymbolInfo.ImageSize = LdrHalTextSection.Length; +#endif InsertTailList(&ModuleTextListHead, &LdrHalTextSection.ListEntry); + +#ifdef DBG + InitializeListHead(&SymbolListHead); +#endif } @@ -243,300 +299,337 @@ LdrInitModuleManagement(VOID) &ModuleObject->ListEntry); } +#ifdef DBG -#ifdef KDBG - -BOOLEAN LdrpReadLine(PCHAR Line, - ULONG LineSize, - PVOID *Buffer, - PULONG Size) +VOID +LdrpParseImageSymbols(PIMAGE_SYMBOL_INFO SymbolInfo) +/* Note: It is important that the symbol strings buffer not be released after + this function is called because the strings are still referenced */ { - CHAR ch; - PCHAR Block; - ULONG Count; - - if (*Size == 0) - return FALSE; - - ch = ' '; - Count = 0; - Block = *Buffer; - while ((*Size > 0) && (Count < LineSize) && ((ch = *Block) != (CHAR)13)) - { - *Line = ch; - Line++; - Block++; - Count++; - *Size -= 1; - } - *Line = (CHAR)0; - - if (ch == (CHAR)13) - { - Block++; - *Size -= 1; - } - - if ((*Size > 0) && (*Block == (CHAR)10)) - { - Block++; - *Size -= 1; - } - - *Buffer = Block; - - return TRUE; -} - -ULONG HexL(PCHAR Buffer) -{ - CHAR ch; - UINT i, j; - ULONG Value; - - j = 32; - i = 0; - Value = 0; - while ((j > 0) && ((ch = Buffer[i]) != ' ')) - { - j -= 4; - if ((ch >= '0') && (ch <= '9')) - Value |= ((ch - '0') << j); - if ((ch >= 'A') && (ch <= 'F')) - Value |= ((10 + (ch - 'A')) << j); - else - if ((ch >= 'a') && (ch <= 'f')) - Value |= ((10 + (ch - 'a')) << j); - i++; - } - return Value; -} - -PSYMBOL LdrpParseLine(PCHAR Line, - PULONG TextBase, - PBOOLEAN TextBaseValid, - PULONG Alignment) -/* - Line format: [ADDRESS] - TYPE: - U = ? - A = Image information - t = Symbol in text segment - T = Symbol in text segment - d = Symbol in data segment - D = Symbol in data segment - b = Symbol in BSS segment - B = Symbol in BSS segment - ? = Unknown segment or symbol in unknown segment -*/ -{ - ANSI_STRING AnsiString; - CHAR Buffer[128]; + PSYMBOL CurrentFileNameSymbol; + PSYMBOL CurrentFunctionSymbol; + PSYMBOL CurrentLineNumberSymbol; PSYMBOL Symbol; - ULONG Address; - PCHAR Str; - CHAR Type; + PSTAB_ENTRY StabEntry; + PVOID StabsEnd; + PCHAR String; + ULONG_PTR FunRelativeAddress; + ULONG FunLineNumber; + ULONG_PTR ImageBase; - if ((Line[0] == (CHAR)0) || (Line[0] == ' ')) - return NULL; + assert(SymbolInfo); - Address = HexL(Line); + DPRINT("Parsing symbols.\n"); - Line = strchr(Line, ' '); - if (Line == NULL) - return NULL; - - Line++; - Type = *Line; - - Line = strchr(Line, ' '); - if (Line == NULL) - return NULL; - - Line++; - Str = strchr(Line, ' '); - if (Str == NULL) - strcpy((char*)&Buffer, Line); - else - strncpy((char*)&Buffer, Line, Str - Line); - - if ((Type == 'A') && (strcmp((char*)&Buffer, "__section_alignment__")) == 0) + SymbolInfo->FileNameSymbols.SymbolCount = 0; + SymbolInfo->FileNameSymbols.Symbols = NULL; + SymbolInfo->FunctionSymbols.SymbolCount = 0; + SymbolInfo->FunctionSymbols.Symbols = NULL; + SymbolInfo->LineNumberSymbols.SymbolCount = 0; + SymbolInfo->LineNumberSymbols.Symbols = NULL; + StabsEnd = SymbolInfo->SymbolsBase + SymbolInfo->SymbolsLength; + StabEntry = (PSTAB_ENTRY) SymbolInfo->SymbolsBase; + ImageBase = SymbolInfo->ImageBase; + FunRelativeAddress = 0; + FunLineNumber = 0; + CurrentFileNameSymbol = NULL; + CurrentFunctionSymbol = NULL; + CurrentLineNumberSymbol = NULL; + while ((ULONG_PTR) StabEntry < (ULONG_PTR) StabsEnd) { - *Alignment = Address; - return NULL; - } + Symbol = NULL; - /* We only want symbols in the .text segment */ - if ((Type != 't') && (Type != 'T')) - return NULL; - - /* Discard other symbols we can't use */ - if ((Buffer[0] != '_') || ((Buffer[0] == '_') && (Buffer[1] == '_'))) - return NULL; - - Symbol = ExAllocatePool(NonPagedPool, sizeof(SYMBOL)); - if (!Symbol) - return NULL; - - Symbol->Next = NULL; - - Symbol->RelativeAddress = Address; - - RtlInitAnsiString(&AnsiString, (PCSZ)&Buffer); - RtlAnsiStringToUnicodeString(&Symbol->Name, &AnsiString, TRUE); - - if (!(*TextBaseValid)) - { - *TextBase = Address - *Alignment; - *TextBaseValid = TRUE; - } - - return Symbol; -} - -VOID -LdrpLoadModuleSymbolsFromBuffer(PMODULE_OBJECT ModuleObject, - PVOID Buffer, - ULONG Length) -/* - Symbols must be sorted by address, e.g. - "nm --numeric-sort module.sys > module.sym" - */ -{ - PSYMBOL Symbol, CurrentSymbol = NULL; - BOOLEAN TextBaseValid; - BOOLEAN Valid; - ULONG TextBase = 0; - ULONG Alignment = 0; - CHAR Line[256]; - ULONG Tmp; - - assert(ModuleObject); - - if (ModuleObject->TextSection == NULL) - { - ModuleObject->TextSection = &NtoskrnlTextSection; - } - - if (ModuleObject->TextSection->Symbols.SymbolCount > 0) - { - CPRINT("Symbols are already loaded for %wZ\n", &ModuleObject->BaseName); - return; - } - - ModuleObject->TextSection->Symbols.SymbolCount = 0; - ModuleObject->TextSection->Symbols.Symbols = NULL; - TextBaseValid = FALSE; - Valid = FALSE; - while (LdrpReadLine((PCHAR)&Line, 256, &Buffer, &Length)) - { - Symbol = LdrpParseLine((PCHAR)&Line, &Tmp, &Valid, &Alignment); - - if ((Valid) && (!TextBaseValid)) + if (StabEntry->n_type == N_FUN) { - TextBase = Tmp; - TextBaseValid = TRUE; + if (StabEntry->n_desc > 0) + { + assert(StabEntry->n_value >= ImageBase); + + FunRelativeAddress = StabEntry->n_value - ImageBase; + FunLineNumber = StabEntry->n_desc; + + Symbol = ExAllocatePool(NonPagedPool, sizeof(SYMBOL)); + assert(Symbol); + Symbol->Next = NULL; + Symbol->SymbolType = ST_FUNCTION; + Symbol->RelativeAddress = FunRelativeAddress; + Symbol->LineNumber = FunLineNumber; + String = (PCHAR)SymbolInfo->SymbolStringsBase + StabEntry->n_strx; + RtlInitAnsiString(&Symbol->Name, String); + + DPRINT("FUN found. '%s' %d @ %x\n", + Symbol->Name.Buffer, FunLineNumber, FunRelativeAddress); + } + } + else if (StabEntry->n_type == N_SLINE) + { + Symbol = ExAllocatePool(NonPagedPool, sizeof(SYMBOL)); + assert(Symbol); + Symbol->Next = NULL; + Symbol->SymbolType = ST_LINENUMBER; + Symbol->RelativeAddress = FunRelativeAddress + StabEntry->n_value; + Symbol->LineNumber = StabEntry->n_desc; + + DPRINT("SLINE found. %d @ %x\n", + Symbol->LineNumber, Symbol->RelativeAddress); + } + else if (StabEntry->n_type == N_SO) + { + Symbol = ExAllocatePool(NonPagedPool, sizeof(SYMBOL)); + assert(Symbol); + Symbol->Next = NULL; + Symbol->SymbolType = ST_FILENAME; + Symbol->RelativeAddress = StabEntry->n_value - ImageBase; + Symbol->LineNumber = 0; + String = (PCHAR)SymbolInfo->SymbolStringsBase + StabEntry->n_strx; + RtlInitAnsiString(&Symbol->Name, String); + + DPRINT("SO found. '%s' @ %x\n", + Symbol->Name.Buffer, Symbol->RelativeAddress); } if (Symbol != NULL) { - Symbol->RelativeAddress -= TextBase; + switch (Symbol->SymbolType) + { + case ST_FILENAME: + if (SymbolInfo->FileNameSymbols.Symbols == NULL) + SymbolInfo->FileNameSymbols.Symbols = Symbol; + else + CurrentFileNameSymbol->Next = Symbol; - if (ModuleObject->TextSection->Symbols.Symbols == NULL) - ModuleObject->TextSection->Symbols.Symbols = Symbol; - else - CurrentSymbol->Next = Symbol; + CurrentFileNameSymbol = Symbol; - CurrentSymbol = Symbol; + SymbolInfo->FileNameSymbols.SymbolCount++; + break; + case ST_FUNCTION: + if (SymbolInfo->FunctionSymbols.Symbols == NULL) + SymbolInfo->FunctionSymbols.Symbols = Symbol; + else + CurrentFunctionSymbol->Next = Symbol; - ModuleObject->TextSection->Symbols.SymbolCount++; + CurrentFunctionSymbol = Symbol; + + SymbolInfo->FunctionSymbols.SymbolCount++; + break; + case ST_LINENUMBER: + if (SymbolInfo->LineNumberSymbols.Symbols == NULL) + SymbolInfo->LineNumberSymbols.Symbols = Symbol; + else + CurrentLineNumberSymbol->Next = Symbol; + + CurrentLineNumberSymbol = Symbol; + + SymbolInfo->LineNumberSymbols.SymbolCount++; + break; + } } + + StabEntry++; } } - -VOID -LdrpLoadUserModuleSymbolsFromBuffer(PLDR_MODULE ModuleObject, - PVOID Buffer, - ULONG Length) -/* - Symbols must be sorted by address, e.g. - "nm --numeric-sort module.dll > module.sym" - */ +static NTSTATUS +LdrpGetFileName(IN PIMAGE_SYMBOL_INFO SymbolInfo, + IN ULONG_PTR RelativeAddress, + OUT PCH FileName) { - PSYMBOL Symbol, CurrentSymbol = NULL; - BOOLEAN TextBaseValid; - BOOLEAN Valid; - ULONG TextBase = 0; - ULONG Alignment = 0; - CHAR Line[256]; - ULONG Tmp; + PSYMBOL NextSymbol; + ULONG_PTR NextAddress; + PSYMBOL Symbol; - if (ModuleObject->Symbols.SymbolCount > 0) + Symbol = SymbolInfo->FileNameSymbols.Symbols; + while (Symbol != NULL) { - DPRINT("Symbols are already loaded for %wZ\n", &ModuleObject->BaseDllName); - return; + NextSymbol = Symbol->Next; + if (NextSymbol != NULL) + NextAddress = NextSymbol->RelativeAddress; + else + NextAddress = SymbolInfo->ImageSize; + + DPRINT("FN SEARCH: Type %d RelativeAddress %x >= Symbol->RelativeAddress %x < NextAddress %x\n", + Symbol->SymbolType, RelativeAddress, Symbol->RelativeAddress, NextAddress); + + if ((Symbol->SymbolType == ST_FILENAME) && + (RelativeAddress >= Symbol->RelativeAddress) && + (RelativeAddress < NextAddress)) + { + DPRINT("FN found\n"); + strcpy(FileName, Symbol->Name.Buffer); + return STATUS_SUCCESS; + } + Symbol = NextSymbol; } - ModuleObject->Symbols.SymbolCount = 0; - ModuleObject->Symbols.Symbols = NULL; - TextBaseValid = FALSE; - Valid = FALSE; - while (LdrpReadLine((PCHAR)&Line, 256, &Buffer, &Length)) - { - Symbol = LdrpParseLine((PCHAR)&Line, &Tmp, &Valid, &Alignment); + DPRINT("FN not found\n"); - if ((Valid) && (!TextBaseValid)) - { - TextBase = Tmp; - TextBaseValid = TRUE; - } - - if (Symbol != NULL) - { - Symbol->RelativeAddress -= TextBase; - - if (ModuleObject->Symbols.Symbols == NULL) - ModuleObject->Symbols.Symbols = Symbol; - else - CurrentSymbol->Next = Symbol; - - CurrentSymbol = Symbol; - - ModuleObject->Symbols.SymbolCount++; - } - } + return STATUS_UNSUCCESSFUL; } +static NTSTATUS +LdrpGetFunctionName(IN PIMAGE_SYMBOL_INFO SymbolInfo, + IN ULONG_PTR RelativeAddress, + OUT PCH FunctionName) +{ + PSYMBOL NextSymbol; + ULONG_PTR NextAddress; + PSYMBOL Symbol; + + Symbol = SymbolInfo->FunctionSymbols.Symbols; + while (Symbol != NULL) + { + NextSymbol = Symbol->Next; + if (NextSymbol != NULL) + NextAddress = NextSymbol->RelativeAddress; + else + NextAddress = SymbolInfo->ImageSize; + + DPRINT("FUN SEARCH: Type %d RelativeAddress %x >= Symbol->RelativeAddress %x < NextAddress %x\n", + Symbol->SymbolType, RelativeAddress, Symbol->RelativeAddress, NextAddress); + + if ((Symbol->SymbolType == ST_FUNCTION) && + (RelativeAddress >= Symbol->RelativeAddress) && + (RelativeAddress < NextAddress)) + { + PCHAR ExtraInfo; + ULONG Length; + + DPRINT("FUN found\n"); + + /* Remove the extra information from the function name */ + ExtraInfo = strchr(Symbol->Name.Buffer, ':'); + if (ExtraInfo != NULL) + Length = ExtraInfo - Symbol->Name.Buffer; + else + Length = strlen(Symbol->Name.Buffer); + + strncpy(FunctionName, Symbol->Name.Buffer, Length); + return STATUS_SUCCESS; + } + Symbol = NextSymbol; + } + + DPRINT("FUN not found\n"); + + return STATUS_UNSUCCESSFUL; +} + +static NTSTATUS +LdrpGetLineNumber(IN PIMAGE_SYMBOL_INFO SymbolInfo, + IN ULONG_PTR RelativeAddress, + OUT PULONG LineNumber) +{ + PSYMBOL NextSymbol; + ULONG_PTR NextAddress; + PSYMBOL Symbol; + + Symbol = SymbolInfo->LineNumberSymbols.Symbols; + while (Symbol != NULL) + { + NextSymbol = Symbol->Next; + if (NextSymbol != NULL) + NextAddress = NextSymbol->RelativeAddress; + else + NextAddress = SymbolInfo->ImageSize; + + DPRINT("LN SEARCH: Type %d RelativeAddress %x >= Symbol->RelativeAddress %x < NextAddress %x\n", + Symbol->SymbolType, RelativeAddress, Symbol->RelativeAddress, NextAddress); + + if ((Symbol->SymbolType == ST_LINENUMBER) && + (RelativeAddress >= Symbol->RelativeAddress) && + (RelativeAddress < NextAddress)) + { + DPRINT("LN found\n"); + *LineNumber = Symbol->LineNumber; + return STATUS_SUCCESS; + } + Symbol = NextSymbol; + } + + DPRINT("LN not found\n"); + + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +LdrGetAddressInformation(IN PIMAGE_SYMBOL_INFO SymbolInfo, + IN ULONG_PTR RelativeAddress, + OUT PULONG LineNumber, + OUT PCH FileName OPTIONAL, + OUT PCH FunctionName OPTIONAL) +{ + NTSTATUS Status; + + *LineNumber = 0; + + DPRINT("RelativeAddress %p\n", RelativeAddress); + + if (RelativeAddress >= SymbolInfo->ImageSize) + { + DPRINT("Address is not within .text section. RelativeAddress %p Length 0x%x\n", + RelativeAddress, SymbolInfo->ImageSize); + return STATUS_UNSUCCESSFUL; + } + + if (!AreSymbolsParsed(SymbolInfo)) + { + LdrpParseImageSymbols(SymbolInfo); + } + + Status = LdrpGetLineNumber(SymbolInfo, RelativeAddress, LineNumber); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + if (FileName) + { + Status = LdrpGetFileName(SymbolInfo, RelativeAddress, FileName); + if (!NT_SUCCESS(Status)) + { + strcpy(FileName, ""); + } + } + + if (FunctionName) + { + Status = LdrpGetFunctionName(SymbolInfo, RelativeAddress, FunctionName); + if (!NT_SUCCESS(Status)) + { + strcpy(FunctionName, ""); + } + } + + return STATUS_SUCCESS; +} VOID -LdrpLoadModuleSymbols(PMODULE_OBJECT ModuleObject) +LdrpLoadModuleSymbols(PUNICODE_STRING FileName, + PIMAGE_SYMBOL_INFO SymbolInfo) { FILE_STANDARD_INFORMATION FileStdInfo; OBJECT_ATTRIBUTES ObjectAttributes; WCHAR TmpFileName[MAX_PATH]; - UNICODE_STRING Filename; + UNICODE_STRING SymFileName; LPWSTR Start, Ext; HANDLE FileHandle; PVOID FileBuffer; NTSTATUS Status; ULONG Length; IO_STATUS_BLOCK IoStatusBlock; - - ModuleObject->TextSection->Symbols.SymbolCount = 0; - ModuleObject->TextSection->Symbols.Symbols = NULL; + PSYMBOLFILE_HEADER SymbolFileHeader; /* Get the path to the symbol store */ wcscpy(TmpFileName, L"\\SystemRoot\\symbols\\"); /* Get the symbol filename from the module name */ - Start = wcsrchr(ModuleObject->BaseName.Buffer, L'\\'); + Start = wcsrchr(FileName->Buffer, L'\\'); if (Start == NULL) - Start = ModuleObject->BaseName.Buffer; + Start = FileName->Buffer; else Start++; - Ext = wcsrchr(ModuleObject->BaseName.Buffer, L'.'); + Ext = wcsrchr(FileName->Buffer, L'.'); if (Ext != NULL) Length = Ext - Start; else @@ -544,11 +637,11 @@ LdrpLoadModuleSymbols(PMODULE_OBJECT ModuleObject) wcsncat(TmpFileName, Start, Length); wcscat(TmpFileName, L".sym"); - RtlInitUnicodeString(&Filename, TmpFileName); + RtlInitUnicodeString(&SymFileName, TmpFileName); /* Open the file */ InitializeObjectAttributes(&ObjectAttributes, - &Filename, + &SymFileName, 0, NULL, NULL); @@ -561,11 +654,11 @@ LdrpLoadModuleSymbols(PMODULE_OBJECT ModuleObject) 0); if (!NT_SUCCESS(Status)) { - DPRINT("Could not open symbol file: %wZ\n", &Filename); + DPRINT("Could not open symbol file: %wZ\n", &SymFileName); return; } - CPRINT("Loading symbols from %wZ...\n", &Filename); + CPRINT("Loading symbols from %wZ...\n", &SymFileName); /* Get the size of the file */ Status = ZwQueryInformationFile(FileHandle, @@ -576,6 +669,7 @@ LdrpLoadModuleSymbols(PMODULE_OBJECT ModuleObject) if (!NT_SUCCESS(Status)) { DPRINT("Could not get file size\n"); + ZwClose(FileHandle); return; } @@ -586,6 +680,7 @@ LdrpLoadModuleSymbols(PMODULE_OBJECT ModuleObject) if (FileBuffer == NULL) { DPRINT("Could not allocate memory for symbol file\n"); + ZwClose(FileHandle); return; } @@ -598,132 +693,150 @@ LdrpLoadModuleSymbols(PMODULE_OBJECT ModuleObject) 0, 0); if (!NT_SUCCESS(Status)) { - DPRINT("Could not read symbol file into memory\n"); + DPRINT("Could not read symbol file into memory (Status 0x%x)\n", Status); ExFreePool(FileBuffer); + ZwClose(FileHandle); return; } ZwClose(FileHandle); - LdrpLoadModuleSymbolsFromBuffer(ModuleObject, - FileBuffer, - FileStdInfo.EndOfFile.u.LowPart); - - ExFreePool(FileBuffer); + SymbolFileHeader = (PSYMBOLFILE_HEADER) FileBuffer; + SymbolInfo->FileBuffer = FileBuffer; + SymbolInfo->SymbolsBase = FileBuffer + SymbolFileHeader->StabsOffset; + SymbolInfo->SymbolsLength = SymbolFileHeader->StabsLength; + SymbolInfo->SymbolStringsBase = FileBuffer + SymbolFileHeader->StabstrOffset; + SymbolInfo->SymbolStringsLength = SymbolFileHeader->StabstrLength; } VOID -LdrLoadUserModuleSymbols(PLDR_MODULE ModuleObject) +LdrUnloadModuleSymbols(PIMAGE_SYMBOL_INFO SymbolInfo) { - FILE_STANDARD_INFORMATION FileStdInfo; - OBJECT_ATTRIBUTES ObjectAttributes; - WCHAR TmpFileName[MAX_PATH]; - UNICODE_STRING Filename; - LPWSTR Start, Ext; - HANDLE FileHandle; - PVOID FileBuffer; - NTSTATUS Status; - ULONG Length; - IO_STATUS_BLOCK IoStatusBlock; + PSYMBOL NextSymbol; + PSYMBOL Symbol; - ModuleObject->Symbols.SymbolCount = 0; - ModuleObject->Symbols.Symbols = NULL; + DPRINT("Unloading symbols\n"); - /* Get the path to the symbol store */ - wcscpy(TmpFileName, L"\\SystemRoot\\symbols\\"); - - /* Get the symbol filename from the module name */ - Start = wcsrchr(ModuleObject->BaseDllName.Buffer, L'\\'); - if (Start == NULL) - Start = ModuleObject->BaseDllName.Buffer; - else - Start++; - - Ext = wcsrchr(ModuleObject->BaseDllName.Buffer, L'.'); - if (Ext != NULL) - Length = Ext - Start; - else - Length = wcslen(Start); - - wcsncat(TmpFileName, Start, Length); - wcscat(TmpFileName, L".sym"); - RtlInitUnicodeString(&Filename, TmpFileName); - - /* Open the file */ - InitializeObjectAttributes(&ObjectAttributes, - &Filename, - 0, - NULL, - NULL); - - Status = ZwOpenFile(&FileHandle, - FILE_ALL_ACCESS, - &ObjectAttributes, - &IoStatusBlock, - 0, - 0); - if (!NT_SUCCESS(Status)) + if (SymbolInfo != NULL) { - DPRINT("Could not open symbol file: %wZ\n", &Filename); - return; + Symbol = SymbolInfo->FileNameSymbols.Symbols; + while (Symbol != NULL) + { + NextSymbol = Symbol->Next; + RtlFreeAnsiString(&Symbol->Name); + ExFreePool(Symbol); + Symbol = NextSymbol; + } + + SymbolInfo->FileNameSymbols.SymbolCount = 0; + SymbolInfo->FileNameSymbols.Symbols = NULL; + + Symbol = SymbolInfo->FunctionSymbols.Symbols; + while (Symbol != NULL) + { + NextSymbol = Symbol->Next; + RtlFreeAnsiString(&Symbol->Name); + ExFreePool(Symbol); + Symbol = NextSymbol; + } + + SymbolInfo->FunctionSymbols.SymbolCount = 0; + SymbolInfo->FunctionSymbols.Symbols = NULL; + + Symbol = SymbolInfo->LineNumberSymbols.Symbols; + while (Symbol != NULL) + { + NextSymbol = Symbol->Next; + RtlFreeAnsiString(&Symbol->Name); + ExFreePool(Symbol); + Symbol = NextSymbol; + } + + SymbolInfo->LineNumberSymbols.SymbolCount = 0; + SymbolInfo->LineNumberSymbols.Symbols = NULL; +#if 0 + /* Don't free buffers because we cache symbol buffers + (eg. they are shared across processes) */ + /* FIXME: We can free them if we do reference counting */ + if (SymbolInfo->FileBuffer != NULL) + { + ExFreePool(SymbolInfo->FileBuffer); + SymbolInfo->FileBuffer = NULL; + SymbolInfo->SymbolsBase = NULL; + SymbolInfo->SymbolsLength = 0; + } +#endif + } +} + + +PIMAGE_SYMBOL_INFO_CACHE +LdrpLookupUserSymbolInfo(PLDR_MODULE LdrModule) +{ + PIMAGE_SYMBOL_INFO_CACHE Current; + PLIST_ENTRY CurrentEntry; + KIRQL Irql; + + DPRINT("Searching symbols for %S\n", LdrModule->FullDllName.Buffer); + + KeAcquireSpinLock(&ModuleListLock,&Irql); + + CurrentEntry = SymbolListHead.Flink; + while (CurrentEntry != (&SymbolListHead)) + { + Current = CONTAINING_RECORD(CurrentEntry, IMAGE_SYMBOL_INFO_CACHE, ListEntry); + + if (RtlEqualUnicodeString(&Current->FullName, &LdrModule->FullDllName, TRUE)) + { + KeReleaseSpinLock(&ModuleListLock, Irql); + return Current; + } + + CurrentEntry = CurrentEntry->Flink; } - CPRINT("Loading symbols from %wZ...\n", &Filename); + KeReleaseSpinLock(&ModuleListLock, Irql); - /* Get the size of the file */ - Status = ZwQueryInformationFile(FileHandle, - &IoStatusBlock, - &FileStdInfo, - sizeof(FileStdInfo), - FileStandardInformation); - if (!NT_SUCCESS(Status)) + return(NULL); +} + + +VOID +LdrLoadUserModuleSymbols(PLDR_MODULE LdrModule) +{ + PIMAGE_SYMBOL_INFO_CACHE CacheEntry; + + DPRINT("LdrModule %p\n", LdrModule); + + RtlZeroMemory(&LdrModule->SymbolInfo, sizeof(LdrModule->SymbolInfo)); + LdrModule->SymbolInfo.ImageBase = (ULONG_PTR) LdrModule->BaseAddress; + LdrModule->SymbolInfo.ImageSize = LdrModule->SizeOfImage; + + CacheEntry = LdrpLookupUserSymbolInfo(LdrModule); + if (CacheEntry != NULL) { - DPRINT("Could not get file size\n"); - return; - } - - /* Allocate nonpageable memory for symbol file */ - FileBuffer = ExAllocatePool(NonPagedPool, - FileStdInfo.EndOfFile.u.LowPart); - - if (FileBuffer == NULL) - { - DPRINT("Could not allocate memory for symbol file\n"); - return; - } + DPRINT("Symbol cache hit for %S\n", CacheEntry->FullName.Buffer); - /* Load file into memory chunk */ - Status = ZwReadFile(FileHandle, - 0, 0, 0, - &IoStatusBlock, - FileBuffer, - FileStdInfo.EndOfFile.u.LowPart, - 0, 0); - if (!NT_SUCCESS(Status)) - { - DPRINT("Could not read symbol file into memory\n"); - ExFreePool(FileBuffer); - return; + LdrModule->SymbolInfo.FileBuffer = CacheEntry->FileBuffer; + LdrModule->SymbolInfo.SymbolsBase = CacheEntry->SymbolsBase; + LdrModule->SymbolInfo.SymbolsLength = CacheEntry->SymbolsLength; + LdrModule->SymbolInfo.SymbolStringsBase = CacheEntry->SymbolStringsBase; + LdrModule->SymbolInfo.SymbolStringsLength = CacheEntry->SymbolStringsLength; + } + else + { + CacheEntry = ExAllocatePool(NonPagedPool, sizeof(IMAGE_SYMBOL_INFO_CACHE)); + assert(CacheEntry); + RtlZeroMemory(CacheEntry, sizeof(IMAGE_SYMBOL_INFO_CACHE)); + RtlCreateUnicodeString(&CacheEntry->FullName, LdrModule->FullDllName.Buffer); + assert(CacheEntry->FullName.Buffer); + LdrpLoadModuleSymbols(&LdrModule->FullDllName, &LdrModule->SymbolInfo); + InsertTailList(&SymbolListHead, &CacheEntry->ListEntry); } - - ZwClose(FileHandle); - - LdrpLoadUserModuleSymbolsFromBuffer(ModuleObject, - FileBuffer, - FileStdInfo.EndOfFile.u.LowPart); - - ExFreePool(FileBuffer); } - -VOID -LdrpUnloadModuleSymbols(PMODULE_OBJECT ModuleObject) -{ - /* FIXME: implement me! */ -} - -#endif /* KDBG */ +#endif /* DBG */ NTSTATUS @@ -894,12 +1007,10 @@ LdrLoadModule(PUNICODE_STRING Filename, /* Cleanup */ ExFreePool(ModuleLoadBase); -#ifdef KDBG - - /* Load symbols for module if available */ - LdrpLoadModuleSymbols(Module); - -#endif /* KDBG */ +#ifdef DBG + /* Load symbols for the image if available */ + LdrpLoadModuleSymbols(Filename, &Module->TextSection->SymbolInfo); +#endif /* DBG */ *ModuleObject = Module; @@ -917,10 +1028,10 @@ LdrUnloadModule(PMODULE_OBJECT ModuleObject) RemoveEntryList(&ModuleObject->ListEntry); KeReleaseSpinLock(&ModuleListLock, Irql); -#ifdef KDBG +#ifdef DBG /* Unload symbols for module if available */ - LdrpUnloadModuleSymbols(ModuleObject); -#endif /* KDBG */ + LdrUnloadModuleSymbols(&ModuleObject->TextSection->SymbolInfo); +#endif /* DBG */ /* Free text section */ if (ModuleObject->TextSection != NULL) @@ -945,6 +1056,10 @@ LdrInitializeBootStartDriver(PVOID ModuleLoadBase, PCHAR FileName, ULONG ModuleLength) { +#ifdef DBG + PSYMBOLFILE_HEADER SymbolFileHeader; + PIMAGE_SYMBOL_INFO SymbolInfo; +#endif /* DBG */ PMODULE_OBJECT ModuleObject; UNICODE_STRING ModuleName; PDEVICE_NODE DeviceNode; @@ -954,16 +1069,16 @@ LdrInitializeBootStartDriver(PVOID ModuleLoadBase, ULONG Length; LPWSTR Start; LPWSTR Ext; + PCHAR FileExt; CHAR TextBuffer [256]; ULONG x, y, cx, cy; -#ifdef KDBG +#ifdef DBG CHAR TmpBaseName[MAX_PATH]; CHAR TmpFileName[MAX_PATH]; ANSI_STRING AnsiString; - PCHAR FileExt; -#endif +#endif /* DBG */ HalQueryDisplayParameters(&x, &y, &cx, &cy); RtlFillMemory(TextBuffer, x, ' '); @@ -976,7 +1091,6 @@ LdrInitializeBootStartDriver(PVOID ModuleLoadBase, HalDisplayString(TextBuffer); HalSetDisplayParameters(cx, cy); -#ifdef KDBG /* Split the filename into base name and extension */ FileExt = strrchr(FileName, '.'); if (FileExt != NULL) @@ -984,6 +1098,8 @@ LdrInitializeBootStartDriver(PVOID ModuleLoadBase, else Length = strlen(FileName); +#ifdef DBG + if ((FileExt != NULL) && (strcmp(FileExt, ".sym") == 0)) { DPRINT("Module %s is a symbol file\n", FileName); @@ -997,8 +1113,6 @@ LdrInitializeBootStartDriver(PVOID ModuleLoadBase, strcat(TmpFileName, ".sys"); RtlInitAnsiString(&AnsiString, TmpFileName); - DPRINT("dasdsad: %s\n", TmpFileName); - RtlAnsiStringToUnicodeString(&ModuleName, &AnsiString, TRUE); ModuleObject = LdrGetModuleObject(&ModuleName); RtlFreeUnicodeString(&ModuleName); @@ -1013,17 +1127,29 @@ LdrInitializeBootStartDriver(PVOID ModuleLoadBase, } if (ModuleObject != NULL) { - LdrpLoadModuleSymbolsFromBuffer(ModuleObject, - ModuleLoadBase, - ModuleLength); + SymbolInfo = (PIMAGE_SYMBOL_INFO) &ModuleObject->TextSection->SymbolInfo; + SymbolFileHeader = (PSYMBOLFILE_HEADER) ModuleLoadBase; + SymbolInfo->FileBuffer = ModuleLoadBase; + SymbolInfo->SymbolsBase = ModuleLoadBase + SymbolFileHeader->StabsOffset; + SymbolInfo->SymbolsLength = SymbolFileHeader->StabsLength; + SymbolInfo->SymbolStringsBase = ModuleLoadBase + SymbolFileHeader->StabstrOffset; + SymbolInfo->SymbolStringsLength = SymbolFileHeader->StabstrLength; } + return(STATUS_SUCCESS); } else { - DPRINT("Module %s is executable\n", FileName); + DPRINT("Module %s is non-symbol file\n", FileName); + } + +#endif /* !DBG */ + + if ((FileExt != NULL) && !(strcmp(FileExt, ".sys") == 0)) + { + CPRINT("Ignoring non-driver file %s\n", FileName); + return STATUS_SUCCESS; } -#endif /* KDBG */ /* Use IopRootDeviceNode for now */ Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &DeviceNode); @@ -1444,7 +1570,8 @@ LdrPEProcessModule(PVOID ModuleLoadBase, PESectionHeaders[Idx].VirtualAddress + DriverBase); memcpy(PESectionHeaders[Idx].VirtualAddress + DriverBase, (PVOID)(ModuleLoadBase + PESectionHeaders[Idx].PointerToRawData), - PESectionHeaders[Idx].Misc.VirtualSize > PESectionHeaders[Idx].SizeOfRawData ? PESectionHeaders[Idx].SizeOfRawData : PESectionHeaders[Idx].Misc.VirtualSize ); + PESectionHeaders[Idx].Misc.VirtualSize > PESectionHeaders[Idx].SizeOfRawData + ? PESectionHeaders[Idx].SizeOfRawData : PESectionHeaders[Idx].Misc.VirtualSize ); } else { @@ -1671,10 +1798,15 @@ LdrPEProcessModule(PVOID ModuleLoadBase, ModuleTextSection = ExAllocatePool(NonPagedPool, sizeof(MODULE_TEXT_SECTION)); + assert(ModuleTextSection); + RtlZeroMemory(ModuleTextSection, sizeof(MODULE_TEXT_SECTION)); ModuleTextSection->Base = (ULONG)DriverBase; ModuleTextSection->Length = DriverSize; - ModuleTextSection->SymbolsBase = NULL; - ModuleTextSection->SymbolsLength = 0; +#ifdef DBG + RtlZeroMemory(&ModuleTextSection->SymbolInfo, sizeof(ModuleTextSection->SymbolInfo)); + ModuleTextSection->SymbolInfo.ImageBase = PEOptionalHeader->ImageBase; + ModuleTextSection->SymbolInfo.ImageSize = ModuleTextSection->Length; +#endif /* DBG */ ModuleTextSection->Name = ExAllocatePool(NonPagedPool, (wcslen(NameBuffer) + 1) * sizeof(WCHAR)); @@ -1689,8 +1821,8 @@ LdrPEProcessModule(PVOID ModuleLoadBase, if ((KdDebuggerEnabled == TRUE) && (KdDebugState & KD_DEBUG_GDB)) { - DbgPrint("Module %wZ loaded at 0x%.08x.\n", - FileName, CreatedModuleObject->Base); + DPRINT("Module %wZ loaded at 0x%.08x.\n", + FileName, CreatedModuleObject->Base); } return STATUS_SUCCESS; diff --git a/reactos/ntoskrnl/ldr/sysdll.c b/reactos/ntoskrnl/ldr/sysdll.c index fc994f095a5..d4fdf9f5d6e 100644 --- a/reactos/ntoskrnl/ldr/sysdll.c +++ b/reactos/ntoskrnl/ldr/sysdll.c @@ -96,7 +96,7 @@ NTSTATUS LdrpMapSystemDll(HANDLE ProcessHandle, FILE_ALL_ACCESS, &FileObjectAttributes, NULL, - 0, + FILE_SHARE_READ, 0); if (!NT_SUCCESS(Status)) { diff --git a/reactos/ntoskrnl/ps/process.c b/reactos/ntoskrnl/ps/process.c index e6822986262..24ba6d62185 100644 --- a/reactos/ntoskrnl/ps/process.c +++ b/reactos/ntoskrnl/ps/process.c @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.84 2002/07/04 19:56:36 dwelch Exp $ +/* $Id: process.c,v 1.85 2002/07/13 12:44:08 chorns Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -278,15 +278,14 @@ PsInitProcessManagment(VOID) &SystemProcessHandle); } -#ifdef KDBG +#ifdef DBG VOID PiFreeSymbols(PPEB Peb) { PLIST_ENTRY CurrentEntry; PLDR_MODULE Current; - PSYMBOL NextSymbol; - PSYMBOL Symbol; + PIMAGE_SYMBOL_INFO SymbolInfo; assert (Peb); assert (Peb->Ldr); @@ -297,21 +296,15 @@ PiFreeSymbols(PPEB Peb) { Current = CONTAINING_RECORD(CurrentEntry, LDR_MODULE, InLoadOrderModuleList); - Symbol = Current->Symbols.Symbols; - while (Symbol != NULL) - { - NextSymbol = Symbol->Next; - RtlFreeUnicodeString (&Symbol->Name); - ExFreePool (Symbol); - Symbol = NextSymbol; - } - Current->Symbols.SymbolCount = 0; - Current->Symbols.Symbols = NULL; + + SymbolInfo = &Current->SymbolInfo; + LdrUnloadModuleSymbols(SymbolInfo); + CurrentEntry = CurrentEntry->Flink; } } -#endif /* KDBG */ +#endif /* DBG */ VOID STDCALL PiDeleteProcess(PVOID ObjectBody) @@ -333,9 +326,9 @@ PiDeleteProcess(PVOID ObjectBody) RemoveEntryList(&Process->ProcessListEntry); KeReleaseSpinLock(&PsProcessListLock, oldIrql); -#ifdef KDBG +#ifdef DBG PiFreeSymbols(Process->Peb); -#endif /* KDBG */ +#endif /* DBG */ ObDereferenceObject(Process->Token); diff --git a/reactos/ntoskrnl/rtl/ctype.c b/reactos/ntoskrnl/rtl/ctype.c index 98940383c64..7301dfb21c9 100644 --- a/reactos/ntoskrnl/rtl/ctype.c +++ b/reactos/ntoskrnl/rtl/ctype.c @@ -1,4 +1,4 @@ -/* $Id: ctype.c,v 1.7 2002/06/16 17:25:58 chorns Exp $ +/* $Id: ctype.c,v 1.8 2002/07/13 12:44:08 chorns Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -13,6 +13,7 @@ #include +#undef _pctype #define upalpha ('A' - 'a') diff --git a/reactos/ntoskrnl/rtl/string.c b/reactos/ntoskrnl/rtl/string.c index d595991ae61..99fd4ee7c10 100644 --- a/reactos/ntoskrnl/rtl/string.c +++ b/reactos/ntoskrnl/rtl/string.c @@ -239,8 +239,12 @@ char *strncpy(char *dst, const char *src, size_t n) } } while (--n != 0); + d[0] = 0; } - + else + { + dst[0] = 0; + } return dst; } diff --git a/reactos/rules.mak b/reactos/rules.mak index ba2b467472f..355c468cc47 100644 --- a/reactos/rules.mak +++ b/reactos/rules.mak @@ -76,6 +76,7 @@ CP = $(TOOLS_PATH)/rcopy RM = $(TOOLS_PATH)/rdel RMDIR = $(TOOLS_PATH)/rrmdir RMKDIR = $(TOOLS_PATH)/rmkdir +RSYM = $(TOOLS_PATH)/rsym MC = $(TOOLS_PATH)/wmc/wmc diff --git a/reactos/tools/Makefile b/reactos/tools/Makefile index a73a451e139..c46f3d922ba 100644 --- a/reactos/tools/Makefile +++ b/reactos/tools/Makefile @@ -6,7 +6,8 @@ TOOLS = \ rcopy$(EXE_POSTFIX) \ rdel$(EXE_POSTFIX) \ rmkdir$(EXE_POSTFIX) \ - rrmdir$(EXE_POSTFIX) + rrmdir$(EXE_POSTFIX) \ + rsym$(EXE_POSTFIX) CLEAN_FILES = $(TOOLS) @@ -50,6 +51,15 @@ rrmdir$(EXE_POSTFIX): rrmdir.c $(HOST_CC) $(CFLAGS) -DDOS_PATHS rrmdir.c -o rrmdir$(EXE_POSTFIX) endif +ifeq ($(HOST),mingw32-linux) +rsym$(EXE_POSTFIX): rsym.c + $(HOST_CC) $(CFLAGS) -DUNIX_PATHS rsym.c -o rsym$(EXE_POSTFIX) +endif +ifeq ($(HOST),mingw32-windows) +rsym$(EX_POSTFIX): rsym.c + $(HOST_CC) $(CFLAGS) -DDOS_PATHS rsym.c -o rsym$(EXE_POSTFIX) +endif + wmc_directory_target: make -C wmc wmc$(EXE_POSTFIX) diff --git a/reactos/tools/helper.mk b/reactos/tools/helper.mk index ba5c262390f..701e80aa6c3 100644 --- a/reactos/tools/helper.mk +++ b/reactos/tools/helper.mk @@ -1,4 +1,4 @@ -# $Id: helper.mk,v 1.18 2002/06/30 02:40:24 ei Exp $ +# $Id: helper.mk,v 1.19 2002/07/13 12:44:09 chorns Exp $ # # Helper makefile for ReactOS modules # Variables this makefile accepts: @@ -42,6 +42,9 @@ # $WINE_MODE = Compile using WINE headers (no,yes) (optional) # $WINE_RC = Name of .rc file for WINE modules (optional) +include $(PATH_TO_TOP)/config + + ifeq ($(TARGET_PATH),) TARGET_PATH := . endif @@ -378,7 +381,8 @@ include $(PATH_TO_TOP)/config TARGET_CFLAGS += $(MK_CFLAGS) TARGET_CFLAGS += -pipe -march=$(ARCH) ifeq ($(DBG),1) -#TARGET_CFLAGS += -g +TARGET_CFLAGS += -g +TARGET_LFLAGS += -g endif TARGET_CPPFLAGS += $(MK_CPPFLAGS) @@ -456,7 +460,7 @@ endif -o $(MK_NOSTRIPNAME) \ $(MK_FULLRES) $(MK_OBJECTS) $(MK_LIBS) $(MK_GCCLIBS) - $(RM) temp.exp - - $(NM) --numeric-sort $(MK_NOSTRIPNAME) > $(MK_BASENAME).sym + - $(RSYM) $(MK_NOSTRIPNAME) $(MK_BASENAME).sym $(MK_FULLNAME): $(MK_NOSTRIPNAME) $(CP) $(MK_NOSTRIPNAME) $(MK_FULLNAME) @@ -496,7 +500,7 @@ $(MK_NOSTRIPNAME): $(MK_FULLRES) $(TARGET_OBJECTS) $(MK_LIBS) -o $(MK_NOSTRIPNAME) \ $(MK_FULLRES) $(MK_OBJECTS) $(MK_LIBS) $(MK_GCCLIBS) - $(RM) temp.exp - $(NM) --numeric-sort $(MK_NOSTRIPNAME) > $(MK_BASENAME).sym + $(RSYM) $(MK_NOSTRIPNAME) $(MK_BASENAME).sym $(MK_FULLNAME): $(MK_FULLRES) $(TARGET_OBJECTS) $(MK_LIBS) $(MK_NOSTRIPNAME) $(LD) -r -o $(MK_STRIPPED_OBJECT) $(MK_OBJECTS) @@ -583,6 +587,7 @@ $(INSTALL_DIR)/$(MK_INSTALLDIR)/$(MK_FULLNAME): $(MK_FULLNAME) $(MK_BASENAME).sy $(CP) $(MK_FULLNAME) $(INSTALL_DIR)/$(MK_INSTALLDIR)/$(MK_FULLNAME) $(CP) $(MK_BASENAME).sym $(INSTALL_DIR)/symbols/$(MK_BASENAME).sym + dist: $(DIST_DIR)/$(MK_DISTDIR)/$(MK_FULLNAME) $(DIST_DIR)/$(MK_DISTDIR)/$(MK_FULLNAME): $(MK_FULLNAME) diff --git a/reactos/tools/rsym.c b/reactos/tools/rsym.c new file mode 100644 index 00000000000..cf2638ababa --- /dev/null +++ b/reactos/tools/rsym.c @@ -0,0 +1,255 @@ +/* + * Usage: rsym input-file output-file + */ +#include +#include +#include + +#define NULL ((void*)0) + +#define IMAGE_DOS_MAGIC 0x5a4d +#define IMAGE_PE_MAGIC 0x00004550 + +#define IMAGE_SIZEOF_SHORT_NAME 8 + +#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 + +typedef void* PVOID; +typedef unsigned char BYTE; +typedef unsigned short WORD; +typedef unsigned long DWORD; +typedef signed long LONG; +typedef unsigned long ULONG; + +#pragma pack(push,2) +typedef struct _IMAGE_DOS_HEADER { + WORD e_magic; + WORD e_cblp; + WORD e_cp; + WORD e_crlc; + WORD e_cparhdr; + WORD e_minalloc; + WORD e_maxalloc; + WORD e_ss; + WORD e_sp; + WORD e_csum; + WORD e_ip; + WORD e_cs; + WORD e_lfarlc; + WORD e_ovno; + WORD e_res[4]; + WORD e_oemid; + WORD e_oeminfo; + WORD e_res2[10]; + LONG e_lfanew; +} IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER; +#pragma pack(pop) +#pragma pack(push,4) +typedef struct _IMAGE_DATA_DIRECTORY { + DWORD VirtualAddress; + DWORD Size; +} IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY; +typedef struct _IMAGE_OPTIONAL_HEADER { + WORD Magic; + BYTE MajorLinkerVersion; + BYTE MinorLinkerVersion; + DWORD SizeOfCode; + DWORD SizeOfInitializedData; + DWORD SizeOfUninitializedData; + DWORD AddressOfEntryPoint; + DWORD BaseOfCode; + DWORD BaseOfData; + DWORD ImageBase; + DWORD SectionAlignment; + DWORD FileAlignment; + WORD MajorOperatingSystemVersion; + WORD MinorOperatingSystemVersion; + WORD MajorImageVersion; + WORD MinorImageVersion; + WORD MajorSubsystemVersion; + WORD MinorSubsystemVersion; + DWORD Reserved1; + DWORD SizeOfImage; + DWORD SizeOfHeaders; + DWORD CheckSum; + WORD Subsystem; + WORD DllCharacteristics; + DWORD SizeOfStackReserve; + DWORD SizeOfStackCommit; + DWORD SizeOfHeapReserve; + DWORD SizeOfHeapCommit; + DWORD LoaderFlags; + DWORD NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} IMAGE_OPTIONAL_HEADER,*PIMAGE_OPTIONAL_HEADER; +typedef struct _IMAGE_FILE_HEADER { + WORD Machine; + WORD NumberOfSections; + DWORD TimeDateStamp; + DWORD PointerToSymbolTable; + DWORD NumberOfSymbols; + WORD SizeOfOptionalHeader; + WORD Characteristics; +} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; +typedef struct _IMAGE_SECTION_HEADER { + BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; + union { + DWORD PhysicalAddress; + DWORD VirtualSize; + } Misc; + DWORD VirtualAddress; + DWORD SizeOfRawData; + DWORD PointerToRawData; + DWORD PointerToRelocations; + DWORD PointerToLinenumbers; + WORD NumberOfRelocations; + WORD NumberOfLinenumbers; + DWORD Characteristics; +} IMAGE_SECTION_HEADER,*PIMAGE_SECTION_HEADER; +#pragma pack(pop) + +typedef struct _SYMBOLFILE_HEADER { + unsigned long StabsOffset; + unsigned long StabsLength; + unsigned long StabstrOffset; + unsigned long StabstrLength; +} SYMBOLFILE_HEADER, *PSYMBOLFILE_HEADER; + + +char* convert_path(char* origpath) +{ + char* newpath; + int i; + + newpath = strdup(origpath); + + i = 0; + while (newpath[i] != 0) + { +#ifdef UNIX_PATHS + if (newpath[i] == '\\') + { + newpath[i] = '/'; + } +#else +#ifdef DOS_PATHS + if (newpath[i] == '/') + { + newpath[i] = '\\'; + } +#endif +#endif + i++; + } + return(newpath); +} + +#define TRANSFER_SIZE (65536) + +int main(int argc, char* argv[]) +{ + SYMBOLFILE_HEADER SymbolFileHeader; + IMAGE_DOS_HEADER PEDosHeader; + IMAGE_FILE_HEADER PEFileHeader; + PIMAGE_SECTION_HEADER PESectionHeaders; + PVOID SymbolsBase; + ULONG SymbolsLength; + PVOID SymbolStringsBase; + ULONG SymbolStringsLength; + ULONG Idx; + char* path1; + char* path2; + FILE* in; + FILE* out; + char* buf; + int n_in; + int n_out; + + if (argc != 3) + { + fprintf(stderr, "Too many arguments\n"); + exit(1); + } + + path1 = convert_path(argv[1]); + path2 = convert_path(argv[2]); + + in = fopen(path1, "rb"); + if (in == NULL) + { + perror("Cannot open input file"); + exit(1); + } + + out = fopen(path2, "wb"); + if (out == NULL) + { + perror("Cannot open output file"); + fclose(in); + exit(1); + } + + /* Check if MZ header exists */ + n_in = fread(&PEDosHeader, 1, sizeof(PEDosHeader), in); + if (PEDosHeader.e_magic != IMAGE_DOS_MAGIC && PEDosHeader.e_lfanew != 0L) + { + perror("Input file is not a PE image.\n"); + } + + /* Read PE file header */ + /* sizeof(ULONG) = sizeof(MAGIC) */ + fseek(in, PEDosHeader.e_lfanew + sizeof(ULONG), SEEK_SET); + n_in = fread(&PEFileHeader, 1, sizeof(PEFileHeader), in); + + /* Read PE section headers */ + PESectionHeaders = malloc(PEFileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER)); + fseek(in, PEDosHeader.e_lfanew + sizeof(ULONG) + sizeof(IMAGE_FILE_HEADER) + + sizeof(IMAGE_OPTIONAL_HEADER), SEEK_SET); + n_in = fread(PESectionHeaders, 1, PEFileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER), in); + + /* Copy .stab and .stabstr sections if available */ + SymbolsBase = NULL; + SymbolsLength = 0; + SymbolStringsBase = NULL; + SymbolStringsLength = 0; + + for (Idx = 0; Idx < PEFileHeader.NumberOfSections; Idx++) + { + //printf("section: '%.08s'\n", PESectionHeaders[Idx].Name); + if ((strncmp(PESectionHeaders[Idx].Name, ".stab", 5) == 0) + && (PESectionHeaders[Idx].Name[5] == 0)) + { + //printf(".stab section found. Size %d\n", + // PESectionHeaders[Idx].SizeOfRawData); + + SymbolsLength = PESectionHeaders[Idx].SizeOfRawData; + SymbolsBase = malloc(SymbolsLength); + + fseek(in, PESectionHeaders[Idx].PointerToRawData, SEEK_SET); + n_in = fread(SymbolsBase, 1, SymbolsLength, in); + } + + if (strncmp(PESectionHeaders[Idx].Name, ".stabstr", 8) == 0) + { + //printf(".stabstr section found. Size %d\n", + // PESectionHeaders[Idx].SizeOfRawData); + + SymbolStringsLength = PESectionHeaders[Idx].SizeOfRawData; + SymbolStringsBase = malloc(SymbolStringsLength); + + fseek(in, PESectionHeaders[Idx].PointerToRawData, SEEK_SET); + n_in = fread(SymbolStringsBase, 1, SymbolStringsLength, in); + } + } + + SymbolFileHeader.StabsOffset = sizeof(SYMBOLFILE_HEADER); + SymbolFileHeader.StabsLength = SymbolsLength; + SymbolFileHeader.StabstrOffset = SymbolFileHeader.StabsOffset + SymbolsLength; + SymbolFileHeader.StabstrLength = SymbolStringsLength; + + n_out = fwrite(&SymbolFileHeader, 1, sizeof(SYMBOLFILE_HEADER), out); + n_out = fwrite(SymbolsBase, 1, SymbolsLength, out); + n_out = fwrite(SymbolStringsBase, 1, SymbolStringsLength, out); + + exit(0); +}