LIB_FSLIB = vfatlib
# Static libraries
-LIB_STATIC = string rosrtl epsapi uuid libwine zlib rtl tgetopt pseh adns dxguid strmiids crt
+LIB_STATIC = string rosrtl epsapi uuid libwine zlib rtl tgetopt pseh adns dxguid strmiids crt rossym
# Keyboard layout libraries
DLLS_KBD = kbdda kbddv kbdes kbdfr kbdgr kbdse kbduk kbdus
COMPILER_DEFINES = -D__$(TARGET)__ $(COMPILER_DEBUG_DEFINES)
-COMPILER_INCLUDES = -I$(SRCDIR)/include
+COMPILER_INCLUDES = -I$(SRCDIR)/include -I$(PATH_TO_TOP)/include
CFLAGS = $(COMPILER_OPTIONS) \
$(COMPILER_DEFINES) \
@echo Make ALL done.
-freeldr.sys : $(ALL_OBJS)
+freeldr.sys : $(ALL_OBJS) $(PATH_TO_TOP)/dk/w32/lib/librossym.a
@echo ===================================================== LINKING $@
- @$(LD) $(LFLAGS) -o freeldr.exe $(F_OBJS)
+ @$(LD) $(LFLAGS) -o freeldr.exe $(F_OBJS) $(PATH_TO_TOP)/dk/w32/lib/librossym.a
ifeq ($(FULL_MAP),yes)
@$(OBJDUMP) -d -S freeldr.exe > freeldr.map
else
#define BOOLEAN int
typedef BOOLEAN *PBOOLEAN;
-#define CHAR char
-#define PCHAR char *
-#define UCHAR unsigned char
-#define PUCHAR unsigned char *
-#define WCHAR unsigned short
-#define PWCHAR unsigned short *
+#define CHAR char
+#define PCHAR char *
+#define UCHAR unsigned char
+#define PUCHAR unsigned char *
+#define WCHAR unsigned short
+#define PWCHAR unsigned short *
+#define ULONG unsigned long
+#if defined(_WIN64)
+#define ULONG_PTR __int64
+#else
+#define ULONG_PTR unsigned long
+#endif
#define VOID void
#define PVOID VOID*
return TRUE;
}
-#if 0
-BOOL MultiBootLoadModule(FILE *ModuleImage, char *ModuleName)
-{
- U32 dwModuleSize;
- module_t* pModule;
- char* ModuleNameString;
- char * TempName;
-
- /*
- * Get current module data structure and module name string array
- */
- pModule = &multiboot_modules[mb_info.mods_count];
- do {
- TempName = strchr( ModuleName, '\\' );
- if( TempName )
- ModuleName = TempName + 1;
- } while( TempName );
-
- ModuleNameString = multiboot_module_strings[mb_info.mods_count];
-
- dwModuleSize = FsGetFileSize(ModuleImage);
- pModule->mod_start = next_module_load_base;
- pModule->mod_end = next_module_load_base + dwModuleSize;
- strcpy(ModuleNameString, ModuleName);
- pModule->string = (unsigned long)ModuleNameString;
-
- /*
- * Load the file image
- */
- FsReadFile(ModuleImage, dwModuleSize, NULL, (void*)next_module_load_base);
-
- next_module_load_base = ROUND_UP(pModule->mod_end, /*PAGE_SIZE*/4096);
- mb_info.mods_count++;
-
- return TRUE;
-}
-#endif
-
PVOID MultiBootLoadModule(FILE *ModuleImage, char *ModuleName, U32* ModuleSize)
{
U32 dwModuleSize;
#include <machine.h>
#include <inifile.h>
+#include <reactos/rossym.h>
+
#include "registry.h"
return(TRUE);
}
-static BOOL
-LoadSymbolFile(PCHAR szSystemRoot,
- PCHAR ModuleName,
- int nPos)
+static PVOID
+FreeldrAllocMem(ULONG_PTR Size)
{
- CHAR SymbolFileName[1024];
- PFILE FilePointer;
- U32 Length;
- PCHAR Start;
- PCHAR Ext;
- char value[256];
- char *p;
+ return MmAllocateMemory((U32) Size);
+}
- /* Get the path to the symbol store */
- strcpy(SymbolFileName, szSystemRoot);
- strcat(SymbolFileName, "symbols\\");
+static VOID
+FreeldrFreeMem(PVOID Area)
+{
+ MmFreeMemory(Area);
+}
- /* Get the symbol filename from the module name */
- Start = strrchr(ModuleName, '\\');
- if (Start == NULL)
- Start = ModuleName;
- else
- Start++;
+static BOOLEAN
+FreeldrReadFile(PVOID FileContext, PVOID Buffer, ULONG Size)
+{
+ U32 BytesRead;
- Ext = strrchr(ModuleName, '.');
- if (Ext != NULL)
- Length = Ext - Start;
- else
- Length = strlen(Start);
+ return FsReadFile((PFILE) FileContext, (U32) Size, &BytesRead, Buffer)
+ && Size == BytesRead;
+}
+
+static BOOLEAN
+FreeldrSeekFile(PVOID FileContext, ULONG_PTR Position)
+{
+ FsSetFilePointer((PFILE) FileContext, (U32) Position);
- strncat(SymbolFileName, Start, Length);
- strcat(SymbolFileName, ".sym");
+ return TRUE;
+}
- FilePointer = FsOpenFile((PCHAR)&SymbolFileName[0]);
+static BOOL
+LoadKernelSymbols(PCHAR szKernelName, int nPos)
+{
+ static ROSSYM_CALLBACKS FreeldrCallbacks =
+ {
+ FreeldrAllocMem,
+ FreeldrFreeMem,
+ FreeldrReadFile,
+ FreeldrSeekFile
+ };
+ PFILE FilePointer;
+ PROSSYM_INFO RosSymInfo;
+ U32 Size;
+ PVOID Base;
+
+ RosSymInit(&FreeldrCallbacks);
+
+ FilePointer = FsOpenFile(szKernelName);
if (FilePointer == NULL)
{
- DbgPrint((DPRINT_REACTOS, "Symbol file %s not loaded.\n", SymbolFileName));
- /* This is not critical */
return FALSE;
}
- DbgPrint((DPRINT_REACTOS, "Symbol file %s is loaded.\n", SymbolFileName));
-
- /*
- * Update the status bar with the current file
- */
- strcpy(value, "Reading ");
- p = strrchr(SymbolFileName, '\\');
- if (p == NULL)
- strcat(value, SymbolFileName);
- else
- strcat(value, p + 1);
- UiDrawStatusText(value);
+ if (! RosSymCreateFromFile(FilePointer, &RosSymInfo))
+ {
+ return FALSE;
+ }
- /*
- * Load the symbol file
- */
- MultiBootLoadModule(FilePointer, SymbolFileName, NULL);
+ Base = MultiBootCreateModule("NTOSKRNL.SYM");
+ Size = RosSymGetRawDataLength(RosSymInfo);
+ RosSymGetRawData(RosSymInfo, Base);
+ MultiBootCloseModule(Base, Size);
- UiDrawProgressBarCenter(nPos, 100, "Loading ReactOS...");
+ RosSymDelete(RosSymInfo);
- return (TRUE);
+ return TRUE;
}
-
static BOOL
LoadDriver(PCHAR szFileName, int nPos)
{
nPos += 5;
LoadDriver(ImagePath, nPos);
- LoadSymbolFile(szSystemRoot, ImagePath, nPos);
}
else
{
nPos += 5;
LoadDriver(ImagePath, nPos);
- LoadSymbolFile(szSystemRoot, ImagePath, nPos);
}
else
{
UiMessageBox(MsgBuffer);
return;
}
- UiDrawProgressBarCenter(25, 100, "Loading ReactOS...");
+ UiDrawProgressBarCenter(30, 100, "Loading ReactOS...");
/*
- * Load symbol files
+ * Load kernel symbols
*/
- LoadSymbolFile(szBootPath, szKernelName, 30);
- LoadSymbolFile(szBootPath, szHalName, 30);
-
- UiDrawProgressBarCenter(30, 100, "Loading ReactOS...");
+ LoadKernelSymbols(szKernelName, 30);
+ UiDrawProgressBarCenter(40, 100, "Loading ReactOS...");
/*
* Load boot drivers
*/
- LoadBootDrivers(szBootPath, 30);
-
+ LoadBootDrivers(szBootPath, 40);
#if 0
/*
boot_reactos();
}
+#undef DbgPrint
+ULONG
+DbgPrint(char *Fmt, ...)
+{
+ UiMessageBox(Fmt);
+ return 0;
+}
+
/* EOF */
#ifndef __NTOSKRNL_INCLUDE_INTERNAL_LDR_H
#define __NTOSKRNL_INCLUDE_INTERNAL_LDR_H
-#include <ntos/kdbgsyms.h>
#include <roscfg.h>
#include <napi/teb.h>
+#include <reactos/rossym.h>
typedef NTSTATUS STDCALL_FUNC (*PEPFUNC)(PPEB);
ULONG CheckSum;
ULONG TimeDateStamp;
#if defined(DBG) || defined(KDBG)
- IMAGE_SYMBOL_INFO SymbolInfo;
+ PROSSYM_INFO RosSymInfo;
#endif /* KDBG */
} LDR_MODULE, *PLDR_MODULE;
#include "ntos/gditypes.h"
#include "ntos/fstypes.h" /* AG */
#include "ntos/heap.h"
-#include "ntos/kdbgsyms.h"
#include "ntos/keyboard.h"
#include "ntos/minmax.h"
#include "ntos/mm.h"
#include "ntos/file.h"
#include "ntos/gditypes.h"
#include "ntos/heap.h"
-#include "ntos/kdbgsyms.h"
#include "ntos/keyboard.h"
#include "ntos/minmax.h"
#include "ntos/mm.h"
+++ /dev/null
-#ifndef __KDBGSYMS_H
-#define __KDBGSYMS_H
-
-#include <ddk/ntddk.h>
-
-typedef struct _IMAGE_SYMBOL_INFO
-{
- ULONG_PTR ImageBase;
- ULONG_PTR ImageSize;
- PVOID FileBuffer;
- PVOID StabsBase;
- ULONG StabsLength;
- PVOID StabStringsBase;
- ULONG StabStringsLength;
- PVOID SymbolsBase;
- ULONG SymbolsLength;
- PVOID SymbolStringsBase;
- ULONG SymbolStringsLength;
-} IMAGE_SYMBOL_INFO, *PIMAGE_SYMBOL_INFO;
-
-#endif /* __KDBGSYMS_H */
-
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: include/reactos/rossym.h
+ * PURPOSE: Handling of rossym symbol info
+ *
+ * PROGRAMMERS: Ge van Geldorp (gvg@reactos.com)
+ */
+
+#ifndef REACTOS_ROSSYM_H_INCLUDED
+#define REACTOS_ROSSYM_H_INCLUDED
+
+#define ROSSYM_SECTION_NAME ".rossym"
+
+typedef struct _ROSSYM_HEADER {
+ unsigned long SymbolsOffset;
+ unsigned long SymbolsLength;
+ unsigned long StringsOffset;
+ unsigned long StringsLength;
+} ROSSYM_HEADER, *PROSSYM_HEADER;
+
+typedef struct _ROSSYM_ENTRY {
+ ULONG_PTR Address;
+ ULONG FunctionOffset;
+ ULONG FileOffset;
+ ULONG SourceLine;
+} ROSSYM_ENTRY, *PROSSYM_ENTRY;
+
+typedef struct _ROSSYM_CALLBACKS {
+ PVOID (*AllocMemProc)(ULONG_PTR Size);
+ VOID (*FreeMemProc)(PVOID Area);
+ BOOLEAN (*ReadFileProc)(PVOID FileContext, PVOID Buffer, ULONG Size);
+ BOOLEAN (*SeekFileProc)(PVOID FileContext, ULONG_PTR Position);
+} ROSSYM_CALLBACKS, *PROSSYM_CALLBACKS;
+
+typedef struct _ROSSYM_INFO *PROSSYM_INFO;
+
+VOID RosSymInit(PROSSYM_CALLBACKS Callbacks);
+VOID RosSymInitKernelMode(VOID);
+VOID RosSymInitUserMode(VOID);
+
+BOOLEAN RosSymCreateFromRaw(PVOID RawData, ULONG_PTR DataSize,
+ PROSSYM_INFO *RosSymInfo);
+BOOLEAN RosSymCreateFromMem(PVOID ImageStart, ULONG_PTR ImageSize,
+ PROSSYM_INFO *RosSymInfo);
+BOOLEAN RosSymCreateFromFile(PVOID FileContext, PROSSYM_INFO *RosSymInfo);
+ULONG RosSymGetRawDataLength(PROSSYM_INFO RosSymInfo);
+VOID RosSymGetRawData(PROSSYM_INFO RosSymInfo, PVOID RawData);
+BOOLEAN RosSymGetAddressInformation(PROSSYM_INFO RosSymInfo,
+ ULONG_PTR RelativeAddress,
+ ULONG *LineNumber,
+ char *FileName,
+ char *FunctionName);
+VOID RosSymDelete(PROSSYM_INFO RosSymInfo);
+
+#endif /* REACTOS_ROSSYM_H_INCLUDED */
+
+/* EOF */
+
--- /dev/null
+PATH_TO_TOP = ../..
+
+TARGET_TYPE = library
+
+TARGET_NAME = rossym
+
+include $(PATH_TO_TOP)/config
+
+TARGET_CFLAGS = -Wall -Werror -ffreestanding -D__USE_W32API
+
+TARGET_OBJECTS = \
+ delete.o \
+ find.o \
+ fromfile.o \
+ frommem.o \
+ fromraw.o \
+ getraw.o \
+ init.o \
+ initkm.o \
+ initum.o \
+ zwfile.o
+
+include $(PATH_TO_TOP)/rules.mak
+
+include $(TOOLS_PATH)/helper.mk
+
+DEP_OBJECTS := $(TARGET_OBJECTS)
+
+TARGET_CLEAN = $(DEP_FILES)
+
+include $(PATH_TO_TOP)/tools/depend.mk
+
+# EOF
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: lib/rossym/delete.c
+ * PURPOSE: Free rossym info
+ *
+ * PROGRAMMERS: Ge van Geldorp (gvg@reactos.com)
+ */
+
+#define NTOSAPI
+#include <ddk/ntddk.h>
+#include <reactos/rossym.h>
+#include "rossympriv.h"
+
+#define NDEBUG
+#include <debug.h>
+
+VOID
+RosSymDelete(PROSSYM_INFO RosSymInfo)
+{
+ RosSymFreeMem(RosSymInfo);
+}
+
+/* EOF */
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: lib/rossym/find.c
+ * PURPOSE: Find symbol info for an address
+ *
+ * PROGRAMMERS: Ge van Geldorp (gvg@reactos.com)
+ */
+/*
+ * Parts of this file based on work Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define NTOSAPI
+#include <ddk/ntddk.h>
+#include <reactos/rossym.h>
+#include "rossympriv.h"
+
+#define NDEBUG
+#include <debug.h>
+
+static PROSSYM_ENTRY
+FindEntry(IN PROSSYM_INFO RosSymInfo, IN ULONG_PTR RelativeAddress)
+{
+ /*
+ * Perform a binary search.
+ *
+ * The code below is a bit sneaky. After a comparison fails, we
+ * divide the work in half by moving either left or right. If lim
+ * is odd, moving left simply involves halving lim: e.g., when lim
+ * is 5 we look at item 2, so we change lim to 2 so that we will
+ * look at items 0 & 1. If lim is even, the same applies. If lim
+ * is odd, moving right again involes halving lim, this time moving
+ * the base up one item past p: e.g., when lim is 5 we change base
+ * to item 3 and make lim 2 so that we will look at items 3 and 4.
+ * If lim is even, however, we have to shrink it by one before
+ * halving: e.g., when lim is 4, we still looked at item 2, so we
+ * have to make lim 3, then halve, obtaining 1, so that we will only
+ * look at item 3.
+ */
+ PROSSYM_ENTRY Base = RosSymInfo->Symbols;
+ ULONG Lim;
+ PROSSYM_ENTRY Mid, Low;
+
+ if (RelativeAddress < Base->Address)
+ {
+ return NULL;
+ }
+
+ Low = Base;
+ for (Lim = RosSymInfo->SymbolsCount; Lim != 0; Lim >>= 1)
+ {
+ Mid = Base + (Lim >> 1);
+ if (RelativeAddress == Mid->Address)
+ {
+ return Mid;
+ }
+ if (Mid->Address < RelativeAddress) /* key > mid: move right */
+ {
+ Low = Mid;
+ Base = Mid + 1;
+ Lim--;
+ } /* else move left */
+ }
+
+ return Low;
+}
+
+
+BOOLEAN
+RosSymGetAddressInformation(PROSSYM_INFO RosSymInfo,
+ ULONG_PTR RelativeAddress,
+ ULONG *LineNumber,
+ char *FileName,
+ char *FunctionName)
+{
+ PROSSYM_ENTRY RosSymEntry;
+
+ DPRINT("RelativeAddress = 0x%08x\n", RelativeAddress);
+
+ if (RosSymInfo->Symbols == NULL || RosSymInfo->SymbolsCount == 0 ||
+ RosSymInfo->Strings == NULL || RosSymInfo->StringsLength == 0)
+ {
+__asm__("int $3\n");
+ DPRINT1("Uninitialized RosSymInfo\n");
+ return FALSE;
+ }
+
+ ASSERT(LineNumber || FileName || FunctionName);
+
+ /* find symbol entry for function */
+ RosSymEntry = FindEntry(RosSymInfo, RelativeAddress);
+
+ if (NULL == RosSymEntry)
+ {
+ DPRINT("None of the requested information was found!\n");
+ return FALSE;
+ }
+
+ if (LineNumber != NULL)
+ {
+ *LineNumber = RosSymEntry->SourceLine;
+ }
+ if (FileName != NULL)
+ {
+ PCHAR Name = "";
+ if (RosSymEntry->FileOffset != 0)
+ {
+ Name = (PCHAR) RosSymInfo->Strings + RosSymEntry->FileOffset;
+ }
+ strcpy(FileName, Name);
+ }
+ if (FunctionName != NULL)
+ {
+ PCHAR Name = "";
+ if (RosSymEntry->FunctionOffset != 0)
+ {
+ Name = (PCHAR) RosSymInfo->Strings + RosSymEntry->FunctionOffset;
+ }
+ strcpy(FunctionName, Name);
+ }
+
+ return TRUE;
+}
+
+/* EOF */
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: lib/rossym/fromfile.c
+ * PURPOSE: Creating rossym info from a file
+ *
+ * PROGRAMMERS: Ge van Geldorp (gvg@reactos.com)
+ */
+
+#define NTOSAPI
+#include <ddk/ntddk.h>
+#include <reactos/rossym.h>
+#include "rossympriv.h"
+
+#define NDEBUG
+#include <debug.h>
+
+BOOLEAN
+RosSymCreateFromFile(PVOID FileContext, PROSSYM_INFO *RosSymInfo)
+{
+ IMAGE_DOS_HEADER DosHeader;
+ IMAGE_NT_HEADERS NtHeaders;
+ PIMAGE_SECTION_HEADER SectionHeaders, SectionHeader;
+ unsigned SectionIndex;
+ char SectionName[IMAGE_SIZEOF_SHORT_NAME];
+ ROSSYM_HEADER RosSymHeader;
+
+ /* Load DOS header */
+ if (! RosSymReadFile(FileContext, &DosHeader, sizeof(IMAGE_DOS_HEADER)))
+ {
+ DPRINT1("Failed to read DOS header\n");
+ return FALSE;
+ }
+ if (! ROSSYM_IS_VALID_DOS_HEADER(&DosHeader))
+ {
+ DPRINT1("Image doesn't have a valid DOS header\n");
+ return FALSE;
+ }
+
+ /* Load NT headers */
+ if (! RosSymSeekFile(FileContext, DosHeader.e_lfanew))
+ {
+ DPRINT1("Failed seeking to NT headers\n");
+ return FALSE;
+ }
+ if (! RosSymReadFile(FileContext, &NtHeaders, sizeof(IMAGE_NT_HEADERS)))
+ {
+ DPRINT1("Failed to read NT headers\n");
+ return FALSE;
+ }
+ if (! ROSSYM_IS_VALID_NT_HEADERS(&NtHeaders))
+ {
+ DPRINT1("Image doesn't have a valid PE header\n");
+ return FALSE;
+ }
+
+ /* Load section headers */
+ if (! RosSymSeekFile(FileContext, (char *) IMAGE_FIRST_SECTION(&NtHeaders) -
+ (char *) &NtHeaders + DosHeader.e_lfanew))
+ {
+ DPRINT1("Failed seeking to section headers\n");
+ return FALSE;
+ }
+ SectionHeaders = RosSymAllocMem(NtHeaders.FileHeader.NumberOfSections
+ * sizeof(IMAGE_SECTION_HEADER));
+ if (NULL == SectionHeaders)
+ {
+ DPRINT1("Failed to allocate memory for %u section headers\n",
+ NtHeaders.FileHeader.NumberOfSections);
+ return FALSE;
+ }
+ if (! RosSymReadFile(FileContext, SectionHeaders,
+ NtHeaders.FileHeader.NumberOfSections
+ * sizeof(IMAGE_SECTION_HEADER)))
+ {
+ RosSymFreeMem(SectionHeaders);
+ DPRINT1("Failed to read section headers\n");
+ return FALSE;
+ }
+
+ /* Search for the section header */
+ strncpy(SectionName, ROSSYM_SECTION_NAME, IMAGE_SIZEOF_SHORT_NAME);
+ SectionHeader = SectionHeaders;
+ for (SectionIndex = 0; SectionIndex < NtHeaders.FileHeader.NumberOfSections; SectionIndex++)
+ {
+ if (0 == memcmp(SectionName, SectionHeader->Name, IMAGE_SIZEOF_SHORT_NAME))
+ {
+ break;
+ }
+ SectionHeader++;
+ }
+ if (NtHeaders.FileHeader.NumberOfSections <= SectionIndex)
+ {
+ RosSymFreeMem(SectionHeaders);
+ DPRINT("No %s section found\n", ROSSYM_SECTION_NAME);
+ return FALSE;
+ }
+
+ /* Load rossym header */
+ if (! RosSymSeekFile(FileContext, SectionHeader->PointerToRawData))
+ {
+ RosSymFreeMem(SectionHeaders);
+ DPRINT1("Failed seeking to section data\n");
+ return FALSE;
+ }
+ RosSymFreeMem(SectionHeaders);
+ if (! RosSymReadFile(FileContext, &RosSymHeader, sizeof(ROSSYM_HEADER)))
+ {
+ DPRINT1("Failed to read rossym header\n");
+ return FALSE;
+ }
+ if (RosSymHeader.SymbolsOffset < sizeof(ROSSYM_HEADER)
+ || RosSymHeader.StringsOffset < RosSymHeader.SymbolsOffset + RosSymHeader.SymbolsLength
+ || 0 != (RosSymHeader.SymbolsLength % sizeof(ROSSYM_ENTRY)))
+ {
+ DPRINT1("Invalid ROSSYM_HEADER\n");
+ return FALSE;
+ }
+
+ *RosSymInfo = RosSymAllocMem(sizeof(ROSSYM_INFO) - sizeof(ROSSYM_HEADER)
+ + RosSymHeader.StringsOffset + RosSymHeader.StringsLength + 1);
+ if (NULL == *RosSymInfo)
+ {
+ DPRINT1("Failed to allocate memory for rossym\n");
+ return FALSE;
+ }
+ (*RosSymInfo)->Symbols = (PROSSYM_ENTRY)((char *) *RosSymInfo + sizeof(ROSSYM_INFO)
+ - sizeof(ROSSYM_HEADER) + RosSymHeader.SymbolsOffset);
+ (*RosSymInfo)->SymbolsCount = RosSymHeader.SymbolsLength / sizeof(ROSSYM_ENTRY);
+ (*RosSymInfo)->Strings = (PCHAR) *RosSymInfo + sizeof(ROSSYM_INFO) - sizeof(ROSSYM_HEADER)
+ + RosSymHeader.StringsOffset;
+ (*RosSymInfo)->StringsLength = RosSymHeader.StringsLength;
+ if (! RosSymReadFile(FileContext, *RosSymInfo + 1,
+ RosSymHeader.StringsOffset + RosSymHeader.StringsLength
+ - sizeof(ROSSYM_HEADER)))
+ {
+ DPRINT1("Failed to read rossym headers\n");
+ return FALSE;
+ }
+ /* Make sure the last string is null terminated, we allocated an extra byte for that */
+ (*RosSymInfo)->Strings[(*RosSymInfo)->StringsLength] = '\0';
+
+ return TRUE;
+}
+
+/* EOF */
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: lib/rossym/frommem.c
+ * PURPOSE: Creating rossym info from an in-memory image
+ *
+ * PROGRAMMERS: Ge van Geldorp (gvg@reactos.com)
+ */
+
+#define NTOSAPI
+#include <ddk/ntddk.h>
+#include <reactos/rossym.h>
+#include "rossympriv.h"
+
+#define NDEBUG
+#include <debug.h>
+
+BOOLEAN
+RosSymCreateFromMem(PVOID ImageStart, ULONG_PTR ImageSize, PROSSYM_INFO *RosSymInfo)
+{
+ PIMAGE_DOS_HEADER DosHeader;
+ PIMAGE_NT_HEADERS NtHeaders;
+ PIMAGE_SECTION_HEADER SectionHeader;
+ unsigned SectionIndex;
+ char SectionName[IMAGE_SIZEOF_SHORT_NAME];
+
+ /* Check if MZ header is valid */
+ DosHeader = (PIMAGE_DOS_HEADER) ImageStart;
+ if (ImageSize < sizeof(IMAGE_DOS_HEADER)
+ || ! ROSSYM_IS_VALID_DOS_HEADER(DosHeader))
+ {
+ DPRINT1("Image doesn't have a valid DOS header\n");
+ return FALSE;
+ }
+
+ /* Locate NT header */
+ NtHeaders = (PIMAGE_NT_HEADERS)((char *) ImageStart + DosHeader->e_lfanew);
+ if (ImageSize < DosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS)
+ || ! ROSSYM_IS_VALID_NT_HEADERS(NtHeaders))
+ {
+ DPRINT1("Image doesn't have a valid PE header\n");
+ return FALSE;
+ }
+
+ /* Search for the section header */
+ SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);
+ if (ImageSize < (char *) (SectionHeader + NtHeaders->FileHeader.NumberOfSections)
+ - (char *) ImageStart)
+ {
+ DPRINT1("Image doesn't have valid section headers\n");
+ return FALSE;
+ }
+ strncpy(SectionName, ROSSYM_SECTION_NAME, IMAGE_SIZEOF_SHORT_NAME);
+ for (SectionIndex = 0; SectionIndex < NtHeaders->FileHeader.NumberOfSections; SectionIndex++)
+ {
+ if (0 == memcmp(SectionName, SectionHeader->Name, IMAGE_SIZEOF_SHORT_NAME))
+ {
+ break;
+ }
+ SectionHeader++;
+ }
+ if (NtHeaders->FileHeader.NumberOfSections <= SectionIndex)
+ {
+ DPRINT("No %s section found\n", ROSSYM_SECTION_NAME);
+ return FALSE;
+ }
+
+ /* Locate the section itself */
+ if (ImageSize < SectionHeader->PointerToRawData + SectionHeader->SizeOfRawData
+ || SectionHeader->SizeOfRawData < sizeof(ROSSYM_HEADER))
+ {
+ DPRINT1("Invalid %s section\n", ROSSYM_SECTION_NAME);
+ return FALSE;
+ }
+
+ /* Load it */
+ return RosSymCreateFromRaw((char *) ImageStart + SectionHeader->PointerToRawData,
+ SectionHeader->SizeOfRawData, RosSymInfo);
+}
+
+/* EOF */
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: lib/rossym/frommem.c
+ * PURPOSE: Creating rossym info from an in-memory image
+ *
+ * PROGRAMMERS: Ge van Geldorp (gvg@reactos.com)
+ */
+
+#define NTOSAPI
+#include <ddk/ntddk.h>
+#include <reactos/rossym.h>
+#include "rossympriv.h"
+
+#define NDEBUG
+#include <debug.h>
+
+BOOLEAN
+RosSymCreateFromRaw(PVOID RawData, ULONG_PTR DataSize, PROSSYM_INFO *RosSymInfo)
+{
+ PROSSYM_HEADER RosSymHeader;
+
+ RosSymHeader = (PROSSYM_HEADER) RawData;
+ if (RosSymHeader->SymbolsOffset < sizeof(ROSSYM_HEADER)
+ || RosSymHeader->StringsOffset < RosSymHeader->SymbolsOffset + RosSymHeader->SymbolsLength
+ || DataSize < RosSymHeader->StringsOffset + RosSymHeader->StringsLength
+ || 0 != (RosSymHeader->SymbolsLength % sizeof(ROSSYM_ENTRY)))
+ {
+ DPRINT1("Invalid ROSSYM_HEADER\n");
+ return FALSE;
+ }
+
+ /* Copy */
+ *RosSymInfo = RosSymAllocMem(sizeof(ROSSYM_INFO) + RosSymHeader->SymbolsLength
+ + RosSymHeader->StringsLength + 1);
+ if (NULL == *RosSymInfo)
+ {
+ DPRINT1("Failed to allocate memory for rossym\n");
+ return FALSE;
+ }
+ (*RosSymInfo)->Symbols = (PROSSYM_ENTRY)((char *) *RosSymInfo + sizeof(ROSSYM_INFO));
+ (*RosSymInfo)->SymbolsCount = RosSymHeader->SymbolsLength / sizeof(ROSSYM_ENTRY);
+ (*RosSymInfo)->Strings = (PCHAR) *RosSymInfo + sizeof(ROSSYM_INFO) + RosSymHeader->SymbolsLength;
+ (*RosSymInfo)->StringsLength = RosSymHeader->StringsLength;
+ memcpy((*RosSymInfo)->Symbols, (char *) RosSymHeader + RosSymHeader->SymbolsOffset,
+ RosSymHeader->SymbolsLength);
+ memcpy((*RosSymInfo)->Strings, (char *) RosSymHeader + RosSymHeader->StringsOffset,
+ RosSymHeader->StringsLength);
+ /* Make sure the last string is null terminated, we allocated an extra byte for that */
+ (*RosSymInfo)->Strings[(*RosSymInfo)->StringsLength] = '\0';
+
+ return TRUE;
+}
+
+/* EOF */
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: lib/rossym/getraw.c
+ * PURPOSE: Convert rossym info to raw external format
+ *
+ * PROGRAMMERS: Ge van Geldorp (gvg@reactos.com)
+ */
+
+#define NTOSAPI
+#include <ddk/ntddk.h>
+#include <reactos/rossym.h>
+#include "rossympriv.h"
+
+#define NDEBUG
+#include <debug.h>
+
+ULONG
+RosSymGetRawDataLength(PROSSYM_INFO RosSymInfo)
+{
+ return sizeof(ROSSYM_HEADER)
+ + RosSymInfo->SymbolsCount * sizeof(ROSSYM_ENTRY)
+ + RosSymInfo->StringsLength;
+}
+
+VOID
+RosSymGetRawData(PROSSYM_INFO RosSymInfo, PVOID RawData)
+{
+ PROSSYM_HEADER RosSymHeader;
+
+ RosSymHeader = (PROSSYM_HEADER) RawData;
+ RosSymHeader->SymbolsOffset = sizeof(ROSSYM_HEADER);
+ RosSymHeader->SymbolsLength = RosSymInfo->SymbolsCount * sizeof(ROSSYM_ENTRY);
+ RosSymHeader->StringsOffset = RosSymHeader->SymbolsOffset + RosSymHeader->SymbolsLength;
+ RosSymHeader->StringsLength = RosSymInfo->StringsLength;
+
+ memcpy((char *) RawData + RosSymHeader->SymbolsOffset, RosSymInfo->Symbols,
+ RosSymHeader->SymbolsLength);
+ memcpy((char *) RawData + RosSymHeader->StringsOffset, RosSymInfo->Strings,
+ RosSymHeader->StringsLength);
+}
+
+/* EOF */
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: lib/rossym/data.c
+ * PURPOSE: Definition of external variables
+ *
+ * PROGRAMMERS: Ge van Geldorp (gvg@reactos.com)
+ */
+
+#include <windows.h>
+#include <reactos/rossym.h>
+#include "rossympriv.h"
+
+ROSSYM_CALLBACKS RosSymCallbacks;
+
+VOID
+RosSymInit(PROSSYM_CALLBACKS Callbacks)
+{
+ RosSymCallbacks = *Callbacks;
+}
+
+/* EOF */
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: lib/rossym/initkm.c
+ * PURPOSE: Initialize library for use in kernel mode
+ *
+ * PROGRAMMERS: Ge van Geldorp (gvg@reactos.com)
+ */
+
+#define NTOSAPI
+#include <roskrnl.h>
+#include <reactos/rossym.h>
+#include "rossympriv.h"
+
+#define NDEBUG
+#include <debug.h>
+
+#define TAG_ROSSYM TAG('R', 'S', 'Y', 'M')
+
+static PVOID
+RosSymAllocMemKM(ULONG_PTR Size)
+{
+ return ExAllocatePoolWithTag(NonPagedPool, Size, TAG_ROSSYM);
+}
+
+static VOID
+RosSymFreeMemKM(PVOID Area)
+{
+ return ExFreePool(Area);
+}
+
+VOID
+RosSymInitKernelMode(VOID)
+{
+ static ROSSYM_CALLBACKS KmCallbacks =
+ {
+ RosSymAllocMemKM,
+ RosSymFreeMemKM,
+ RosSymZwReadFile,
+ RosSymZwSeekFile
+ };
+
+ RosSymInit(&KmCallbacks);
+}
+
+/* EOF */
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: lib/rossym/initum.c
+ * PURPOSE: Initialize library for use in user mode
+ *
+ * PROGRAMMERS: Ge van Geldorp (gvg@reactos.com)
+ */
+
+#include <windows.h>
+#include <reactos/rossym.h>
+#include "rossympriv.h"
+
+#define NDEBUG
+#include <debug.h>
+
+static PVOID
+RosSymAllocMemUM(ULONG_PTR Size)
+{
+ return HeapAlloc(GetProcessHeap(), 0, Size);
+}
+
+static VOID
+RosSymFreeMemUM(PVOID Area)
+{
+ HeapFree(GetProcessHeap(), 0, Area);
+}
+
+VOID
+RosSymInitUserMode(VOID)
+{
+ static ROSSYM_CALLBACKS KmCallbacks =
+ {
+ RosSymAllocMemUM,
+ RosSymFreeMemUM,
+ RosSymZwReadFile,
+ RosSymZwSeekFile
+ };
+
+ RosSymInit(&KmCallbacks);
+}
+
+/* EOF */
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: lib/rossym/rossympriv.h
+ * PURPOSE: Private header for rossym
+ *
+ * PROGRAMMERS: Ge van Geldorp (gvg@reactos.com)
+ */
+
+#ifndef ROSSYMPRIV_H_INCLUDED
+#define ROSSYMPRIV_H_INCLUDED
+
+typedef struct _ROSSYM_INFO {
+ PROSSYM_ENTRY Symbols;
+ ULONG SymbolsCount;
+ PCHAR Strings;
+ ULONG StringsLength;
+} ROSSYM_INFO;
+
+extern ROSSYM_CALLBACKS RosSymCallbacks;
+
+#define RosSymAllocMem(Size) (*RosSymCallbacks.AllocMemProc)(Size)
+#define RosSymFreeMem(Area) (*RosSymCallbacks.FreeMemProc)(Area)
+#define RosSymReadFile(FileContext, Buffer, Size) (*RosSymCallbacks.ReadFileProc)((FileContext), (Buffer), (Size))
+#define RosSymSeekFile(FileContext, Position) (*RosSymCallbacks.SeekFileProc)((FileContext), (Position))
+
+extern BOOLEAN RosSymZwReadFile(PVOID FileContext, PVOID Buffer, ULONG Size);
+extern BOOLEAN RosSymZwSeekFile(PVOID FileContext, ULONG_PTR Position);
+
+#define ROSSYM_IS_VALID_DOS_HEADER(DosHeader) (IMAGE_DOS_SIGNATURE == (DosHeader)->e_magic \
+ && 0L != (DosHeader)->e_lfanew)
+#define ROSSYM_IS_VALID_NT_HEADERS(NtHeaders) (IMAGE_NT_SIGNATURE == (NtHeaders)->Signature \
+ && IMAGE_NT_OPTIONAL_HDR_MAGIC == (NtHeaders)->OptionalHeader.Magic)
+
+
+#endif /* ROSSYMPRIV_H_INCLUDED */
+
+/* EOF */
+
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: lib/rossym/zwfile.c
+ * PURPOSE: File I/O using native functions
+ *
+ * PROGRAMMERS: Ge van Geldorp (gvg@reactos.com)
+ */
+
+#define NTOSAPI
+#include <ddk/ntddk.h>
+#include <reactos/rossym.h>
+#include "rossympriv.h"
+
+#define NDEBUG
+#include <debug.h>
+
+BOOLEAN
+RosSymZwReadFile(PVOID FileContext, PVOID Buffer, ULONG Size)
+{
+ NTSTATUS Status;
+ IO_STATUS_BLOCK IoStatusBlock;
+
+ Status = ZwReadFile(*((HANDLE *) FileContext),
+ 0, 0, 0,
+ &IoStatusBlock,
+ Buffer,
+ Size,
+ 0, 0);
+
+ return NT_SUCCESS(Status) && IoStatusBlock.Information == Size;
+}
+
+BOOLEAN
+RosSymZwSeekFile(PVOID FileContext, ULONG_PTR Position)
+{
+ NTSTATUS Status;
+ IO_STATUS_BLOCK IoStatusBlock;
+ FILE_POSITION_INFORMATION NewPosition;
+
+ NewPosition.CurrentByteOffset.u.HighPart = 0;
+ NewPosition.CurrentByteOffset.u.LowPart = Position;
+ Status = ZwSetInformationFile(*((HANDLE *) FileContext),
+ &IoStatusBlock,
+ (PVOID) &NewPosition,
+ sizeof(FILE_POSITION_INFORMATION),
+ FilePositionInformation);
+
+ return NT_SUCCESS(Status);
+}
+
+/* EOF */
OBJECTS_KDBG :=
endif
ifeq ($(DBG_OR_KDBG), 1)
-OBJECTS_KDBG := $(OBJECTS_KDBG) dbg/kdb_stabs.o dbg/kdb_symbols.o dbg/profile.o
+OBJECTS_KDBG := $(OBJECTS_KDBG) dbg/kdb_symbols.o dbg/profile.o
endif
TARGET_ASFLAGS = -I./include
$(SDK_PATH_LIB)/libstring.a \
$(SDK_PATH_LIB)/librosrtl.a \
$(SDK_PATH_LIB)/libpseh.a \
+ $(SDK_PATH_LIB)/librossym.a \
$(PATH_TO_TOP)/drivers/lib/csq/csq.o
TARGET_LFLAGS = \
typedef struct _KDB_MODULE_INFO
{
- WCHAR Name[256];
- ULONG_PTR Base;
- ULONG Size;
- PIMAGE_SYMBOL_INFO SymbolInfo;
+ WCHAR Name[256];
+ ULONG_PTR Base;
+ ULONG Size;
+ PROSSYM_INFO RosSymInfo;
} KDB_MODULE_INFO, *PKDB_MODULE_INFO;
/* from kdb_symbols.c */
KdbSymPrintAddress(IN PVOID Address);
NTSTATUS
-KdbSymGetAddressInformation(IN PIMAGE_SYMBOL_INFO SymbolInfo,
+KdbSymGetAddressInformation(IN PROSSYM_INFO RosSymInfo,
IN ULONG_PTR RelativeAddress,
OUT PULONG LineNumber OPTIONAL,
OUT PCH FileName OPTIONAL,
OUT PCH FunctionName OPTIONAL);
-BOOLEAN
-KdbpSymGetSourceAddress(IN PIMAGE_SYMBOL_INFO SymbolInfo,
- IN PCHAR FileName,
- IN ULONG LineNumber OPTIONAL,
- IN PCHAR FuncName OPTIONAL,
- OUT PVOID *Address);
-
/* other functions */
-/*NTSTATUS
-KdbSafeReadMemory(PVOID dst, PVOID src, INT size);
-NTSTATUS
-KdbSafeWriteMemory(PVOID dst, PVOID src, INT size);*/
#define KdbpSafeReadMemory(dst, src, size) MmSafeCopyFromUser(dst, src, size)
#define KdbpSafeWriteMemory(dst, src, size) MmSafeCopyToUser(dst, src, size)
CHAR
+++ /dev/null
-/* $Id:$
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/dbg/kdb_stabs.c
- * PURPOSE: Stabs functions...
- *
- * PROGRAMMERS: Gregor Anich (blight@blight.eu.org)
- */
-
-#include <ddk/ntddk.h>
-#include <roscfg.h>
-#include <internal/ntoskrnl.h>
-#include <internal/ke.h>
-#include <internal/i386/segment.h>
-#include <internal/i386/mm.h>
-#include <internal/module.h>
-#include <internal/mm.h>
-#include <internal/ps.h>
-#include <internal/trap.h>
-#include <ntdll/ldr.h>
-#include <internal/safe.h>
-#include <internal/kd.h>
-#include <rosrtl/string.h>
-
-#define NDEBUG
-#include <internal/debug.h>
-
-#include "kdb.h"
-#include "kdb_stabs.h"
-
-
-/*! \brief Find a stab entry...
- *
- * Looks through the stab for an entry which matches the specified criteria.
- *
- * \param SymbolInfo Pointer to the symbol info.
- * \param Type Type of stab entry to look for.
- * \param RelativeAddress Relative address of stab to look for.
- * \param StartEntry Starting stab entry.
- *
- * \returns Pointer to a STAB_ENTRY
- * \retval NULL No entry found.
- */
-PSTAB_ENTRY
-KdbpStabFindEntry(IN PIMAGE_SYMBOL_INFO SymbolInfo,
- IN CHAR Type,
- IN PVOID RelativeAddress OPTIONAL,
- IN PSTAB_ENTRY StartEntry OPTIONAL)
-{
- PSTAB_ENTRY StabEntry, BestStabEntry = NULL;
- PVOID StabsEnd;
- ULONG_PTR AddrFound = 0;
-
- StabEntry = SymbolInfo->StabsBase;
- StabsEnd = (PVOID)((ULONG_PTR)SymbolInfo->StabsBase + SymbolInfo->StabsLength);
- if (StartEntry != NULL)
- {
- ASSERT((ULONG_PTR)StartEntry >= (ULONG_PTR)StabEntry);
- if ((ULONG_PTR)StartEntry >= (ULONG_PTR)StabsEnd)
- return NULL;
- StabEntry = StartEntry;
- }
-
- if ( RelativeAddress != NULL )
- {
- for (; (ULONG_PTR)StabEntry < (ULONG_PTR)StabsEnd; StabEntry++)
- {
- ULONG_PTR SymbolRelativeAddress;
-
- if (StabEntry->n_type != Type)
- continue;
-
- if (RelativeAddress != NULL)
- {
- if (StabEntry->n_value >= SymbolInfo->ImageSize)
- continue;
-
- SymbolRelativeAddress = StabEntry->n_value;
- if ((SymbolRelativeAddress <= (ULONG_PTR)RelativeAddress) &&
- (SymbolRelativeAddress > AddrFound))
- {
- AddrFound = SymbolRelativeAddress;
- BestStabEntry = StabEntry;
- }
- }
- }
- }
- else
- BestStabEntry = StabEntry;
-
- if (BestStabEntry == NULL)
- {
- DPRINT("StabEntry not found!\n");
- }
- else
- {
- DPRINT("StabEntry found!\n");
- }
-
- return BestStabEntry;
-}
+++ /dev/null
-#ifndef __KDB_STABS_H__
-#define __KDB_STABS_H__
-
-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;
-
-/*
- * String - Function name with type information
- * Desc - Line number
- * Value - Absolute virtual address
- */
-#define N_FUN 0x24
-
-/*
- * Desc - Line number
- * Value - Relative virtual address
- */
-#define N_SLINE 0x44
-
-/*
- * String - First ending with a '/' is the compillation directory (CD)
- * Not ending with a '/' is a source file relative to CD
- */
-#define N_SO 0x64
-
-/*
- * String - Variable name with type information
- * Value - Register
- */
-#define N_RSYM 0x40
-
-/*
- * String - Variable name with type information
- * Value - Offset of variable within local variables (from %ebp)
- */
-#define N_LSYM 0x80
-
-#define N_SOL 0x84
-
-
-#define N_PSYM 0xa0
-
-/*
- * Value - Start address of code block
- */
-#define N_LBRAC 0xc0
-
-/*
- * Value - End address of code block
- */
-#define N_RBRAC 0xe0
-
-
-/*
- * Functions
- */
-
-PSTAB_ENTRY
-KdbpStabFindEntry(IN PIMAGE_SYMBOL_INFO SymbolInfo,
- IN CHAR Type,
- IN PVOID RelativeAddress OPTIONAL,
- IN PSTAB_ENTRY StartEntry OPTIONAL);
-
-#endif /* __KDB_STABS_H__ */
-/*
- * Parts of this file based on work Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/* $Id$
- *
+/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/dbg/kdb_symbols.c
#include <internal/safe.h>
#include <internal/kd.h>
#include <rosrtl/string.h>
-#include <coff.h>
+#include <reactos/rossym.h>
#define NDEBUG
#include <internal/debug.h>
#include "kdb.h"
-#include "kdb_stabs.h"
/* GLOBALS ******************************************************************/
-typedef struct _SYMBOLFILE_HEADER {
- ULONG StabsOffset;
- ULONG StabsLength;
- ULONG StabstrOffset;
- ULONG StabstrLength;
- ULONG SymbolsOffset;
- ULONG SymbolsLength;
- ULONG SymbolstrOffset;
- ULONG SymbolstrLength;
-} SYMBOLFILE_HEADER, *PSYMBOLFILE_HEADER;
+#define TAG_KDBS TAG('K', 'D', 'B', 'S')
typedef struct _IMAGE_SYMBOL_INFO_CACHE {
LIST_ENTRY ListEntry;
ULONG RefCount;
UNICODE_STRING FileName;
- PVOID FileBuffer;
- PVOID StabsBase;
- ULONG StabsLength;
- PVOID StabStringsBase;
- ULONG StabStringsLength;
- PVOID SymbolsBase;
- ULONG SymbolsLength;
- PVOID SymbolStringsBase;
- ULONG SymbolStringsLength;
+ PROSSYM_INFO RosSymInfo;
} IMAGE_SYMBOL_INFO_CACHE, *PIMAGE_SYMBOL_INFO_CACHE;
-
static LIST_ENTRY SymbolFileListHead;
static KSPIN_LOCK SymbolFileListLock;
pInfo->Name[Length] = L'\0';
pInfo->Base = (ULONG_PTR)current->BaseAddress;
pInfo->Size = current->SizeOfImage;
- pInfo->SymbolInfo = ¤t->SymbolInfo;
+ pInfo->RosSymInfo = current->RosSymInfo;
return TRUE;
}
current_entry = current_entry->Flink;
pInfo->Name[255] = L'\0';
pInfo->Base = (ULONG_PTR)current->Base;
pInfo->Size = current->Length;
- pInfo->SymbolInfo = ¤t->SymbolInfo;
+ pInfo->RosSymInfo = current->RosSymInfo;
return TRUE;
}
current_entry = current_entry->Flink;
return FALSE;
RelativeAddress = (ULONG_PTR) Address - Info.Base;
- Status = KdbSymGetAddressInformation(Info.SymbolInfo,
+ Status = KdbSymGetAddressInformation(Info.RosSymInfo,
RelativeAddress,
&LineNumber,
FileName,
return TRUE;
}
-/*! \brief Find a COFF symbol entry...
- *
- * Finds the COFF symbol as close as possible before the specified address
- *
- * \param SymbolInfo Pointer to the symbol info.
- * \param RelativeAddress Relative address of address to look for.
- *
- * \returns Pointer to a external_syment
- * \retval NULL No entry found.
- */
-static struct external_syment *
-KdbpSymbolsFindEntry(IN PIMAGE_SYMBOL_INFO SymbolInfo,
- IN ULONG_PTR RelativeAddress)
-{
- /*
- * Perform a binary search.
- *
- * The code below is a bit sneaky. After a comparison fails, we
- * divide the work in half by moving either left or right. If lim
- * is odd, moving left simply involves halving lim: e.g., when lim
- * is 5 we look at item 2, so we change lim to 2 so that we will
- * look at items 0 & 1. If lim is even, the same applies. If lim
- * is odd, moving right again involes halving lim, this time moving
- * the base up one item past p: e.g., when lim is 5 we change base
- * to item 3 and make lim 2 so that we will look at items 3 and 4.
- * If lim is even, however, we have to shrink it by one before
- * halving: e.g., when lim is 4, we still looked at item 2, so we
- * have to make lim 3, then halve, obtaining 1, so that we will only
- * look at item 3.
- */
- struct external_syment *Base = (struct external_syment *) SymbolInfo->SymbolsBase;
- ULONG Lim;
- struct external_syment *Mid, *Low;
-
- if (SymbolInfo->SymbolsLength < sizeof(struct external_syment)
- || RelativeAddress < Base->e_value)
- {
- return NULL;
- }
-
- Low = Base;
- for (Lim = SymbolInfo->SymbolsLength / sizeof(struct external_syment); Lim != 0; Lim >>= 1)
- {
- Mid = Base + (Lim >> 1);
- if (RelativeAddress == Mid->e_value)
- {
- return Mid;
- }
- if (Mid->e_value < RelativeAddress) /* key > mid: move right */
- {
- Low = Mid;
- Base = Mid + 1;
- Lim--;
- } /* else move left */
- }
-
- ASSERT(Low->e_value < RelativeAddress);
-
- return Low;
-}
-
/*! \brief Get information for an address (source file, line number,
* function name)
*
- * \param SymbolInfo Pointer to IMAGE_SYMBOL_INFO.
+ * \param SymbolInfo Pointer to ROSSYM_INFO.
* \param RelativeAddress Relative address to look up.
* \param LineNumber Pointer to an ULONG which is filled with the line
* number (can be NULL)
* \retval STATUS_UNSUCCESSFUL None of the requested information was found.
*/
NTSTATUS
-KdbSymGetAddressInformation(IN PIMAGE_SYMBOL_INFO SymbolInfo,
+KdbSymGetAddressInformation(IN PROSSYM_INFO RosSymInfo,
IN ULONG_PTR RelativeAddress,
OUT PULONG LineNumber OPTIONAL,
OUT PCH FileName OPTIONAL,
OUT PCH FunctionName OPTIONAL)
{
- PSTAB_ENTRY StabsFunctionEntry = NULL, FileEntry = NULL, LineEntry = NULL;
- struct external_syment *SymbolsFunctionEntry = NULL;
-
- DPRINT("RelativeAddress = 0x%08x\n", RelativeAddress);
-
- if (SymbolInfo->StabsBase == NULL || SymbolInfo->StabsLength == 0 ||
- SymbolInfo->StabStringsBase == NULL || SymbolInfo->StabStringsLength == 0)
+ if (NULL == RosSymInfo)
{
return STATUS_UNSUCCESSFUL;
}
-#ifdef PEDANTIC_STABS
- if (RelativeAddress >= SymbolInfo->ImageSize)
+ if (! RosSymGetAddressInformation(RosSymInfo, RelativeAddress, LineNumber,
+ FileName, FunctionName))
{
- DPRINT("Address is not within .text section. RelativeAddress %p Length 0x%x\n",
- RelativeAddress, SymbolInfo->ImageSize);
return STATUS_UNSUCCESSFUL;
}
-#endif
-
- ASSERT(LineNumber || FileName || FunctionName);
-
- if (LineNumber != NULL || FunctionName != NULL)
- {
- /* find stab entry for function */
- StabsFunctionEntry = KdbpStabFindEntry(SymbolInfo, N_FUN, (PVOID)RelativeAddress, NULL);
- if (StabsFunctionEntry == NULL)
- {
- DPRINT("No function stab entry found. RelativeAddress %p\n", RelativeAddress);
- }
-
- if (LineNumber != NULL && StabsFunctionEntry != NULL)
- {
- /* find stab entry for line number */
- ULONG_PTR FunctionRelativeAddress = RelativeAddress - StabsFunctionEntry->n_value;
- ULONG_PTR AddrFound = 0;
- PSTAB_ENTRY NextLineEntry;
-
- LineEntry = NextLineEntry = StabsFunctionEntry;
- while (NextLineEntry != NULL)
- {
- NextLineEntry++;
- if ((ULONG_PTR)NextLineEntry >= ((ULONG_PTR)SymbolInfo->StabsBase + SymbolInfo->StabsLength))
- break;
- if (NextLineEntry->n_type == N_FUN)
- break;
- if (NextLineEntry->n_type != N_SLINE)
- continue;
-
- if ( NextLineEntry->n_value <= FunctionRelativeAddress
- && NextLineEntry->n_value >= AddrFound )
- {
- AddrFound = NextLineEntry->n_value;
- LineEntry = NextLineEntry;
- }
- }
- }
- }
-
- if (FunctionName != NULL
- && SymbolInfo->SymbolsBase != NULL && SymbolInfo->SymbolsLength != 0
- && SymbolInfo->SymbolStringsBase != NULL && SymbolInfo->SymbolStringsLength != 0)
- {
- /* find symbol entry for function */
- SymbolsFunctionEntry = KdbpSymbolsFindEntry(SymbolInfo, RelativeAddress);
- }
-
- if (FileName != NULL)
- {
- /* find stab entry for file name */
- PCHAR p;
- INT Length;
-
- FileEntry = KdbpStabFindEntry(SymbolInfo, N_SO, (PVOID)RelativeAddress, NULL);
- if (FileEntry != NULL)
- {
- p = (PCHAR)SymbolInfo->StabStringsBase + FileEntry->n_strx;
- Length = strlen(p);
- if (p[Length - 1] == '/' || p[Length - 1] == '\\') /* source dir */
- FileEntry = KdbpStabFindEntry(SymbolInfo, N_SO, (PVOID)RelativeAddress, FileEntry + 1);
- }
- if (FileEntry == NULL)
- {
- DPRINT("No filename stab entry found. RelativeAddress %p\n", RelativeAddress);
- }
- }
-
- if (((LineNumber != NULL && LineEntry == NULL) || LineNumber == NULL) &&
- ((FileName != NULL && FileEntry == NULL) || FileName == NULL) &&
- ((FunctionName != NULL && StabsFunctionEntry == NULL && SymbolsFunctionEntry == NULL) ||
- FunctionName == NULL))
- {
- DPRINT("None of the requested information was found!\n");
- return STATUS_UNSUCCESSFUL;
- }
-
- if (LineNumber != NULL)
- {
- *LineNumber = 0;
- if (LineEntry != NULL)
- *LineNumber = LineEntry->n_desc;
- }
- if (FileName != NULL)
- {
- PCHAR Name = "";
- if (FileEntry != NULL)
- {
- Name = (PCHAR)SymbolInfo->StabStringsBase + FileEntry->n_strx;
- }
- strcpy(FileName, Name);
- }
- if (FunctionName != NULL)
- {
- PCHAR Name = "", p;
- if (StabsFunctionEntry != NULL)
- {
- if (SymbolsFunctionEntry == NULL ||
- SymbolsFunctionEntry->e_value <= StabsFunctionEntry->n_value)
- {
- Name = (PCHAR)SymbolInfo->StabStringsBase + StabsFunctionEntry->n_strx;
- strcpy(FunctionName, Name);
- if ((p = strchr(FunctionName, ':')) != NULL) /* remove extra info from function name */
- {
- *p = '\0';
- }
- }
- else if (SymbolsFunctionEntry != NULL)
- {
- if (SymbolsFunctionEntry->e.e.e_zeroes == 0)
- {
- Name = (PCHAR) SymbolInfo->SymbolStringsBase + SymbolsFunctionEntry->e.e.e_offset;
- strcpy(FunctionName, Name);
- }
- else
- {
- memcpy(FunctionName, SymbolsFunctionEntry->e.e_name, E_SYMNMLEN);
- FunctionName[E_SYMNMLEN] = '\0';
- }
- }
- }
- else if (SymbolsFunctionEntry != NULL)
- {
- if (SymbolsFunctionEntry->e.e.e_zeroes == 0)
- {
- Name = (PCHAR) SymbolInfo->SymbolStringsBase + SymbolsFunctionEntry->e.e.e_offset;
- strcpy(FunctionName, Name);
- }
- else
- {
- memcpy(FunctionName, SymbolsFunctionEntry->e.e_name, E_SYMNMLEN);
- FunctionName[E_SYMNMLEN] = '\0';
- }
- }
- else
- {
- FunctionName[0] = '\0';
- }
- }
return STATUS_SUCCESS;
}
-
-/*! \brief Get absolute source-line number or function address
- *
- * \param SymbolInfo IMAGE_SYMBOL_INFO of the module containing source file/line number.
- * \param FileName Source filename.
- * \param LineNumber Line number in source file.
- * \param FuncName Function name.
- * \param Address Filled with the address on success.
- *
- * \retval TRUE Success.
- * \retval FALSE Failure.
- */
-BOOLEAN
-KdbpSymGetSourceAddress(IN PIMAGE_SYMBOL_INFO SymbolInfo,
- IN PCHAR FileName,
- IN ULONG LineNumber OPTIONAL,
- IN PCHAR FuncName OPTIONAL,
- OUT PVOID *Address)
-{
- PSTAB_ENTRY Entry, FunctionEntry = NULL;
- PCHAR SymbolName, p;
- CHAR Buffer[512] = "";
- INT Length, FileNameLength, FuncNameLength = 0;
-
- if (FuncName == NULL && LineNumber < 1)
- return FALSE;
-
- FileNameLength = strlen(FileName);
- FuncNameLength = strlen(FuncName);
- for (Entry = SymbolInfo->StabsBase;
- (ULONG_PTR)Entry < (ULONG_PTR)(SymbolInfo->StabsBase + SymbolInfo->StabsLength);
- Entry++)
- {
- if (Entry->n_type != N_SO)
- continue;
-
- SymbolName = (PCHAR)SymbolInfo->StabStringsBase + Entry->n_strx;
- Length = strlen(SymbolName);
- if (SymbolName[Length - 1] == '/' ||
- SymbolName[Length - 1] == '\\')
- {
- strncpy(Buffer, SymbolName, sizeof (Buffer) - 1);
- Buffer[sizeof (Buffer) - 1] = '\0';
- continue;
- }
- strncat(Buffer, SymbolName, sizeof (Buffer) - 1);
- Buffer[sizeof (Buffer) - 1] = '\0';
-
- Length = strlen(Buffer);
- if (strcmp(Buffer + Length - FileNameLength, FileName) != 0)
- continue;
-
- Entry++;
- for (;(ULONG_PTR)Entry < (ULONG_PTR)(SymbolInfo->StabsBase + SymbolInfo->StabsLength);
- Entry++)
- {
- if (Entry->n_type == N_FUN)
- FunctionEntry = Entry;
- else if (Entry->n_type == N_SO)
- break;
- else if (Entry->n_type != N_SLINE || LineNumber < 1)
- continue;
-
- if (LineNumber > 0 && Entry->n_desc != LineNumber)
- continue;
- else /* if (FunctionName != NULL) */
- {
- SymbolName = (PCHAR)SymbolInfo->StabStringsBase + Entry->n_strx;
- p = strchr(SymbolName, ':');
- if (p == NULL)
- return FALSE;
- Length = p - SymbolName;
- if (Length != FuncNameLength)
- continue;
- if (strncmp(FuncName, SymbolName, Length) != 0)
- continue;
- }
-
- /* found */
- if (Entry->n_type == N_FUN)
- {
- *Address = (PVOID)Entry->n_value; /* FIXME: relocate address */
- return TRUE;
- }
-
- if (FunctionEntry == NULL)
- return FALSE;
-
- *Address = (PVOID)((ULONG_PTR)Entry->n_value + FunctionEntry->n_value); /* FIXME: relocate address */
- return TRUE;
- }
- break;
- }
-
- return FALSE;
-}
-
/*! \brief Find cached symbol file.
*
* Looks through the list of cached symbol files and tries to find an already
*
* \sa KdbpSymAddCachedFile
*/
-STATIC PIMAGE_SYMBOL_INFO_CACHE
+STATIC PROSSYM_INFO
KdbpSymFindCachedFile(IN PUNICODE_STRING FileName)
{
PIMAGE_SYMBOL_INFO_CACHE Current;
Current->RefCount++;
KeReleaseSpinLock(&SymbolFileListLock, Irql);
DPRINT("Found cached file!\n");
- return Current;
+ return Current->RosSymInfo;
}
CurrentEntry = CurrentEntry->Flink;
/*! \brief Add a symbol file to the cache.
*
* \param FileName Filename of the symbol file.
- * \param SymbolInfo Pointer to the symbol info.
+ * \param RosSymInfo Pointer to the symbol info.
*
* \sa KdbpSymRemoveCachedFile
*/
STATIC VOID
KdbpSymAddCachedFile(IN PUNICODE_STRING FileName,
- IN PIMAGE_SYMBOL_INFO SymbolInfo)
+ IN PROSSYM_INFO RosSymInfo)
{
PIMAGE_SYMBOL_INFO_CACHE CacheEntry;
- DPRINT("Adding symbol file: FileBuffer = %p, ImageBase = %p\n",
- SymbolInfo->FileBuffer, SymbolInfo->ImageBase);
+ DPRINT("Adding symbol file: RosSymInfo = %p\n", RosSymInfo);
/* allocate entry */
- CacheEntry = ExAllocatePool(NonPagedPool, sizeof (IMAGE_SYMBOL_INFO_CACHE));
+ CacheEntry = ExAllocatePoolWithTag(NonPagedPool, sizeof (IMAGE_SYMBOL_INFO_CACHE), TAG_KDBS);
ASSERT(CacheEntry);
RtlZeroMemory(CacheEntry, sizeof (IMAGE_SYMBOL_INFO_CACHE));
/* fill entry */
- RtlpCreateUnicodeString(&CacheEntry->FileName, FileName->Buffer, NonPagedPool);
+ RtlpCreateUnicodeString(&CacheEntry->FileName, FileName->Buffer, PagedPool);
ASSERT(CacheEntry->FileName.Buffer);
CacheEntry->RefCount = 1;
- CacheEntry->FileBuffer = SymbolInfo->FileBuffer;
- CacheEntry->StabsBase = SymbolInfo->StabsBase;
- CacheEntry->StabsLength = SymbolInfo->StabsLength;
- CacheEntry->StabStringsBase = SymbolInfo->StabStringsBase;
- CacheEntry->StabStringsLength = SymbolInfo->StabStringsLength;
- CacheEntry->SymbolsBase = SymbolInfo->SymbolsBase;
- CacheEntry->SymbolsLength = SymbolInfo->SymbolsLength;
- CacheEntry->SymbolStringsBase = SymbolInfo->SymbolStringsBase;
- CacheEntry->SymbolStringsLength = SymbolInfo->SymbolStringsLength;
+ CacheEntry->RosSymInfo = RosSymInfo;
InsertTailList(&SymbolFileListHead, &CacheEntry->ListEntry); /* FIXME: Lock list? */
}
* it's reference count. If the refcount is 0 after decreasing it the cache
* entry will be removed from the list and freed.
*
- * \param SymbolInfo Pointer to the symbol info.
+ * \param RosSymInfo Pointer to the symbol info.
*
* \sa KdbpSymAddCachedFile
*/
STATIC VOID
-KdbpSymRemoveCachedFile(IN PIMAGE_SYMBOL_INFO SymbolInfo)
+KdbpSymRemoveCachedFile(IN PROSSYM_INFO RosSymInfo)
{
PIMAGE_SYMBOL_INFO_CACHE Current;
PLIST_ENTRY CurrentEntry;
{
Current = CONTAINING_RECORD(CurrentEntry, IMAGE_SYMBOL_INFO_CACHE, ListEntry);
- if (Current->FileBuffer == SymbolInfo->FileBuffer) /* found */
+ if (Current->RosSymInfo == RosSymInfo) /* found */
{
ASSERT(Current->RefCount > 0);
Current->RefCount--;
if (Current->RefCount < 1)
{
RemoveEntryList(&Current->ListEntry);
- ExFreePool(Current->FileBuffer);
+ RosSymDelete(Current->RosSymInfo);
ExFreePool(Current);
}
KeReleaseSpinLock(&SymbolFileListLock, Irql);
}
KeReleaseSpinLock(&SymbolFileListLock, Irql);
- DPRINT1("Warning: Removing unknown symbol file: FileBuffer = %p, ImageBase = %p\n",
- SymbolInfo->FileBuffer, SymbolInfo->ImageBase);
+ DPRINT1("Warning: Removing unknown symbol file: RosSymInfo = %p\n", RosSymInfo);
}
/*! \brief Loads a symbol file.
*
* \param FileName Filename of the symbol file to load.
- * \param SymbolInfo Pointer to a SymbolInfo which gets filled.
+ * \param RosSymInfo Pointer to a ROSSYM_INFO which gets filled.
*
* \sa KdbpSymUnloadModuleSymbols
*/
STATIC VOID
KdbpSymLoadModuleSymbols(IN PUNICODE_STRING FileName,
- OUT PIMAGE_SYMBOL_INFO SymbolInfo)
+ OUT PROSSYM_INFO *RosSymInfo)
{
- FILE_STANDARD_INFORMATION FileStdInfo;
OBJECT_ATTRIBUTES ObjectAttributes;
- WCHAR TmpFileName[MAX_PATH];
- UNICODE_STRING SymFileName;
- LPWSTR Start, Ext;
HANDLE FileHandle;
- PVOID FileBuffer;
NTSTATUS Status;
- ULONG Length;
IO_STATUS_BLOCK IoStatusBlock;
- PSYMBOLFILE_HEADER SymbolFileHeader;
- PIMAGE_SYMBOL_INFO_CACHE CachedSymbolFile;
#ifdef KDBG
/* Allow KDB to break on module load */
KdbModuleLoaded(FileName);
#endif
- /* Get the path to the symbol store */
- wcscpy(TmpFileName, L"\\SystemRoot\\symbols\\");
-
- /* Get the symbol filename from the module name */
- Start = wcsrchr(FileName->Buffer, L'\\');
- if (Start == NULL)
- Start = FileName->Buffer;
- else
- Start++;
-
- Ext = wcsrchr(FileName->Buffer, L'.');
- if (Ext != NULL)
- Length = Ext - Start;
- else
- Length = wcslen(Start);
-
- wcsncat(TmpFileName, Start, Length);
- wcscat(TmpFileName, L".sym");
- RtlInitUnicodeString(&SymFileName, TmpFileName);
-
/* Try to find cached (already loaded) symbol file */
- CachedSymbolFile = KdbpSymFindCachedFile(&SymFileName);
- if (CachedSymbolFile != NULL)
+ *RosSymInfo = KdbpSymFindCachedFile(FileName);
+ if (*RosSymInfo != NULL)
{
- DPRINT("Found cached symbol file %wZ\n", &SymFileName);
- SymbolInfo->FileBuffer = CachedSymbolFile->FileBuffer;
- SymbolInfo->StabsBase = CachedSymbolFile->StabsBase;
- SymbolInfo->StabsLength = CachedSymbolFile->StabsLength;
- SymbolInfo->StabStringsBase = CachedSymbolFile->StabStringsBase;
- SymbolInfo->StabStringsLength = CachedSymbolFile->StabStringsLength;
- SymbolInfo->SymbolsBase = CachedSymbolFile->SymbolsBase;
- SymbolInfo->SymbolsLength = CachedSymbolFile->SymbolsLength;
- SymbolInfo->SymbolStringsBase = CachedSymbolFile->SymbolStringsBase;
- SymbolInfo->SymbolStringsLength = CachedSymbolFile->SymbolStringsLength;
+ DPRINT("Found cached symbol file %wZ\n", FileName);
return;
}
/* Open the file */
InitializeObjectAttributes(&ObjectAttributes,
- &SymFileName,
+ FileName,
0,
NULL,
NULL);
- DPRINT("Attempting to open symbols: %wZ\n", &SymFileName);
+ DPRINT("Attempting to open image: %wZ\n", FileName);
Status = ZwOpenFile(&FileHandle,
FILE_ALL_ACCESS,
FILE_SYNCHRONOUS_IO_NONALERT|FILE_NO_INTERMEDIATE_BUFFERING);
if (!NT_SUCCESS(Status))
{
- DPRINT("Could not open symbol file: %wZ\n", &SymFileName);
- return;
- }
-
- DPRINT("Loading symbols from %wZ...\n", &SymFileName);
-
- /* Get the size of the file */
- Status = ZwQueryInformationFile(FileHandle,
- &IoStatusBlock,
- &FileStdInfo,
- sizeof(FileStdInfo),
- FileStandardInformation);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("Could not get file size\n");
- ZwClose(FileHandle);
+ DPRINT("Could not open image file: %wZ\n", &FileName);
return;
}
- DPRINT("Symbol file is %08x bytes\n", FileStdInfo.EndOfFile.u.LowPart);
-
- /* Allocate nonpageable memory for symbol file */
- FileBuffer = ExAllocatePool(NonPagedPool,
- FileStdInfo.AllocationSize.u.LowPart);
+ DPRINT("Loading symbols from %wZ...\n", FileName);
- if (FileBuffer == NULL)
+ if (! RosSymCreateFromFile(&FileHandle, RosSymInfo))
{
- DPRINT("Could not allocate memory for symbol file\n");
- ZwClose(FileHandle);
- return;
- }
-
- /* Load file into memory chunk */
- Status = ZwReadFile(FileHandle,
- 0, 0, 0,
- &IoStatusBlock,
- FileBuffer,
- FileStdInfo.EndOfFile.u.LowPart,
- 0, 0);
- if (!NT_SUCCESS(Status) && Status != STATUS_END_OF_FILE)
- {
- DPRINT("Could not read symbol file into memory (Status 0x%x)\n", Status);
- ExFreePool(FileBuffer);
- ZwClose(FileHandle);
+ DPRINT("Failed to load symbols from %wZ\n", FileName);
return;
}
DPRINT("Symbols loaded.\n");
- SymbolFileHeader = (PSYMBOLFILE_HEADER) FileBuffer;
- SymbolInfo->FileBuffer = FileBuffer;
- SymbolInfo->StabsBase = FileBuffer + SymbolFileHeader->StabsOffset;
- SymbolInfo->StabsLength = SymbolFileHeader->StabsLength;
- SymbolInfo->StabStringsBase = FileBuffer + SymbolFileHeader->StabstrOffset;
- SymbolInfo->StabStringsLength = SymbolFileHeader->StabstrLength;
- SymbolInfo->SymbolsBase = FileBuffer + SymbolFileHeader->SymbolsOffset;
- SymbolInfo->SymbolsLength = SymbolFileHeader->SymbolsLength;
- SymbolInfo->SymbolStringsBase = FileBuffer + SymbolFileHeader->SymbolstrOffset;
- SymbolInfo->SymbolStringsLength = SymbolFileHeader->SymbolstrLength;
-
/* add file to cache */
- KdbpSymAddCachedFile(&SymFileName, SymbolInfo);
-
- DPRINT("Installed stabs: %wZ (%08x-%08x,%08x) (%08x-%08x,%08x)\n",
- FileName,
- SymbolInfo->StabsBase,
- SymbolInfo->StabsLength + SymbolInfo->StabsBase,
- SymbolInfo->StabStringsBase,
- SymbolInfo->SymbolsBase,
- SymbolInfo->SymbolsLength + SymbolInfo->SymbolsBase,
- SymbolInfo->SymbolStringsBase);
+ KdbpSymAddCachedFile(FileName, *RosSymInfo);
+
+ DPRINT("Installed symbols: %wZ %p\n", FileName, *RosSymInfo);
}
/*! \brief Unloads symbol info.
*
- * \param SymbolInfo Pointer to the symbol info to unload.
+ * \param RosSymInfo Pointer to the symbol info to unload.
*
* \sa KdbpSymLoadModuleSymbols
*/
STATIC VOID
-KdbpSymUnloadModuleSymbols(IN PIMAGE_SYMBOL_INFO SymbolInfo)
+KdbpSymUnloadModuleSymbols(IN PROSSYM_INFO RosSymInfo)
{
DPRINT("Unloading symbols\n");
- if (SymbolInfo != NULL && SymbolInfo->FileBuffer != NULL &&
- (PVOID)SymbolInfo->ImageBase != NULL)
+ if (RosSymInfo != NULL)
{
- KdbpSymRemoveCachedFile(SymbolInfo);
- SymbolInfo->FileBuffer = NULL;
- SymbolInfo->StabsBase = NULL;
- SymbolInfo->StabsLength = 0;
- SymbolInfo->SymbolsBase = NULL;
- SymbolInfo->SymbolsLength = 0;
+ KdbpSymRemoveCachedFile(RosSymInfo);
}
}
VOID
KdbSymLoadUserModuleSymbols(IN PLDR_MODULE LdrModule)
{
+ static WCHAR Prefix[] = L"\\??\\";
+ UNICODE_STRING KernelName;
DPRINT("LdrModule %p\n", LdrModule);
- RtlZeroMemory(&LdrModule->SymbolInfo, sizeof (LdrModule->SymbolInfo));
- LdrModule->SymbolInfo.ImageBase = (ULONG_PTR)LdrModule->BaseAddress;
- LdrModule->SymbolInfo.ImageSize = LdrModule->SizeOfImage;
+ KernelName.MaximumLength = sizeof(Prefix) + LdrModule->FullDllName.Length;
+ KernelName.Length = KernelName.MaximumLength - sizeof(WCHAR);
+ KernelName.Buffer = ExAllocatePoolWithTag(PagedPool, KernelName.MaximumLength, TAG_KDBS);
+ if (NULL == KernelName.Buffer)
+ {
+ return;
+ }
+ memcpy(KernelName.Buffer, Prefix, sizeof(Prefix) - sizeof(WCHAR));
+ memcpy(KernelName.Buffer + sizeof(Prefix) / sizeof(WCHAR) - 1, LdrModule->FullDllName.Buffer,
+ LdrModule->FullDllName.Length);
+ KernelName.Buffer[KernelName.Length / sizeof(WCHAR)] = L'\0';
+
+ LdrModule->RosSymInfo = NULL;
- KdbpSymLoadModuleSymbols(&LdrModule->FullDllName, &LdrModule->SymbolInfo);
+ KdbpSymLoadModuleSymbols(&KernelName, &LdrModule->RosSymInfo);
+
+ ExFreePool(KernelName.Buffer);
}
/*! \brief Frees all symbols loaded for a process.
{
PLIST_ENTRY CurrentEntry;
PLDR_MODULE Current;
- PIMAGE_SYMBOL_INFO SymbolInfo;
PEPROCESS CurrentProcess;
PPEB Peb;
{
Current = CONTAINING_RECORD(CurrentEntry, LDR_MODULE, InLoadOrderModuleList);
- SymbolInfo = &Current->SymbolInfo;
- KdbpSymUnloadModuleSymbols(SymbolInfo);
+ KdbpSymUnloadModuleSymbols(Current->RosSymInfo);
CurrentEntry = CurrentEntry->Flink;
}
/* Load symbols for the image if available */
DPRINT("Loading driver %wZ symbols (driver @ %08x)\n", Filename, Module->Base);
- RtlZeroMemory(&Module->TextSection->SymbolInfo, sizeof (Module->TextSection->SymbolInfo));
- Module->TextSection->SymbolInfo.ImageBase = Module->TextSection->Base;
- Module->TextSection->SymbolInfo.ImageSize = Module->TextSection->Length;
+ Module->TextSection->RosSymInfo = NULL;
- KdbpSymLoadModuleSymbols(Filename, &Module->TextSection->SymbolInfo);
+ KdbpSymLoadModuleSymbols(Filename, &Module->TextSection->RosSymInfo);
}
/*! \brief Unloads symbol info for a driver.
KdbSymUnloadDriverSymbols(IN PMODULE_OBJECT ModuleObject)
{
/* Unload symbols for module if available */
- KdbpSymUnloadModuleSymbols(&ModuleObject->TextSection->SymbolInfo);
+ KdbpSymUnloadModuleSymbols(ModuleObject->TextSection->RosSymInfo);
+ ModuleObject->TextSection->RosSymInfo = NULL;
}
/*! \brief Called when a symbol file is loaded by the loader?
PMODULE_OBJECT ModuleObject;
UNICODE_STRING UnicodeString;
PLOADER_MODULE KeLoaderModules = (PLOADER_MODULE)KeLoaderBlock.ModsAddr;
- CHAR SymbolName[MAX_PATH];
- PSYMBOLFILE_HEADER SymbolFileHeader;
- PIMAGE_SYMBOL_INFO SymbolInfo;
ANSI_STRING AnsiString;
- PCHAR Extension;
ULONG i;
+ BOOLEAN IsRaw;
DPRINT("KdbSymProcessBootSymbols(%s)\n", FileName);
- RtlInitAnsiString(&AnsiString, FileName);
+ if (0 == _stricmp(FileName, "ntoskrnl.sym"))
+ {
+ RtlInitAnsiString(&AnsiString, "ntoskrnl.exe");
+ IsRaw = TRUE;
+ }
+ else
+ {
+ RtlInitAnsiString(&AnsiString, FileName);
+ IsRaw = FALSE;
+ }
RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, TRUE);
ModuleObject = LdrGetModuleObject(&UnicodeString);
RtlFreeUnicodeString(&UnicodeString);
if (ModuleObject != NULL)
{
- strcpy(SymbolName, FileName);
- Extension = strrchr(SymbolName, '.');
- if (Extension == NULL)
- {
- Extension = SymbolName + strlen(SymbolName);
- }
- strcpy(Extension, ".sym");
for (i = 0; i < KeLoaderBlock.ModsCount; i++)
{
- if (KeLoaderModules[i].Reserved == 0 && !_stricmp(SymbolName, (PCHAR)KeLoaderModules[i].String))
+ if (0 == _stricmp(FileName, (PCHAR)KeLoaderModules[i].String))
{
break;
}
if (i < KeLoaderBlock.ModsCount)
{
KeLoaderModules[i].Reserved = 1;
- SymbolInfo = (PIMAGE_SYMBOL_INFO) &ModuleObject->TextSection->SymbolInfo;
- if (SymbolInfo->FileBuffer != NULL)
+ if (ModuleObject->TextSection->RosSymInfo != NULL)
{
- KdbpSymRemoveCachedFile(SymbolInfo);
+ KdbpSymRemoveCachedFile(ModuleObject->TextSection->RosSymInfo);
}
- SymbolFileHeader = ExAllocatePool(NonPagedPool, KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart);
- if (SymbolFileHeader == NULL)
+ if (IsRaw)
{
- DPRINT("Could not allocate memory for symbol file\n");
- return;
+ if (! RosSymCreateFromRaw((PVOID) KeLoaderModules[i].ModStart,
+ KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart,
+ &ModuleObject->TextSection->RosSymInfo))
+ {
+ return;
+ }
+ }
+ else
+ {
+ if (! RosSymCreateFromMem((PVOID) KeLoaderModules[i].ModStart,
+ KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart,
+ &ModuleObject->TextSection->RosSymInfo))
+ {
+ return;
+ }
}
- memcpy(SymbolFileHeader,
- (PVOID)KeLoaderModules[i].ModStart,
- KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart);
-
- SymbolInfo->FileBuffer = SymbolFileHeader;
- SymbolInfo->StabsBase = (PVOID)SymbolFileHeader + SymbolFileHeader->StabsOffset;
- SymbolInfo->StabsLength = SymbolFileHeader->StabsLength;
- SymbolInfo->StabStringsBase = (PVOID)SymbolFileHeader + SymbolFileHeader->StabstrOffset;
- SymbolInfo->StabStringsLength = SymbolFileHeader->StabstrLength;
- SymbolInfo->SymbolsBase = (PVOID)SymbolFileHeader + SymbolFileHeader->SymbolsOffset;
- SymbolInfo->SymbolsLength = SymbolFileHeader->SymbolsLength;
- SymbolInfo->SymbolStringsBase = (PVOID)SymbolFileHeader + SymbolFileHeader->SymbolstrOffset;
- SymbolInfo->SymbolStringsLength = SymbolFileHeader->SymbolstrLength;
/* add file to cache */
- RtlInitAnsiString(&AnsiString, SymbolName);
+ RtlInitAnsiString(&AnsiString, FileName);
RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, TRUE);
- KdbpSymAddCachedFile(&UnicodeString, SymbolInfo);
+ KdbpSymAddCachedFile(&UnicodeString, ModuleObject->TextSection->RosSymInfo);
RtlFreeUnicodeString(&UnicodeString);
- DPRINT("Installed stabs: %s@%08x-%08x (%08x-%08x,%08x) (%08x-%08x,%08x)\n",
+ DPRINT("Installed symbols: %s@%08x-%08x %p\n",
FileName,
ModuleObject->Base,
ModuleObject->Length + ModuleObject->Base,
- SymbolInfo->StabsBase,
- SymbolInfo->StabsLength + SymbolInfo->StabsBase,
- SymbolInfo->StabStringsBase,
- SymbolInfo->SymbolsBase,
- SymbolInfo->SymbolsLength + SymbolInfo->SymbolsBase,
- SymbolInfo->SymbolStringsBase);
+ ModuleObject->TextSection->RosSymInfo);
}
}
}
KdbSymInit(IN PMODULE_TEXT_SECTION NtoskrnlTextSection,
IN PMODULE_TEXT_SECTION LdrHalTextSection)
{
- RtlZeroMemory(&NtoskrnlTextSection->SymbolInfo, sizeof(NtoskrnlTextSection->SymbolInfo));
- NtoskrnlTextSection->SymbolInfo.ImageBase = NtoskrnlTextSection->OptionalHeader->ImageBase;
- NtoskrnlTextSection->SymbolInfo.ImageSize = NtoskrnlTextSection->Length;
-
- RtlZeroMemory(&LdrHalTextSection->SymbolInfo, sizeof(LdrHalTextSection->SymbolInfo));
- LdrHalTextSection->SymbolInfo.ImageBase = LdrHalTextSection->OptionalHeader->ImageBase;
- LdrHalTextSection->SymbolInfo.ImageSize = LdrHalTextSection->Length;
+ NtoskrnlTextSection->RosSymInfo = NULL;
+ LdrHalTextSection->RosSymInfo = NULL;
InitializeListHead(&SymbolFileListHead);
KeInitializeSpinLock(&SymbolFileListLock);
+
+ RosSymInitKernelMode();
}
/* EOF */
-/* $Id:$
+/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
extern LIST_ENTRY ModuleTextListHead;
ULONG_PTR RelativeAddress;
NTSTATUS Status;
- ULONG LineNumber;
CHAR FileName[256];
CHAR FunctionName[256];
address < (PVOID)(current->Base + current->Length))
{
RelativeAddress = (ULONG_PTR) address - current->Base;
- Status = KdbSymGetAddressInformation(¤t->SymbolInfo,
+ Status = KdbSymGetAddressInformation(current->RosSymInfo,
RelativeAddress,
- &LineNumber,
+ NULL,
FileName,
FunctionName);
if (NT_SUCCESS(Status))
{
- sprintf(NameBuffer, "%s (%s)", FileName, FunctionName);
+ sprintf(NameBuffer, "%s (%s)", FunctionName, FileName);
return(TRUE);
}
return(TRUE);
PLIST_ENTRY Largest;
KdbProfilerWriteString("\r\n\r\n");
- KdbProfilerWriteString("Count Symbol\n");
+ KdbProfilerWriteString("Count Symbol\r\n");
KdbProfilerWriteString("--------------------------------------------------\r\n");
current = SamplesListHead->Flink;
ULONG Index;
ULONG_PTR Address;
- if (!ExInitializeHashTable(&Hashtable, 17, KdbProfilerKeyCompare, TRUE))
+ if (!ExInitializeHashTable(&Hashtable, 12, KdbProfilerKeyCompare, TRUE))
{
DPRINT1("ExInitializeHashTable() failed.");
KEBUGCHECK(0);
KeWaitForSingleObject(&KdbProfilerLock, Executive, KernelMode, FALSE, NULL);
- KdbSuspendProfiling();
+ KdbSuspendProfiling();
KdbProfilerAnalyzeSamples();
- KdbResumeProfiling();
+ KdbResumeProfiling();
- KeReleaseMutex(&KdbProfilerLock, FALSE);
- }
+ KeReleaseMutex(&KdbProfilerLock, FALSE);
+ }
}
VOID
DPRINT1("Failed to create profiler log file\n");
return;
}
+ KeInitializeMutex(&KdbProfilerLock, 0);
+
+ KdbProfileDatabase = ExAllocatePool(NonPagedPool, sizeof(PROFILE_DATABASE));
+ ASSERT(KdbProfileDatabase);
+ InitializeListHead(&KdbProfileDatabase->ListHead);
+ KeInitializeDpc(&KdbProfilerCollectorDpc, KdbProfilerCollectorDpcRoutine, NULL);
+
+ /* Initialize our periodic timer and its associated DPC object. When the timer
+ expires, the KdbProfilerSessionEndDpc deferred procedure call (DPC) is queued */
+ KeInitializeTimerEx(&KdbProfilerTimer, SynchronizationTimer);
Status = PsCreateSystemThread(&KdbProfilerThreadHandle,
THREAD_ALL_ACCESS,
return;
}
- KeInitializeMutex(&KdbProfilerLock, 0);
-
- KdbProfileDatabase = ExAllocatePool(NonPagedPool, sizeof(PROFILE_DATABASE));
- ASSERT(KdbProfileDatabase);
- InitializeListHead(&KdbProfileDatabase->ListHead);
- KeInitializeDpc(&KdbProfilerCollectorDpc, KdbProfilerCollectorDpcRoutine, NULL);
-
- /* Initialize our periodic timer and its associated DPC object. When the timer
- expires, the KdbProfilerSessionEndDpc deferred procedure call (DPC) is queued */
- KeInitializeTimerEx(&KdbProfilerTimer, SynchronizationTimer);
-
/* Start the periodic timer with an initial and periodic
relative expiration time of PROFILE_SESSION_LENGTH seconds */
DueTime.QuadPart = -(LONGLONG) PROFILE_SESSION_LENGTH * 1000 * 10000;
#include <ddk/ntddk.h>
#include <roscfg.h>
#include <pe.h>
-#include <ntos/kdbgsyms.h>
+#include <reactos/rossym.h>
typedef struct _MODULE_TEXT_SECTION
{
PWCH Name;
PIMAGE_OPTIONAL_HEADER OptionalHeader;
#if defined(DBG) || defined(KDBG)
- IMAGE_SYMBOL_INFO SymbolInfo;
+ PROSSYM_INFO RosSymInfo;
#endif /* KDBG */
} MODULE_TEXT_SECTION, *PMODULE_TEXT_SECTION;
if (Extension == NULL)
Extension = "";
- if (!_stricmp(Extension, ".exe") || !_stricmp(Extension, ".dll"))
+ if (!_stricmp(Extension, ".sym") || !_stricmp(Extension, ".dll"))
{
/* Process symbols for *.exe and *.dll */
KDB_SYMBOLFILE_HOOK(ModuleName);
TARGET_ASFLAGS += -g
TARGET_CFLAGS += -g
TARGET_LFLAGS += -g
- ifeq ($(INSTALL_SYMBOLS),)
- INSTALL_SYMBOLS := yes
- endif
endif
TARGET_CPPFLAGS += $(MK_CPPFLAGS) $(STD_CPPFLAGS)
-o $(MK_NOSTRIPNAME) \
$(MK_FULLRES) $(MK_OBJECTS) $(MK_LIBS) $(MK_GCCLIBS)
- $(RM) temp.exp
-ifeq ($(BUILD_SYM),yes)
- $(HALFVERBOSEECHO) [RSYM] $(MK_BASENAME).sym
- - $(RSYM) $(MK_NOSTRIPNAME) $(MK_BASENAME).sym
-endif
ifeq ($(BUILD_MAP),full)
$(HALFVERBOSEECHO) [OBJDUMP] $(MK_BASENAME).map
$(OBJDUMP) -d -S $(MK_NOSTRIPNAME) > $(MK_BASENAME).map
endif
$(MK_FULLNAME): $(MK_NOSTRIPNAME) $(MK_EXTRADEP)
- $(HALFVERBOSEECHO) [LD] $(MK_FULLNAME)
- -
-ifneq ($(TARGET_CPPAPP),yes)
- $(LD) --strip-debug -r -o $(MK_STRIPPED_OBJECT) $(MK_OBJECTS)
-endif
-ifeq ($(MK_EXETYPE),dll)
- $(LD_CC) -Wl,--base-file,base.tmp \
- -Wl,--entry,$(TARGET_ENTRY) \
- -Wl,--strip-debug \
- $(TARGET_LFLAGS) \
- -o junk.tmp \
- $(MK_FULLRES) $(MK_STRIPPED_OBJECT) $(MK_LIBS) $(MK_GCCLIBS)
- - $(RM) junk.tmp
- $(DLLTOOL) --dllname $(MK_FULLNAME) \
- --base-file base.tmp \
- --output-exp temp.exp $(MK_EXTRACMD)
- - $(RM) base.tmp
- $(LD_CC) -Wl,--base-file,base.tmp \
- -Wl,--entry,$(TARGET_ENTRY) \
- -Wl,--strip-debug \
- $(TARGET_LFLAGS) \
- temp.exp \
- -o junk.tmp \
- $(MK_FULLRES) $(MK_STRIPPED_OBJECT) $(MK_LIBS) $(MK_GCCLIBS)
- - $(RM) junk.tmp
- $(DLLTOOL) --dllname $(MK_FULLNAME) \
- --base-file base.tmp \
- --output-exp temp.exp $(MK_KILLAT) $(MK_EXTRACMD)
- - $(RM) base.tmp
-endif
- $(LD_CC) $(TARGET_LFLAGS) \
- -Wl,--entry,$(TARGET_ENTRY) \
- -Wl,--strip-debug \
- $(MK_EXTRACMD2) \
- -o $(MK_FULLNAME) \
- $(MK_FULLRES) $(MK_STRIPPED_OBJECT) $(MK_LIBS) $(MK_GCCLIBS)
-ifneq ($(TARGET_CPPAPP),yes)
- - $(RM) temp.exp $(MK_STRIPPED_OBJECT)
-else
- - $(RM) temp.exp
-endif
+ $(HALFVERBOSEECHO) [RSYM] $(MK_FULLNAME)
+ $(RSYM) $(MK_NOSTRIPNAME) $(MK_FULLNAME)
@echo $(MK_FULLNAME) was successfully built.
endif # KM_MODE
-o $(MK_NOSTRIPNAME) \
$(MK_FULLRES) $(MK_OBJECTS) $(MK_LIBS) $(MK_GCCLIBS)
- $(RM) temp.exp
-ifeq ($(BUILD_SYM),yes)
- $(HALFVERBOSEECHO) [RSYM] $(MK_BASENAME).sym
- $(RSYM) $(MK_NOSTRIPNAME) $(MK_BASENAME).sym
-endif
ifeq ($(BUILD_MAP),full)
$(HALFVERBOSEECHO) [OBJDUMP] $(MK_BASENAME).map
$(OBJDUMP) -d -S $(MK_NOSTRIPNAME) > $(MK_BASENAME).map
endif
endif
-$(MK_FULLNAME): $(MK_EXTRADEP) $(MK_FULLRES) $(MK_BASENAME).a $(MK_LIBS) $(MK_NOSTRIPNAME)
- -
- $(HALFVERBOSEECHO) [LD] $(MK_FULLNAME)
-ifneq ($(TARGET_CPPAPP),yes)
- $(LD) --strip-debug -r -o $(MK_STRIPPED_OBJECT) $(MK_OBJECTS)
-endif
- $(LD_CC) -Wl,--base-file,base.tmp \
- -Wl,--entry,$(TARGET_ENTRY) \
- $(TARGET_LFLAGS) \
- -o junk.tmp \
- $(MK_FULLRES) $(MK_STRIPPED_OBJECT) $(MK_LIBS) $(MK_GCCLIBS)
- - $(RM) junk.tmp
- $(DLLTOOL) --dllname $(MK_FULLNAME) \
- --base-file base.tmp \
- --output-exp temp.exp $(MK_EXTRACMD) $(MK_KILLAT)
- - $(RM) base.tmp
- $(LD_CC) $(TARGET_LFLAGS) \
- -Wl,--subsystem,native \
- -Wl,--image-base,$(TARGET_BASE) \
- -Wl,--file-alignment,0x1000 \
- -Wl,--section-alignment,0x1000 \
- -Wl,--entry,$(TARGET_ENTRY) \
- -Wl,temp.exp -mdll \
- -o $(MK_FULLNAME) \
- $(MK_FULLRES) $(MK_STRIPPED_OBJECT) $(MK_LIBS) $(MK_GCCLIBS)
-ifneq ($(TARGET_CPPAPP),yes)
- - $(RM) temp.exp $(MK_STRIPPED_OBJECT)
-else
- - $(RM) temp.exp
-endif
+$(MK_FULLNAME): $(MK_NOSTRIPNAME)
+ $(HALFVERBOSEECHO) [RSYM] $(MK_FULLNAME)
+ $(RSYM) $(MK_NOSTRIPNAME) $(MK_FULLNAME)
@echo $(MK_FULLNAME) was successfully built.
endif # MK_MODE
MK_CLEANFILTERED := $(MK_OBJECTS:.o=.d) $(TARGET_PCH:.h=.d)
MK_CLEANDEPS := $(join $(dir $(MK_CLEANFILTERED)), $(addprefix ., $(notdir $(MK_CLEANFILTERED))))
+# FIXME: The $(MK_BASENAME).sym can be removed around 15 Feb 2005
clean: $(MK_REGTESTS_CLEAN) $(SUBDIRS:%=%_clean)
$(HALFVERBOSEECHO) [CLEAN]
- $(RM) *.o $(MK_PCHNAME) $(MK_BASENAME).sym $(MK_BASENAME).a $(MK_RESOURCE) \
endif # MK_INSTALL
-ifeq ($(INSTALL_SYMBOLS),yes)
-
-forceinstall: $(SUBDIRS:%=%_install) $(MK_FULLNAME) $(MK_BASENAME).sym
- $(HALFVERBOSEECHO) [INSTALL] $(MK_FULLNAME) to $(MK_INSTALLDIR)/$(MK_INSTALL_FULLNAME)
- -$(CP) $(MK_FULLNAME) $(INSTALL_DIR)/$(MK_INSTALLDIR)/$(MK_INSTALL_FULLNAME)
- $(HALFVERBOSEECHO) [INSTALL] $(MK_BASENAME).sym to symbols/$(MK_INSTALL_BASENAME).sym
- -$(CP) $(MK_BASENAME).sym $(INSTALL_DIR)/symbols/$(MK_INSTALL_BASENAME).sym
-
-else # INSTALL_SYMBOLS
-
forceinstall: $(SUBDIRS:%=%_install) $(MK_FULLNAME)
$(HALFVERBOSEECHO) [INSTALL] $(MK_FULLNAME) to $(MK_INSTALLDIR)/$(MK_INSTALL_FULLNAME)
-$(CP) $(MK_FULLNAME) $(INSTALL_DIR)/$(MK_INSTALLDIR)/$(MK_INSTALL_FULLNAME)
-endif # INSTALL_SYMBOLS
-
-
# Bootstrap files for the bootable CD
ifeq ($(TARGET_BOOTSTRAP),yes)
/*
* Usage: rsym input-file output-file
+ *
+ * There are two sources of information: the .stab/.stabstr
+ * sections of the executable and the COFF symbol table. Most
+ * of the information is in the .stab/.stabstr sections.
+ * However, most of our asm files don't contain .stab directives,
+ * so routines implemented in assembler won't show up in the
+ * .stab section. They are present in the COFF symbol table.
+ * So, we mostly use the .stab/.stabstr sections, but we augment
+ * the info there with info from the COFF symbol table when
+ * possible.
+ *
+ * This is a tool and is compiled using the host compiler,
+ * i.e. on Linux gcc and not mingw-gcc (cross-compiler).
+ * Therefore we can't include SDK headers and we have to
+ * duplicate some definitions here.
+ * Also note that the internal functions are "old C-style",
+ * returning an int, where a return of 0 means success and
+ * non-zero is failure.
*/
+
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#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;
+#if defined(_WIN64)
+typedef unsigned __int64 ULONG_PTR;
+#else
+typedef unsigned long ULONG_PTR;
+#endif
#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;
+ 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)
+
+#define IMAGE_FILE_LINE_NUMS_STRIPPED 4
+#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 8
+#define IMAGE_FILE_DEBUG_STRIPPED 512
+
#pragma pack(push,4)
+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_DATA_DIRECTORY {
- DWORD VirtualAddress;
- DWORD Size;
+ DWORD VirtualAddress;
+ DWORD Size;
} IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY;
+
+#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5
+
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];
+ 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;
+
+#define IMAGE_SCN_TYPE_NOLOAD 0x00000002
+#define IMAGE_SCN_LNK_REMOVE 0x00000800
+#define IMAGE_SCN_MEM_READ 0x40000000
+#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
+
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;
+ 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;
+
+typedef struct _IMAGE_BASE_RELOCATION {
+ DWORD VirtualAddress;
+ DWORD SizeOfBlock;
+} IMAGE_BASE_RELOCATION,*PIMAGE_BASE_RELOCATION;
+
+
+typedef struct {
+ unsigned short f_magic; /* magic number */
+ unsigned short f_nscns; /* number of sections */
+ unsigned long f_timdat; /* time & date stamp */
+ unsigned long f_symptr; /* file pointer to symtab */
+ unsigned long f_nsyms; /* number of symtab entries */
+ unsigned short f_opthdr; /* sizeof(optional hdr) */
+ unsigned short f_flags; /* flags */
+} FILHDR;
+
+typedef struct {
+ char s_name[8]; /* section name */
+ unsigned long s_paddr; /* physical address, aliased s_nlib */
+ unsigned long s_vaddr; /* virtual address */
+ unsigned long s_size; /* section size */
+ unsigned long s_scnptr; /* file ptr to raw data for section */
+ unsigned long s_relptr; /* file ptr to relocation */
+ unsigned long s_lnnoptr; /* file ptr to line numbers */
+ unsigned short s_nreloc; /* number of relocation entries */
+ unsigned short s_nlnno; /* number of line number entries */
+ unsigned long s_flags; /* flags */
+} SCNHDR;
#pragma pack(pop)
typedef struct _SYMBOLFILE_HEADER {
- unsigned long StabsOffset;
- unsigned long StabsLength;
- unsigned long StabstrOffset;
- unsigned long StabstrLength;
unsigned long SymbolsOffset;
unsigned long SymbolsLength;
- unsigned long SymbolstrOffset;
- unsigned long SymbolstrLength;
+ unsigned long StringsOffset;
+ unsigned long StringsLength;
} SYMBOLFILE_HEADER, *PSYMBOLFILE_HEADER;
typedef struct _STAB_ENTRY {
#define N_SLINE 0x44
#define N_SO 0x64
-typedef struct
-{
- unsigned long OldOffset;
- unsigned long NewOffset;
- char* Name;
- unsigned long Length;
-} STR_ENTRY, *PSTR_ENTRY;
-
/* COFF symbol table */
#define E_SYMNMLEN 8 /* # characters in a symbol name */
#define C_HIDDEN 106 /* ext symbol in dmert public lib */
#pragma pack(push,1)
-typedef struct _EXTERNAL_SYMENT
+typedef struct _COFF_SYMENT
{
union
{
unsigned short e_type;
unsigned char e_sclass;
unsigned char e_numaux;
-} EXTERNAL_SYMENT, *PEXTERNAL_SYMENT;
+} COFF_SYMENT, *PCOFF_SYMENT;
#pragma pack(pop)
+typedef struct _ROSSYM_ENTRY {
+ ULONG_PTR Address;
+ ULONG FunctionOffset;
+ ULONG FileOffset;
+ ULONG SourceLine;
+} ROSSYM_ENTRY, *PROSSYM_ENTRY;
+
+#define ROUND_UP(N, S) (((N) + (S) - 1) & ~((S) - 1))
+
char* convert_path(char* origpath)
{
char* newpath;
return(newpath);
}
-static void
-RelocateString(ULONG *Offset, PSTR_ENTRY StrEntry, ULONG *StrCount, PVOID SymbolStringsBase)
+static int
+CompareSymEntry(const PROSSYM_ENTRY SymEntry1, const PROSSYM_ENTRY SymEntry2)
+{
+ if (SymEntry1->Address < SymEntry2->Address)
+ {
+ return -1;
+ }
+
+ if (SymEntry2->Address < SymEntry1->Address)
+ {
+ return +1;
+ }
+
+ return 0;
+}
+
+static int
+GetStabInfo(void *FileData, PIMAGE_FILE_HEADER PEFileHeader,
+ PIMAGE_SECTION_HEADER PESectionHeaders,
+ ULONG *StabSymbolsLength, void **StabSymbolsBase,
+ ULONG *StabStringsLength, void **StabStringsBase)
{
- ULONG i;
+ ULONG Idx;
+
+ /* Load .stab and .stabstr sections if available */
+ *StabSymbolsBase = NULL;
+ *StabSymbolsLength = 0;
+ *StabStringsBase = NULL;
+ *StabStringsLength = 0;
- for (i = 0; i < *StrCount; i++)
+ for (Idx = 0; Idx < PEFileHeader->NumberOfSections; Idx++)
{
- if (*Offset == StrEntry[i].OldOffset)
+ /* printf("section: '%.08s'\n", PESectionHeaders[Idx].Name); */
+ if ((strncmp((char*)PESectionHeaders[Idx].Name, ".stab", 5) == 0)
+ && (PESectionHeaders[Idx].Name[5] == 0))
+ {
+ /* printf(".stab section found. Size %d\n",
+ PESectionHeaders[Idx].SizeOfRawData); */
+
+ *StabSymbolsLength = PESectionHeaders[Idx].SizeOfRawData;
+ *StabSymbolsBase = (void *)((char *) FileData + PESectionHeaders[Idx].PointerToRawData);
+ }
+
+ if (strncmp((char*)PESectionHeaders[Idx].Name, ".stabstr", 8) == 0)
{
- *Offset = StrEntry[i].NewOffset;
- return;
+ /* printf(".stabstr section found. Size %d\n",
+ PESectionHeaders[Idx].SizeOfRawData); */
+
+ *StabStringsLength = PESectionHeaders[Idx].SizeOfRawData;
+ *StabStringsBase = (void *)((char *) FileData + PESectionHeaders[Idx].PointerToRawData);
}
}
- StrEntry[*StrCount].OldOffset = *Offset;
- StrEntry[*StrCount].Name = (char*) SymbolStringsBase + StrEntry[*StrCount].OldOffset;
- StrEntry[*StrCount].Length = strlen(StrEntry[*StrCount].Name) + 1;
- if (*StrCount == 0)
+ return 0;
+}
+
+static int
+GetCoffInfo(void *FileData, PIMAGE_FILE_HEADER PEFileHeader,
+ PIMAGE_SECTION_HEADER PESectionHeaders,
+ ULONG *CoffSymbolsLength, void **CoffSymbolsBase,
+ ULONG *CoffStringsLength, void **CoffStringsBase)
+{
+
+ if (0 == PEFileHeader->PointerToSymbolTable || 0 == PEFileHeader->NumberOfSymbols)
{
- StrEntry[*StrCount].NewOffset = 0;
+ /* No COFF symbol table */
+ *CoffSymbolsLength = 0;
+ *CoffStringsLength = 0;
}
else
{
- StrEntry[*StrCount].NewOffset = StrEntry[*StrCount - 1].NewOffset
- + StrEntry[*StrCount - 1].Length;
+ *CoffSymbolsLength = PEFileHeader->NumberOfSymbols * sizeof(COFF_SYMENT);
+ *CoffSymbolsBase = (void *)((char *) FileData + PEFileHeader->PointerToSymbolTable);
+ *CoffStringsLength = *((ULONG *) ((char *) *CoffSymbolsBase + *CoffSymbolsLength));
+ *CoffStringsBase = (void *)((char *) *CoffSymbolsBase + *CoffSymbolsLength);
}
- *Offset = StrEntry[*StrCount].NewOffset;
- (*StrCount)++;
+
+ return 0;
}
-static int
-CompareSyment(const PEXTERNAL_SYMENT SymEntry1, const PEXTERNAL_SYMENT SymEntry2)
+static ULONG
+FindOrAddString(char *StringToFind, ULONG *StringsLength, void *StringsBase)
{
- if (SymEntry1->e_value < SymEntry2->e_value)
- {
- return -1;
- }
+ char *Search, *End;
+
+ Search = (char *) StringsBase;
+ End = Search + *StringsLength;
- if (SymEntry2->e_value < SymEntry1->e_value)
+ while (Search < End)
{
- return +1;
+ if (0 == strcmp(Search, StringToFind))
+ {
+ return Search - (char *) StringsBase;
+ }
+ Search += strlen(Search) + 1;
}
- return 0;
-}
+ strcpy(Search, StringToFind);
+ *StringsLength += strlen(StringToFind) + 1;
-#define TRANSFER_SIZE (65536)
+ return Search - (char *) StringsBase;
+}
-int main(int argc, char* argv[])
+static int
+ConvertStabs(ULONG *SymbolsCount, PROSSYM_ENTRY *SymbolsBase,
+ ULONG *StringsLength, void *StringsBase,
+ ULONG StabSymbolsLength, void *StabSymbolsBase,
+ ULONG StabStringsLength, void *StabStringsBase,
+ ULONG_PTR ImageBase, PIMAGE_FILE_HEADER PEFileHeader,
+ PIMAGE_SECTION_HEADER PESectionHeaders)
{
- SYMBOLFILE_HEADER SymbolFileHeader;
- IMAGE_DOS_HEADER PEDosHeader;
- IMAGE_FILE_HEADER PEFileHeader;
- PIMAGE_OPTIONAL_HEADER PEOptHeader;
- PIMAGE_SECTION_HEADER PESectionHeaders;
- ULONG ImageBase;
- PVOID SymbolsBase;
- ULONG SymbolsLength;
- PVOID SymbolStringsBase;
- ULONG SymbolStringsLength;
- PVOID CoffSymbolsBase;
- ULONG CoffSymbolsLength;
- PVOID CoffSymbolStringsBase;
- ULONG CoffSymbolStringsLength;
- ULONG Idx;
- char* path1;
- char* path2;
- FILE* in;
- FILE* out;
- int n_in;
- int n_out;
PSTAB_ENTRY StabEntry;
- ULONG Count;
- ULONG i;
- ULONG SymbolsCount;
- PSTR_ENTRY StrEntry;
- ULONG StrCount;
- PSTR_ENTRY CoffStrEntry;
- ULONG CoffStrCount;
- PEXTERNAL_SYMENT SymEntry;
- unsigned NumAux;
-
- if (argc != 3)
- {
- fprintf(stderr, "Too many arguments\n");
- exit(1);
- }
+ ULONG Count, i;
+ ULONG_PTR Address, LastFunctionAddress;
+ int First;
+ char *Name;
+ char FuncName[256];
- path1 = convert_path(argv[1]);
- path2 = convert_path(argv[2]);
+ StabEntry = StabSymbolsBase;
+ Count = StabSymbolsLength / sizeof(STAB_ENTRY);
+ *SymbolsBase = malloc(Count * sizeof(ROSSYM_ENTRY));
+ if (NULL == *SymbolsBase)
+ {
+ fprintf(stderr, "Failed to allocate memory for converted .stab symbols\n");
+ return 1;
+ }
+ *SymbolsCount = 0;
- in = fopen(path1, "rb");
- if (in == NULL)
+ LastFunctionAddress = 0;
+ First = 1;
+ for (i = 0; i < Count; i++)
{
- perror("Cannot open input file");
- exit(1);
+ switch (StabEntry[i].n_type)
+ {
+ case N_SO:
+ Name = (char *) StabStringsBase + StabEntry[i].n_strx;
+ if ('\0' == *Name || '/' == Name[strlen(Name) - 1]
+ || '\\' == Name[strlen(Name) - 1]
+ || StabEntry[i].n_value < ImageBase)
+ {
+ continue;
+ }
+ Address = StabEntry[i].n_value - ImageBase;
+ if (Address != (*SymbolsBase)[*SymbolsCount].Address && ! First)
+ {
+ (*SymbolsCount)++;
+ }
+ (*SymbolsBase)[*SymbolsCount].Address = Address;
+ (*SymbolsBase)[*SymbolsCount].FileOffset = FindOrAddString((char *) StabStringsBase
+ + StabEntry[i].n_strx,
+ StringsLength,
+ StringsBase);
+ (*SymbolsBase)[*SymbolsCount].FunctionOffset = 0;
+ (*SymbolsBase)[*SymbolsCount].SourceLine = 0;
+ LastFunctionAddress = 0;
+ break;
+ case N_FUN:
+ if (0 == StabEntry[i].n_desc || StabEntry[i].n_value < ImageBase) /* line # 0 isn't valid */
+ {
+ continue;
+ }
+ Address = StabEntry[i].n_value - ImageBase;
+ if (Address != (*SymbolsBase)[*SymbolsCount].Address && ! First)
+ {
+ (*SymbolsCount)++;
+ (*SymbolsBase)[*SymbolsCount].FileOffset = (*SymbolsBase)[*SymbolsCount - 1].FileOffset;
+ }
+ (*SymbolsBase)[*SymbolsCount].Address = Address;
+ if (sizeof(FuncName) <= strlen((char *) StabStringsBase + StabEntry[i].n_strx))
+ {
+ free(*SymbolsBase);
+ fprintf(stderr, "Function name too long\n");
+ return 1;
+ }
+ strcpy(FuncName, (char *) StabStringsBase + StabEntry[i].n_strx);
+ Name = strchr(FuncName, ':');
+ if (NULL != Name)
+ {
+ *Name = '\0';
+ }
+ (*SymbolsBase)[*SymbolsCount].FunctionOffset = FindOrAddString(FuncName,
+ StringsLength,
+ StringsBase);
+ (*SymbolsBase)[*SymbolsCount].SourceLine = 0;
+ LastFunctionAddress = Address;
+ break;
+ case N_SLINE:
+ if (0 == LastFunctionAddress)
+ {
+ Address = StabEntry[i].n_value - ImageBase;
+ }
+ else
+ {
+ Address = LastFunctionAddress + StabEntry[i].n_value;
+ }
+ if (Address != (*SymbolsBase)[*SymbolsCount].Address && ! First)
+ {
+ (*SymbolsCount)++;
+ (*SymbolsBase)[*SymbolsCount].FileOffset = (*SymbolsBase)[*SymbolsCount - 1].FileOffset;
+ (*SymbolsBase)[*SymbolsCount].FunctionOffset = (*SymbolsBase)[*SymbolsCount - 1].FunctionOffset;
+ }
+ (*SymbolsBase)[*SymbolsCount].Address = Address;
+ (*SymbolsBase)[*SymbolsCount].SourceLine = StabEntry[i].n_desc;
+ break;
+ default:
+ continue;
+ }
+ First = 0;
}
+ (*SymbolsCount)++;
- out = fopen(path2, "wb");
- if (out == NULL)
+ qsort(*SymbolsBase, *SymbolsCount, sizeof(ROSSYM_ENTRY), (int (*)(const void *, const void *)) CompareSymEntry);
+
+ return 0;
+}
+
+static int
+ConvertCoffs(ULONG *SymbolsCount, PROSSYM_ENTRY *SymbolsBase,
+ ULONG *StringsLength, void *StringsBase,
+ ULONG CoffSymbolsLength, void *CoffSymbolsBase,
+ ULONG CoffStringsLength, void *CoffStringsBase,
+ ULONG_PTR ImageBase, PIMAGE_FILE_HEADER PEFileHeader,
+ PIMAGE_SECTION_HEADER PESectionHeaders)
+{
+ ULONG Count, i;
+ PCOFF_SYMENT CoffEntry;
+ char FuncName[256];
+ char *p;
+
+ CoffEntry = (PCOFF_SYMENT) CoffSymbolsBase;
+ Count = CoffSymbolsLength / sizeof(COFF_SYMENT);
+ *SymbolsBase = malloc(Count * sizeof(ROSSYM_ENTRY));
+ if (NULL == *SymbolsBase)
{
- perror("Cannot open output file");
- fclose(in);
- exit(1);
+ fprintf(stderr, "Unable to allocate memory for converted COFF symbols\n");
+ return 1;
}
+ *SymbolsCount = 0;
- /* Check if MZ header exists */
- n_in = fread(&PEDosHeader, 1, sizeof(PEDosHeader), in);
- if (PEDosHeader.e_magic != IMAGE_DOS_MAGIC && PEDosHeader.e_lfanew != 0L)
+ for (i = 0; i < Count; i++)
{
- perror("Input file is not a PE image.\n");
+ if (ISFCN(CoffEntry[i].e_type) || C_EXT == CoffEntry[i].e_sclass)
+ {
+ (*SymbolsBase)[*SymbolsCount].Address = CoffEntry[i].e_value;
+ if (0 < CoffEntry[i].e_scnum)
+ {
+ if (PEFileHeader->NumberOfSections < CoffEntry[i].e_scnum)
+ {
+ free(*SymbolsBase);
+ fprintf(stderr, "Invalid section number %d in COFF symbols (only %d sections present)\n",
+ CoffEntry[i].e_scnum, PEFileHeader->NumberOfSections);
+ return 1;
+ }
+ (*SymbolsBase)[*SymbolsCount].Address += PESectionHeaders[CoffEntry[i].e_scnum - 1].VirtualAddress;
+ }
+ (*SymbolsBase)[*SymbolsCount].FileOffset = 0;
+ if (0 == CoffEntry[i].e.e.e_zeroes)
+ {
+ if (sizeof(FuncName) <= strlen((char *) CoffStringsBase + CoffEntry[i].e.e.e_offset))
+ {
+ free(*SymbolsBase);
+ fprintf(stderr, "Function name too long\n");
+ return 1;
+ }
+ strcpy(FuncName, (char *) CoffStringsBase + CoffEntry[i].e.e.e_offset);
+ }
+ else
+ {
+ memcpy(FuncName, CoffEntry[i].e.e_name, E_SYMNMLEN);
+ FuncName[E_SYMNMLEN] = '\0';
+ }
+
+ /* Name demangling: stdcall */
+ p = strrchr(FuncName, '@');
+ if (NULL != p)
+ {
+ *p = '\0';
+ }
+ p = ('_' == FuncName[0] || '@' == FuncName[0] ? FuncName + 1 : FuncName);
+ (*SymbolsBase)[*SymbolsCount].FunctionOffset = FindOrAddString(p,
+ StringsLength,
+ StringsBase);
+ (*SymbolsBase)[*SymbolsCount].SourceLine = 0;
+ (*SymbolsCount)++;
+ }
+ i += CoffEntry[i].e_numaux;
}
- /* 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);
+ qsort(*SymbolsBase, *SymbolsCount, sizeof(ROSSYM_ENTRY), (int (*)(const void *, const void *)) CompareSymEntry);
- /* Read optional header */
- PEOptHeader = malloc(PEFileHeader.SizeOfOptionalHeader);
- fread ( PEOptHeader, 1, PEFileHeader.SizeOfOptionalHeader, in );
- ImageBase = PEOptHeader->ImageBase;
+ return 0;
+}
- /* 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);
+static int
+MergeStabsAndCoffs(ULONG *MergedSymbolCount, PROSSYM_ENTRY *MergedSymbols,
+ ULONG StabSymbolsCount, PROSSYM_ENTRY StabSymbols,
+ ULONG CoffSymbolsCount, PROSSYM_ENTRY CoffSymbols)
+{
+ ULONG StabIndex, j;
+ ULONG CoffIndex;
+ ULONG_PTR StabFunctionStartAddress;
+ ULONG StabFunctionStringOffset, NewStabFunctionStringOffset;
- /* Copy .stab and .stabstr sections if available */
- SymbolsBase = NULL;
- SymbolsLength = 0;
- SymbolStringsBase = NULL;
- SymbolStringsLength = 0;
+ *MergedSymbols = malloc(StabSymbolsCount * sizeof(ROSSYM_ENTRY));
+ if (NULL == *MergedSymbols)
+ {
+ fprintf(stderr, "Unable to allocate memory for merged symbols\n");
+ return 1;
+ }
+ *MergedSymbolCount = 0;
- for (Idx = 0; Idx < PEFileHeader.NumberOfSections; Idx++)
+ StabFunctionStartAddress = 0;
+ StabFunctionStringOffset = 0;
+ CoffIndex = 0;
+ for (StabIndex = 0; StabIndex < StabSymbolsCount; StabIndex++)
{
- //printf("section: '%.08s'\n", PESectionHeaders[Idx].Name);
- if ((strncmp((char*)PESectionHeaders[Idx].Name, ".stab", 5) == 0)
- && (PESectionHeaders[Idx].Name[5] == 0))
+ (*MergedSymbols)[*MergedSymbolCount] = StabSymbols[StabIndex];
+ for (j = StabIndex + 1;
+ j < StabSymbolsCount && StabSymbols[j].Address == StabSymbols[StabIndex].Address;
+ j++)
+ {
+ if (0 != StabSymbols[j].FileOffset && 0 == (*MergedSymbols)[*MergedSymbolCount].FileOffset)
+ {
+ (*MergedSymbols)[*MergedSymbolCount].FileOffset = StabSymbols[j].FileOffset;
+ }
+ if (0 != StabSymbols[j].FunctionOffset && 0 == (*MergedSymbols)[*MergedSymbolCount].FunctionOffset)
+ {
+ (*MergedSymbols)[*MergedSymbolCount].FunctionOffset = StabSymbols[j].FunctionOffset;
+ }
+ if (0 != StabSymbols[j].SourceLine && 0 == (*MergedSymbols)[*MergedSymbolCount].SourceLine)
+ {
+ (*MergedSymbols)[*MergedSymbolCount].SourceLine = StabSymbols[j].SourceLine;
+ }
+ }
+ StabIndex = j - 1;
+ while (CoffIndex < CoffSymbolsCount
+ && CoffSymbols[CoffIndex + 1].Address <= (*MergedSymbols)[*MergedSymbolCount].Address)
+ {
+ CoffIndex++;
+ }
+ NewStabFunctionStringOffset = (*MergedSymbols)[*MergedSymbolCount].FunctionOffset;
+ if (CoffSymbols[CoffIndex].Address < (*MergedSymbols)[*MergedSymbolCount].Address
+ && StabFunctionStartAddress < CoffSymbols[CoffIndex].Address
+ && 0 != CoffSymbols[CoffIndex].FunctionOffset)
+ {
+ (*MergedSymbols)[*MergedSymbolCount].FunctionOffset = CoffSymbols[CoffIndex].FunctionOffset;
+ }
+ if (StabFunctionStringOffset != NewStabFunctionStringOffset)
{
- //printf(".stab section found. Size %d\n",
- // PESectionHeaders[Idx].SizeOfRawData);
+ StabFunctionStartAddress = (*MergedSymbols)[*MergedSymbolCount].Address;
+ }
+ StabFunctionStringOffset = NewStabFunctionStringOffset;
+ (*MergedSymbolCount)++;
+ }
- SymbolsLength = PESectionHeaders[Idx].SizeOfRawData;
- SymbolsBase = malloc(SymbolsLength);
+ return 0;
+}
- fseek(in, PESectionHeaders[Idx].PointerToRawData, SEEK_SET);
- n_in = fread(SymbolsBase, 1, SymbolsLength, in);
- }
+static PIMAGE_SECTION_HEADER
+FindSectionForRVA(DWORD RVA, unsigned NumberOfSections, PIMAGE_SECTION_HEADER SectionHeaders)
+{
+ unsigned Section;
- if (strncmp((char*)PESectionHeaders[Idx].Name, ".stabstr", 8) == 0)
+ for (Section = 0; Section < NumberOfSections; Section++)
+ {
+ if (SectionHeaders[Section].VirtualAddress <= RVA &&
+ RVA < SectionHeaders[Section].VirtualAddress + SectionHeaders[Section].Misc.VirtualSize)
{
- //printf(".stabstr section found. Size %d\n",
- // PESectionHeaders[Idx].SizeOfRawData);
+ return SectionHeaders + Section;
+ }
+ }
+
+ return NULL;
+}
- SymbolStringsLength = PESectionHeaders[Idx].SizeOfRawData;
- SymbolStringsBase = malloc(SymbolStringsLength);
+static int
+IncludeRelocationsForSection(PIMAGE_SECTION_HEADER SectionHeader)
+{
+ static char *BlacklistedSections[] =
+ {
+ ".idata",
+ ".reloc"
+ };
+ char SectionName[IMAGE_SIZEOF_SHORT_NAME];
+ unsigned i;
- fseek(in, PESectionHeaders[Idx].PointerToRawData, SEEK_SET);
- n_in = fread(SymbolStringsBase, 1, SymbolStringsLength, in);
+ if (0 != (SectionHeader->Characteristics & IMAGE_SCN_LNK_REMOVE))
+ {
+ return 0;
+ }
+
+ for (i = 0; i < sizeof(BlacklistedSections) / sizeof(BlacklistedSections[0]); i++)
+ {
+ strncpy(SectionName, BlacklistedSections[i], IMAGE_SIZEOF_SHORT_NAME);
+ if (0 == memcmp(SectionName, SectionHeader->Name, IMAGE_SIZEOF_SHORT_NAME))
+ {
+ return 0;
}
}
- StabEntry = SymbolsBase;
- SymbolsCount = SymbolsLength / sizeof(STAB_ENTRY);
- Count = 0;
+ return 1;
+}
- for (i = 0; i < SymbolsCount; i++)
+static int
+ProcessRelocations(ULONG *ProcessedRelocsLength, void **ProcessedRelocs,
+ void *RawData, PIMAGE_OPTIONAL_HEADER OptHeader,
+ unsigned NumberOfSections, PIMAGE_SECTION_HEADER SectionHeaders)
+{
+ PIMAGE_SECTION_HEADER RelocSectionHeader, TargetSectionHeader;
+ PIMAGE_BASE_RELOCATION BaseReloc, End, AcceptedRelocs;
+ int Found;
+
+ if (OptHeader->NumberOfRvaAndSizes < IMAGE_DIRECTORY_ENTRY_BASERELOC
+ || 0 == OptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress)
{
- switch ( StabEntry[i].n_type )
- {
- case N_FUN:
- if ( StabEntry[i].n_desc == 0 ) // line # 0 isn't valid
- continue;
- break;
- case N_SLINE:
- break;
- case N_SO:
- break;
- default:
- continue;
- }
- memmove(&StabEntry[Count], &StabEntry[i], sizeof(STAB_ENTRY));
- if ( StabEntry[Count].n_value >= ImageBase )
- StabEntry[Count].n_value -= ImageBase;
- Count++;
+ /* No relocation entries */
+ *ProcessedRelocsLength = 0;
+ *ProcessedRelocs = NULL;
+ return 0;
}
- StrEntry = malloc(sizeof(STR_ENTRY) * Count);
- StrCount = 0;
+ RelocSectionHeader = FindSectionForRVA(OptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress,
+ NumberOfSections, SectionHeaders);
+ if (NULL == RelocSectionHeader)
+ {
+ fprintf(stderr, "Can't find section header for relocation data\n");
+ return 1;
+ }
- for (i = 0; i < Count; i++)
+ *ProcessedRelocs = malloc(RelocSectionHeader->SizeOfRawData);
+ if (NULL == *ProcessedRelocs)
{
- RelocateString(&StabEntry[i].n_strx, StrEntry, &StrCount, SymbolStringsBase);
+ fprintf(stderr, "Failed to allocate %lu bytes for relocations\n", RelocSectionHeader->SizeOfRawData);
+ return 1;
}
+ *ProcessedRelocsLength = 0;
- SymbolFileHeader.StabsOffset = sizeof(SYMBOLFILE_HEADER);
- SymbolFileHeader.StabsLength = Count * sizeof(STAB_ENTRY);
- SymbolFileHeader.StabstrOffset = SymbolFileHeader.StabsOffset + SymbolFileHeader.StabsLength;
- SymbolFileHeader.StabstrLength = StrEntry[StrCount-1].NewOffset + StrEntry[StrCount-1].Length;
+ BaseReloc = (PIMAGE_BASE_RELOCATION) ((char *) RawData
+ + RelocSectionHeader->PointerToRawData
+ + (OptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress -
+ RelocSectionHeader->VirtualAddress));
+ End = (PIMAGE_BASE_RELOCATION) ((char *) BaseReloc
+ + OptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);
- if (0 == PEFileHeader.PointerToSymbolTable || 0 == PEFileHeader.NumberOfSymbols)
+ while (BaseReloc < End && 0 < BaseReloc->SizeOfBlock)
{
- /* No COFF symbol table */
- SymbolFileHeader.SymbolsOffset = 0;
- SymbolFileHeader.SymbolsLength = 0;
- SymbolFileHeader.SymbolstrOffset = 0;
- SymbolFileHeader.SymbolstrLength = 0;
+ TargetSectionHeader = FindSectionForRVA(BaseReloc->VirtualAddress, NumberOfSections,
+ SectionHeaders);
+ if (NULL != TargetSectionHeader && IncludeRelocationsForSection(TargetSectionHeader))
+ {
+ AcceptedRelocs = *ProcessedRelocs;
+ Found = 0;
+ while (AcceptedRelocs < (PIMAGE_BASE_RELOCATION) ((char *) *ProcessedRelocs +
+ *ProcessedRelocsLength)
+ && ! Found)
+ {
+ Found = BaseReloc->SizeOfBlock == AcceptedRelocs->SizeOfBlock
+ && 0 == memcmp(BaseReloc, AcceptedRelocs, AcceptedRelocs->SizeOfBlock);
+ AcceptedRelocs= (PIMAGE_BASE_RELOCATION) ((char *) AcceptedRelocs +
+ AcceptedRelocs->SizeOfBlock);
+ }
+ if (! Found)
+ {
+ memcpy((char *) *ProcessedRelocs + *ProcessedRelocsLength,
+ BaseReloc, BaseReloc->SizeOfBlock);
+ *ProcessedRelocsLength += BaseReloc->SizeOfBlock;
+ }
+ }
+ BaseReloc = (PIMAGE_BASE_RELOCATION)((char *) BaseReloc + BaseReloc->SizeOfBlock);
}
- else
+
+ return 0;
+}
+
+static int
+CreateOutputFile(FILE *OutFile, void *InData,
+ PIMAGE_DOS_HEADER InDosHeader, PIMAGE_FILE_HEADER InFileHeader,
+ PIMAGE_OPTIONAL_HEADER InOptHeader, PIMAGE_SECTION_HEADER InSectionHeaders,
+ ULONG RosSymLength, void *RosSymSection)
+{
+ ULONG StartOfRawData;
+ unsigned Section;
+ void *OutHeader, *ProcessedRelocs, *PaddedRosSym, *Data;
+ PIMAGE_DOS_HEADER OutDosHeader;
+ PIMAGE_FILE_HEADER OutFileHeader;
+ PIMAGE_OPTIONAL_HEADER OutOptHeader;
+ PIMAGE_SECTION_HEADER OutSectionHeaders, CurrentSectionHeader;
+ DWORD CheckSum;
+ ULONG Length, i;
+ ULONG ProcessedRelocsLength;
+ ULONG RosSymOffset, RosSymFileLength;
+ int InRelocSectionIndex;
+ PIMAGE_SECTION_HEADER OutRelocSection;
+
+ StartOfRawData = 0;
+ for (Section = 0; Section < InFileHeader->NumberOfSections; Section++)
{
- CoffSymbolsLength = PEFileHeader.NumberOfSymbols * sizeof(EXTERNAL_SYMENT);
- CoffSymbolsBase = malloc(CoffSymbolsLength);
- if (NULL == CoffSymbolsBase)
+ if ((0 == StartOfRawData
+ || InSectionHeaders[Section].PointerToRawData < StartOfRawData)
+ && 0 != InSectionHeaders[Section].PointerToRawData
+ && 0 == (InSectionHeaders[Section].Characteristics & IMAGE_SCN_LNK_REMOVE))
{
- fprintf(stderr, "Unable to allocate %u bytes for COFF symbols\n",
- (unsigned) CoffSymbolsLength);
- exit(1);
+ StartOfRawData = InSectionHeaders[Section].PointerToRawData;
}
- fseek(in, PEFileHeader.PointerToSymbolTable, SEEK_SET);
- n_in = fread(CoffSymbolsBase, 1, CoffSymbolsLength, in);
+ }
+ OutHeader = malloc(StartOfRawData);
+ if (NULL == OutHeader)
+ {
+ fprintf(stderr, "Failed to allocate %lu bytes for output file header\n", StartOfRawData);
+ return 1;
+ }
+ memset(OutHeader, '\0', StartOfRawData);
+
+ OutDosHeader = (PIMAGE_DOS_HEADER) OutHeader;
+ memcpy(OutDosHeader, InDosHeader, InDosHeader->e_lfanew + sizeof(ULONG));
+
+ OutFileHeader = (PIMAGE_FILE_HEADER)((char *) OutHeader + OutDosHeader->e_lfanew + sizeof(ULONG));
+ memcpy(OutFileHeader, InFileHeader, sizeof(IMAGE_FILE_HEADER));
+ OutFileHeader->PointerToSymbolTable = 0;
+ OutFileHeader->NumberOfSymbols = 0;
+ OutFileHeader->Characteristics &= ~(IMAGE_FILE_LINE_NUMS_STRIPPED | IMAGE_FILE_LOCAL_SYMS_STRIPPED |
+ IMAGE_FILE_DEBUG_STRIPPED);
+
+ OutOptHeader = (PIMAGE_OPTIONAL_HEADER)(OutFileHeader + 1);
+ memcpy(OutOptHeader, InOptHeader, sizeof(IMAGE_OPTIONAL_HEADER));
+ OutOptHeader->CheckSum = 0;
- SymEntry = CoffSymbolsBase;
- Count = 0;
- for (i = 0; i < PEFileHeader.NumberOfSymbols; i++)
+ OutSectionHeaders = (PIMAGE_SECTION_HEADER)((char *) OutOptHeader + OutFileHeader->SizeOfOptionalHeader);
+
+ if (ProcessRelocations(&ProcessedRelocsLength, &ProcessedRelocs, InData, InOptHeader,
+ InFileHeader->NumberOfSections, InSectionHeaders))
+ {
+ return 1;
+ }
+ if (InOptHeader->NumberOfRvaAndSizes < IMAGE_DIRECTORY_ENTRY_BASERELOC
+ || 0 == InOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress)
+ {
+ InRelocSectionIndex = -1;
+ }
+ else
+ {
+ InRelocSectionIndex = FindSectionForRVA(InOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress,
+ InFileHeader->NumberOfSections, InSectionHeaders) - InSectionHeaders;
+ }
+
+ OutFileHeader->NumberOfSections = 0;
+ CurrentSectionHeader = OutSectionHeaders;
+ OutOptHeader->SizeOfImage = 0;
+ RosSymOffset = 0;
+ OutRelocSection = NULL;
+ for (Section = 0; Section < InFileHeader->NumberOfSections; Section++)
+ {
+ if (0 == (InSectionHeaders[Section].Characteristics & IMAGE_SCN_LNK_REMOVE))
{
- NumAux = SymEntry[i].e_numaux;
- if (ISFCN(SymEntry[i].e_type))
+ *CurrentSectionHeader = InSectionHeaders[Section];
+ CurrentSectionHeader->PointerToLinenumbers = 0;
+ CurrentSectionHeader->NumberOfLinenumbers = 0;
+ if (OutOptHeader->SizeOfImage < CurrentSectionHeader->VirtualAddress +
+ CurrentSectionHeader->Misc.VirtualSize)
{
- SymEntry[Count] = SymEntry[i];
- if (0 < SymEntry[Count].e_scnum)
- {
- if (PEFileHeader.NumberOfSections < SymEntry[Count].e_scnum)
- {
- fprintf(stderr, "Invalid section number %d in COFF symbols (only %d sections present)\n",
- SymEntry[Count].e_scnum, PEFileHeader.NumberOfSections);
- exit(1);
- }
- SymEntry[Count].e_value += PESectionHeaders[SymEntry[Count].e_scnum - 1].VirtualAddress;
- SymEntry[Count].e_scnum = -3;
- SymEntry[Count].e_numaux = 0;
- }
- Count++;
+ OutOptHeader->SizeOfImage = ROUND_UP(CurrentSectionHeader->VirtualAddress +
+ CurrentSectionHeader->Misc.VirtualSize,
+ OutOptHeader->SectionAlignment);
+ }
+ if (RosSymOffset < CurrentSectionHeader->PointerToRawData + CurrentSectionHeader->SizeOfRawData)
+ {
+ RosSymOffset = CurrentSectionHeader->PointerToRawData + CurrentSectionHeader->SizeOfRawData;
+ }
+ if (Section == InRelocSectionIndex)
+ {
+ OutRelocSection = CurrentSectionHeader;
}
- i += NumAux;
+ (OutFileHeader->NumberOfSections) ++;
+ CurrentSectionHeader++;
+ }
+ }
+
+ if (OutRelocSection == CurrentSectionHeader - 1)
+ {
+ OutOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = ProcessedRelocsLength;
+ if (OutOptHeader->SizeOfImage == OutRelocSection->VirtualAddress +
+ ROUND_UP(OutRelocSection->Misc.VirtualSize,
+ OutOptHeader->SectionAlignment))
+ {
+ OutOptHeader->SizeOfImage = OutRelocSection->VirtualAddress +
+ ROUND_UP(ProcessedRelocsLength,
+ OutOptHeader->SectionAlignment);
+ }
+ OutRelocSection->Misc.VirtualSize = ProcessedRelocsLength;
+ if (RosSymOffset == OutRelocSection->PointerToRawData
+ + OutRelocSection->SizeOfRawData)
+ {
+ RosSymOffset = OutRelocSection->PointerToRawData +
+ ROUND_UP(ProcessedRelocsLength, OutOptHeader->FileAlignment);
}
+ OutRelocSection->SizeOfRawData = ROUND_UP(ProcessedRelocsLength,
+ OutOptHeader->FileAlignment);
+ }
+
+ RosSymFileLength = ROUND_UP(RosSymLength, OutOptHeader->FileAlignment);
+ memcpy(CurrentSectionHeader->Name, ".rossym", 8); /* We're lucky: string is exactly 8 bytes long */
+ CurrentSectionHeader->Misc.VirtualSize = RosSymLength;
+ CurrentSectionHeader->VirtualAddress = OutOptHeader->SizeOfImage;
+ CurrentSectionHeader->SizeOfRawData = RosSymFileLength;
+ CurrentSectionHeader->PointerToRawData = RosSymOffset;
+ CurrentSectionHeader->PointerToRelocations = 0;
+ CurrentSectionHeader->PointerToLinenumbers = 0;
+ CurrentSectionHeader->NumberOfRelocations = 0;
+ CurrentSectionHeader->NumberOfLinenumbers = 0;
+ CurrentSectionHeader->Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
+ | IMAGE_SCN_LNK_REMOVE | IMAGE_SCN_TYPE_NOLOAD;
+ OutOptHeader->SizeOfImage = ROUND_UP(CurrentSectionHeader->VirtualAddress +
+ CurrentSectionHeader->Misc.VirtualSize,
+ OutOptHeader->SectionAlignment);
+ (OutFileHeader->NumberOfSections)++;
- qsort(CoffSymbolsBase, Count, sizeof(EXTERNAL_SYMENT), (int (*)(const void *, const void *)) CompareSyment);
+ PaddedRosSym = malloc(RosSymFileLength);
+ if (NULL == PaddedRosSym)
+ {
+ fprintf(stderr, "Failed to allocate %lu bytes for padded .rossym\n", RosSymFileLength);
+ return 1;
+ }
+ memcpy(PaddedRosSym, RosSymSection, RosSymLength);
+ memset((char *) PaddedRosSym + RosSymLength, '\0', RosSymFileLength - RosSymLength);
- n_in = fread(&CoffSymbolStringsLength, 1, sizeof(ULONG), in);
- CoffSymbolStringsBase = malloc(CoffSymbolStringsLength);
- if (NULL == CoffSymbolStringsBase)
+ CheckSum = 0;
+ for (i = 0; i < StartOfRawData / 2; i++)
+ {
+ CheckSum += ((unsigned short*) OutHeader)[i];
+ CheckSum = 0xffff & (CheckSum + (CheckSum >> 16));
+ }
+ Length = StartOfRawData;
+ for (Section = 0; Section < OutFileHeader->NumberOfSections; Section++)
+ {
+ if (OutRelocSection == OutSectionHeaders + Section)
+ {
+ Data = (void *) ProcessedRelocs;
+ }
+ else if (Section + 1 == OutFileHeader->NumberOfSections)
{
- fprintf(stderr, "Unable to allocate %u bytes for COFF symbol strings\n",
- (unsigned) CoffSymbolStringsLength);
- exit(1);
+ Data = (void *) PaddedRosSym;
}
- n_in = fread((char *) CoffSymbolStringsBase + sizeof(ULONG), 1, CoffSymbolStringsLength - 4, in);
+ else
+ {
+ Data = (void *) ((char *) InData + OutSectionHeaders[Section].PointerToRawData);
+ }
+ for (i = 0; i < OutSectionHeaders[Section].SizeOfRawData / 2; i++)
+ {
+ CheckSum += ((unsigned short*) Data)[i];
+ CheckSum = 0xffff & (CheckSum + (CheckSum >> 16));
+ }
+ Length += OutSectionHeaders[Section].SizeOfRawData;
+ }
+ CheckSum += Length;
+ OutOptHeader->CheckSum = CheckSum;
- CoffStrEntry = malloc(sizeof(STR_ENTRY) * Count);
- CoffStrCount = 0;
+ if (fwrite(OutHeader, 1, StartOfRawData, OutFile) != StartOfRawData)
+ {
+ perror("Error writing output header\n");
+ free(OutHeader);
+ return 1;
+ }
- for (i = 0; i < Count; i++)
+ for (Section = 0; Section < OutFileHeader->NumberOfSections; Section++)
+ {
+ if (0 != OutSectionHeaders[Section].SizeOfRawData)
{
- if (0 == SymEntry[i].e.e.e_zeroes)
+ fseek(OutFile, OutSectionHeaders[Section].PointerToRawData, SEEK_SET);
+ if (OutRelocSection == OutSectionHeaders + Section)
+ {
+ Data = (void *) ProcessedRelocs;
+ }
+ else if (Section + 1 == OutFileHeader->NumberOfSections)
{
- RelocateString(&SymEntry[i].e.e.e_offset, CoffStrEntry, &CoffStrCount, CoffSymbolStringsBase);
+ Data = (void *) PaddedRosSym;
+ }
+ else
+ {
+ Data = (void *) ((char *) InData + OutSectionHeaders[Section].PointerToRawData);
+ }
+ if (fwrite(Data, 1, OutSectionHeaders[Section].SizeOfRawData, OutFile) !=
+ OutSectionHeaders[Section].SizeOfRawData)
+ {
+ perror("Error writing section data\n");
+ free(PaddedRosSym);
+ free(OutHeader);
+ return 1;
}
}
+ }
+
+ free(PaddedRosSym);
+ free(OutHeader);
- SymbolFileHeader.SymbolsOffset = SymbolFileHeader.StabstrOffset + SymbolFileHeader.StabstrLength;
- SymbolFileHeader.SymbolsLength = Count * sizeof(EXTERNAL_SYMENT);
- SymbolFileHeader.SymbolstrOffset = SymbolFileHeader.SymbolsOffset + SymbolFileHeader.SymbolsLength;
- SymbolFileHeader.SymbolstrLength = CoffStrEntry[CoffStrCount - 1].NewOffset
- + CoffStrEntry[CoffStrCount - 1].Length;
+ return 0;
+}
+
+int main(int argc, char* argv[])
+{
+ PSYMBOLFILE_HEADER SymbolFileHeader;
+ PIMAGE_DOS_HEADER PEDosHeader;
+ PIMAGE_FILE_HEADER PEFileHeader;
+ PIMAGE_OPTIONAL_HEADER PEOptHeader;
+ PIMAGE_SECTION_HEADER PESectionHeaders;
+ ULONG ImageBase;
+ void *StabBase;
+ ULONG StabsLength;
+ void *StabStringBase;
+ ULONG StabStringsLength;
+ void *CoffBase;
+ ULONG CoffsLength;
+ void *CoffStringBase;
+ ULONG CoffStringsLength;
+ char* path1;
+ char* path2;
+ FILE* in;
+ FILE* out;
+ int n_in;
+ void *StringBase;
+ ULONG StringsLength;
+ ULONG StabSymbolsCount;
+ PROSSYM_ENTRY StabSymbols;
+ ULONG CoffSymbolsCount;
+ PROSSYM_ENTRY CoffSymbols;
+ ULONG MergedSymbolsCount;
+ PROSSYM_ENTRY MergedSymbols;
+ long FileSize;
+ void *FileData;
+ ULONG RosSymLength;
+ void *RosSymSection;
+
+ if (3 != argc)
+ {
+ fprintf(stderr, "Usage: rsym <exefile> <symfile>\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);
+ }
+ fseek(in, 0L, SEEK_END);
+ FileSize = ftell(in);
+ fseek(in, 0L, SEEK_SET);
+ FileData = malloc(FileSize);
+ if (NULL == FileData)
+ {
+ fclose(in);
+ fprintf(stderr, "Can't allocate %ld bytes to read input file\n", FileSize);
+ exit(1);
+ }
+ n_in = fread(FileData, 1, FileSize, in);
+ if (n_in != FileSize)
+ {
+ perror("Error reading from input file");
+ free(FileData);
+ fclose(in);
+ exit(1);
+ }
+ fclose(in);
+
+ /* Check if MZ header exists */
+ PEDosHeader = (PIMAGE_DOS_HEADER) FileData;
+ if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC || PEDosHeader->e_lfanew == 0L)
+ {
+ perror("Input file is not a PE image.\n");
+ free(FileData);
+ exit(1);
+ }
+
+ /* Locate PE file header */
+ /* sizeof(ULONG) = sizeof(MAGIC) */
+ PEFileHeader = (PIMAGE_FILE_HEADER)((char *) FileData + PEDosHeader->e_lfanew + sizeof(ULONG));
+
+ /* Locate optional header */
+ PEOptHeader = (PIMAGE_OPTIONAL_HEADER)(PEFileHeader + 1);
+ ImageBase = PEOptHeader->ImageBase;
+
+ /* Locate PE section headers */
+ PESectionHeaders = (PIMAGE_SECTION_HEADER)((char *) PEOptHeader + PEFileHeader->SizeOfOptionalHeader);
+
+ if (GetStabInfo(FileData, PEFileHeader, PESectionHeaders, &StabsLength, &StabBase,
+ &StabStringsLength, &StabStringBase))
+ {
+ free(FileData);
+ exit(1);
+ }
+
+ if (GetCoffInfo(FileData, PEFileHeader, PESectionHeaders, &CoffsLength, &CoffBase,
+ &CoffStringsLength, &CoffStringBase))
+ {
+ free(FileData);
+ exit(1);
+ }
+
+ StringBase = malloc(1 + StabStringsLength + CoffStringsLength +
+ (CoffsLength / sizeof(ROSSYM_ENTRY)) * (E_SYMNMLEN + 1));
+ if (NULL == StringBase)
+ {
+ free(FileData);
+ fprintf(stderr, "Failed to allocate memory for strings table\n");
+ exit(1);
+ }
+ /* Make offset 0 into an empty string */
+ *((char *) StringBase) = '\0';
+ StringsLength = 1;
+
+ if (ConvertStabs(&StabSymbolsCount, &StabSymbols, &StringsLength, StringBase,
+ StabsLength, StabBase, StabStringsLength, StabStringBase,
+ ImageBase, PEFileHeader, PESectionHeaders))
+ {
+ free(StringBase);
+ free(FileData);
+ fprintf(stderr, "Failed to allocate memory for strings table\n");
+ exit(1);
+ }
+
+ if (ConvertCoffs(&CoffSymbolsCount, &CoffSymbols, &StringsLength, StringBase,
+ CoffsLength, CoffBase, CoffStringsLength, CoffStringBase,
+ ImageBase, PEFileHeader, PESectionHeaders))
+ {
+ free(StabSymbols);
+ free(StringBase);
+ free(FileData);
+ exit(1);
+ }
+
+ if (MergeStabsAndCoffs(&MergedSymbolsCount, &MergedSymbols,
+ StabSymbolsCount, StabSymbols,
+ CoffSymbolsCount, CoffSymbols))
+ {
+ free(CoffSymbols);
+ free(StabSymbols);
+ free(StringBase);
+ free(FileData);
+ exit(1);
+ }
+
+ free(CoffSymbols);
+ free(StabSymbols);
+
+ RosSymLength = sizeof(SYMBOLFILE_HEADER) + MergedSymbolsCount * sizeof(ROSSYM_ENTRY)
+ + StringsLength;
+ RosSymSection = malloc(RosSymLength);
+ if (NULL == RosSymSection)
+ {
+ free(MergedSymbols);
+ free(StringBase);
+ free(FileData);
+ fprintf(stderr, "Unable to allocate memory for .rossym section\n");
+ exit(1);
}
+ memset(RosSymSection, '\0', RosSymLength);
+
+ SymbolFileHeader = (PSYMBOLFILE_HEADER) RosSymSection;
+ SymbolFileHeader->SymbolsOffset = sizeof(SYMBOLFILE_HEADER);
+ SymbolFileHeader->SymbolsLength = MergedSymbolsCount * sizeof(ROSSYM_ENTRY);
+ SymbolFileHeader->StringsOffset = SymbolFileHeader->SymbolsOffset + SymbolFileHeader->SymbolsLength;
+ SymbolFileHeader->StringsLength = StringsLength;
+
+ memcpy((char *) RosSymSection + SymbolFileHeader->SymbolsOffset, MergedSymbols,
+ SymbolFileHeader->SymbolsLength);
+ memcpy((char *) RosSymSection + SymbolFileHeader->StringsOffset, StringBase,
+ SymbolFileHeader->StringsLength);
- n_out = fwrite(&SymbolFileHeader, 1, sizeof(SYMBOLFILE_HEADER), out);
- n_out = fwrite(SymbolsBase, 1, SymbolFileHeader.StabsLength, out);
- for (i = 0; i < StrCount; i++)
+ free(MergedSymbols);
+ free(StringBase);
+
+ out = fopen(path2, "wb");
+ if (out == NULL)
{
- fwrite(StrEntry[i].Name, 1, StrEntry[i].Length, out);
+ perror("Cannot open output file");
+ free(RosSymSection);
+ free(FileData);
+ exit(1);
}
- n_out = fwrite(CoffSymbolsBase, 1, SymbolFileHeader.SymbolsLength, out);
- for (i = 0; i < CoffStrCount; i++)
+
+ if (CreateOutputFile(out, FileData, PEDosHeader, PEFileHeader, PEOptHeader,
+ PESectionHeaders, RosSymLength, RosSymSection))
{
- fwrite(CoffStrEntry[i].Name, 1, CoffStrEntry[i].Length, out);
+ fclose(out);
+ free(RosSymSection);
+ free(FileData);
+ exit(1);
}
fclose(out);
- exit(0);
+ free(RosSymSection);
+ free(FileData);
+
+ return 0;
}
+
+/* EOF */