mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
Include COFF symbols in our .sym files
svn path=/trunk/; revision=12895
This commit is contained in:
parent
ad6ee8a5e1
commit
5637b9f123
5 changed files with 447 additions and 94 deletions
|
@ -6,12 +6,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* #ifndef __dj_ENFORCE_ANSI_FREESTANDING
|
||||
* #ifndef __STRICT_ANSI__
|
||||
* #ifndef _POSIX_SOURCE
|
||||
*/
|
||||
|
||||
/*** coff information for Intel 386/486. */
|
||||
|
||||
/********************** FILE HEADER **********************/
|
||||
|
@ -329,13 +323,6 @@ struct external_reloc {
|
|||
/* For new sections we havn't heard of before */
|
||||
#define DEFAULT_SECTION_ALIGNMENT 4
|
||||
|
||||
/*
|
||||
* #endif /* !_POSIX_SOURCE */
|
||||
* #endif /* !__STRICT_ANSI__ */
|
||||
* #endif /* !__dj_ENFORCE_ANSI_FREESTANDING */
|
||||
*/
|
||||
#ifndef __dj_ENFORCE_FUNCTION_CALLS
|
||||
#endif /* !__dj_ENFORCE_FUNCTION_CALLS */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -8,6 +8,10 @@ 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;
|
||||
|
|
|
@ -69,8 +69,8 @@ KdbpStabFindEntry(IN PIMAGE_SYMBOL_INFO SymbolInfo,
|
|||
PVOID StabsEnd;
|
||||
ULONG_PTR AddrFound = 0;
|
||||
|
||||
StabEntry = SymbolInfo->SymbolsBase;
|
||||
StabsEnd = (PVOID)((ULONG_PTR)SymbolInfo->SymbolsBase + SymbolInfo->SymbolsLength);
|
||||
StabEntry = SymbolInfo->StabsBase;
|
||||
StabsEnd = (PVOID)((ULONG_PTR)SymbolInfo->StabsBase + SymbolInfo->StabsLength);
|
||||
if (StartEntry != NULL)
|
||||
{
|
||||
ASSERT((ULONG_PTR)StartEntry >= (ULONG_PTR)StabEntry);
|
||||
|
|
|
@ -16,6 +16,34 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/dbg/kdb_symbols.c
|
||||
|
@ -41,6 +69,7 @@
|
|||
#include <internal/safe.h>
|
||||
#include <internal/kd.h>
|
||||
#include <rosrtl/string.h>
|
||||
#include <coff.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
@ -55,6 +84,10 @@ typedef struct _SYMBOLFILE_HEADER {
|
|||
ULONG StabsLength;
|
||||
ULONG StabstrOffset;
|
||||
ULONG StabstrLength;
|
||||
ULONG SymbolsOffset;
|
||||
ULONG SymbolsLength;
|
||||
ULONG SymbolstrOffset;
|
||||
ULONG SymbolstrLength;
|
||||
} SYMBOLFILE_HEADER, *PSYMBOLFILE_HEADER;
|
||||
|
||||
typedef struct _IMAGE_SYMBOL_INFO_CACHE {
|
||||
|
@ -62,6 +95,10 @@ typedef struct _IMAGE_SYMBOL_INFO_CACHE {
|
|||
ULONG RefCount;
|
||||
UNICODE_STRING FileName;
|
||||
PVOID FileBuffer;
|
||||
PVOID StabsBase;
|
||||
ULONG StabsLength;
|
||||
PVOID StabStringsBase;
|
||||
ULONG StabStringsLength;
|
||||
PVOID SymbolsBase;
|
||||
ULONG SymbolsLength;
|
||||
PVOID SymbolStringsBase;
|
||||
|
@ -282,6 +319,67 @@ KdbSymPrintAddress(IN PVOID Address)
|
|||
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)
|
||||
|
@ -306,12 +404,13 @@ KdbSymGetAddressInformation(IN PIMAGE_SYMBOL_INFO SymbolInfo,
|
|||
OUT PCH FileName OPTIONAL,
|
||||
OUT PCH FunctionName OPTIONAL)
|
||||
{
|
||||
PSTAB_ENTRY FunctionEntry = NULL, FileEntry = NULL, LineEntry = NULL;
|
||||
PSTAB_ENTRY StabsFunctionEntry = NULL, FileEntry = NULL, LineEntry = NULL;
|
||||
struct external_syment *SymbolsFunctionEntry = NULL;
|
||||
|
||||
DPRINT("RelativeAddress = 0x%08x\n", RelativeAddress);
|
||||
|
||||
if (SymbolInfo->SymbolsBase == NULL || SymbolInfo->SymbolsLength == 0 ||
|
||||
SymbolInfo->SymbolStringsBase == NULL || SymbolInfo->SymbolStringsLength == 0)
|
||||
if (SymbolInfo->StabsBase == NULL || SymbolInfo->StabsLength == 0 ||
|
||||
SymbolInfo->StabStringsBase == NULL || SymbolInfo->StabStringsLength == 0)
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
@ -330,24 +429,24 @@ KdbSymGetAddressInformation(IN PIMAGE_SYMBOL_INFO SymbolInfo,
|
|||
if (LineNumber != NULL || FunctionName != NULL)
|
||||
{
|
||||
/* find stab entry for function */
|
||||
FunctionEntry = KdbpStabFindEntry(SymbolInfo, N_FUN, (PVOID)RelativeAddress, NULL);
|
||||
if (FunctionEntry == NULL)
|
||||
StabsFunctionEntry = KdbpStabFindEntry(SymbolInfo, N_FUN, (PVOID)RelativeAddress, NULL);
|
||||
if (StabsFunctionEntry == NULL)
|
||||
{
|
||||
DPRINT("No function stab entry found. RelativeAddress %p\n", RelativeAddress);
|
||||
}
|
||||
|
||||
if (LineNumber != NULL && FunctionEntry != NULL)
|
||||
if (LineNumber != NULL && StabsFunctionEntry != NULL)
|
||||
{
|
||||
/* find stab entry for line number */
|
||||
ULONG_PTR FunctionRelativeAddress = RelativeAddress - FunctionEntry->n_value;
|
||||
ULONG_PTR FunctionRelativeAddress = RelativeAddress - StabsFunctionEntry->n_value;
|
||||
ULONG_PTR AddrFound = 0;
|
||||
PSTAB_ENTRY NextLineEntry;
|
||||
|
||||
LineEntry = NextLineEntry = FunctionEntry;
|
||||
LineEntry = NextLineEntry = StabsFunctionEntry;
|
||||
while (NextLineEntry != NULL)
|
||||
{
|
||||
NextLineEntry++;
|
||||
if ((ULONG_PTR)NextLineEntry >= ((ULONG_PTR)SymbolInfo->SymbolsBase + SymbolInfo->SymbolsLength))
|
||||
if ((ULONG_PTR)NextLineEntry >= ((ULONG_PTR)SymbolInfo->StabsBase + SymbolInfo->StabsLength))
|
||||
break;
|
||||
if (NextLineEntry->n_type == N_FUN)
|
||||
break;
|
||||
|
@ -364,6 +463,14 @@ KdbSymGetAddressInformation(IN PIMAGE_SYMBOL_INFO SymbolInfo,
|
|||
}
|
||||
}
|
||||
|
||||
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 */
|
||||
|
@ -373,7 +480,7 @@ KdbSymGetAddressInformation(IN PIMAGE_SYMBOL_INFO SymbolInfo,
|
|||
FileEntry = KdbpStabFindEntry(SymbolInfo, N_SO, (PVOID)RelativeAddress, NULL);
|
||||
if (FileEntry != NULL)
|
||||
{
|
||||
p = (PCHAR)SymbolInfo->SymbolStringsBase + FileEntry->n_strx;
|
||||
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);
|
||||
|
@ -384,9 +491,10 @@ KdbSymGetAddressInformation(IN PIMAGE_SYMBOL_INFO SymbolInfo,
|
|||
}
|
||||
}
|
||||
|
||||
if (((LineNumber != NULL && LineEntry == NULL) || LineNumber == NULL) &&
|
||||
((FileName != NULL && FileEntry == NULL) || FileName == NULL) &&
|
||||
((FunctionName != NULL && FunctionEntry == NULL) || FunctionName == NULL))
|
||||
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;
|
||||
|
@ -403,18 +511,56 @@ KdbSymGetAddressInformation(IN PIMAGE_SYMBOL_INFO SymbolInfo,
|
|||
PCHAR Name = "";
|
||||
if (FileEntry != NULL)
|
||||
{
|
||||
Name = (PCHAR)SymbolInfo->SymbolStringsBase + FileEntry->n_strx;
|
||||
Name = (PCHAR)SymbolInfo->StabStringsBase + FileEntry->n_strx;
|
||||
}
|
||||
strcpy(FileName, Name);
|
||||
}
|
||||
if (FunctionName != NULL)
|
||||
{
|
||||
PCHAR Name = "", p;
|
||||
if (FunctionEntry != NULL)
|
||||
Name = (PCHAR)SymbolInfo->SymbolStringsBase + FunctionEntry->n_strx;
|
||||
strcpy(FunctionName, Name);
|
||||
if ((p = strchr(FunctionName, ':')) != NULL) /* remove extra info from function name */
|
||||
*p = '\0';
|
||||
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;
|
||||
|
@ -449,14 +595,14 @@ KdbpSymGetSourceAddress(IN PIMAGE_SYMBOL_INFO SymbolInfo,
|
|||
|
||||
FileNameLength = strlen(FileName);
|
||||
FuncNameLength = strlen(FuncName);
|
||||
for (Entry = SymbolInfo->SymbolsBase;
|
||||
(ULONG_PTR)Entry < (ULONG_PTR)(SymbolInfo->SymbolsBase + SymbolInfo->SymbolsLength);
|
||||
for (Entry = SymbolInfo->StabsBase;
|
||||
(ULONG_PTR)Entry < (ULONG_PTR)(SymbolInfo->StabsBase + SymbolInfo->StabsLength);
|
||||
Entry++)
|
||||
{
|
||||
if (Entry->n_type != N_SO)
|
||||
continue;
|
||||
|
||||
SymbolName = (PCHAR)SymbolInfo->SymbolStringsBase + Entry->n_strx;
|
||||
SymbolName = (PCHAR)SymbolInfo->StabStringsBase + Entry->n_strx;
|
||||
Length = strlen(SymbolName);
|
||||
if (SymbolName[Length - 1] == '/' ||
|
||||
SymbolName[Length - 1] == '\\')
|
||||
|
@ -473,7 +619,7 @@ KdbpSymGetSourceAddress(IN PIMAGE_SYMBOL_INFO SymbolInfo,
|
|||
continue;
|
||||
|
||||
Entry++;
|
||||
for (;(ULONG_PTR)Entry < (ULONG_PTR)(SymbolInfo->SymbolsBase + SymbolInfo->SymbolsLength);
|
||||
for (;(ULONG_PTR)Entry < (ULONG_PTR)(SymbolInfo->StabsBase + SymbolInfo->StabsLength);
|
||||
Entry++)
|
||||
{
|
||||
if (Entry->n_type == N_FUN)
|
||||
|
@ -487,7 +633,7 @@ KdbpSymGetSourceAddress(IN PIMAGE_SYMBOL_INFO SymbolInfo,
|
|||
continue;
|
||||
else /* if (FunctionName != NULL) */
|
||||
{
|
||||
SymbolName = (PCHAR)SymbolInfo->SymbolStringsBase + Entry->n_strx;
|
||||
SymbolName = (PCHAR)SymbolInfo->StabStringsBase + Entry->n_strx;
|
||||
p = strchr(SymbolName, ':');
|
||||
if (p == NULL)
|
||||
return FALSE;
|
||||
|
@ -589,6 +735,10 @@ KdbpSymAddCachedFile(IN PUNICODE_STRING FileName,
|
|||
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;
|
||||
|
@ -692,6 +842,10 @@ KdbpSymLoadModuleSymbols(IN PUNICODE_STRING FileName,
|
|||
{
|
||||
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;
|
||||
|
@ -769,16 +923,23 @@ KdbpSymLoadModuleSymbols(IN PUNICODE_STRING FileName,
|
|||
|
||||
SymbolFileHeader = (PSYMBOLFILE_HEADER) FileBuffer;
|
||||
SymbolInfo->FileBuffer = FileBuffer;
|
||||
SymbolInfo->SymbolsBase = FileBuffer + SymbolFileHeader->StabsOffset;
|
||||
SymbolInfo->SymbolsLength = SymbolFileHeader->StabsLength;
|
||||
SymbolInfo->SymbolStringsBase = FileBuffer + SymbolFileHeader->StabstrOffset;
|
||||
SymbolInfo->SymbolStringsLength = SymbolFileHeader->StabstrLength;
|
||||
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)\n",
|
||||
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);
|
||||
|
@ -800,6 +961,8 @@ KdbpSymUnloadModuleSymbols(IN PIMAGE_SYMBOL_INFO SymbolInfo)
|
|||
{
|
||||
KdbpSymRemoveCachedFile(SymbolInfo);
|
||||
SymbolInfo->FileBuffer = NULL;
|
||||
SymbolInfo->StabsBase = NULL;
|
||||
SymbolInfo->StabsLength = 0;
|
||||
SymbolInfo->SymbolsBase = NULL;
|
||||
SymbolInfo->SymbolsLength = 0;
|
||||
}
|
||||
|
@ -955,10 +1118,14 @@ KdbSymProcessBootSymbols(IN PCHAR FileName)
|
|||
KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart);
|
||||
|
||||
SymbolInfo->FileBuffer = SymbolFileHeader;
|
||||
SymbolInfo->SymbolsBase = (PVOID)SymbolFileHeader + SymbolFileHeader->StabsOffset;
|
||||
SymbolInfo->SymbolsLength = SymbolFileHeader->StabsLength;
|
||||
SymbolInfo->SymbolStringsBase = (PVOID)SymbolFileHeader + SymbolFileHeader->StabstrOffset;
|
||||
SymbolInfo->SymbolStringsLength = SymbolFileHeader->StabstrLength;
|
||||
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);
|
||||
|
@ -966,10 +1133,13 @@ KdbSymProcessBootSymbols(IN PCHAR FileName)
|
|||
KdbpSymAddCachedFile(&UnicodeString, SymbolInfo);
|
||||
RtlFreeUnicodeString(&UnicodeString);
|
||||
|
||||
DPRINT("Installed stabs: %s@%08x-%08x (%08x-%08x,%08x)\n",
|
||||
DPRINT("Installed stabs: %s@%08x-%08x (%08x-%08x,%08x) (%08x-%08x,%08x)\n",
|
||||
FileName,
|
||||
ModuleObject->Base,
|
||||
ModuleObject->Length + ModuleObject->Base,
|
||||
SymbolInfo->StabsBase,
|
||||
SymbolInfo->StabsLength + SymbolInfo->StabsBase,
|
||||
SymbolInfo->StabStringsBase,
|
||||
SymbolInfo->SymbolsBase,
|
||||
SymbolInfo->SymbolsLength + SymbolInfo->SymbolsBase,
|
||||
SymbolInfo->SymbolStringsBase);
|
||||
|
|
|
@ -111,6 +111,10 @@ typedef struct _SYMBOLFILE_HEADER {
|
|||
unsigned long StabsLength;
|
||||
unsigned long StabstrOffset;
|
||||
unsigned long StabstrLength;
|
||||
unsigned long SymbolsOffset;
|
||||
unsigned long SymbolsLength;
|
||||
unsigned long SymbolstrOffset;
|
||||
unsigned long SymbolstrLength;
|
||||
} SYMBOLFILE_HEADER, *PSYMBOLFILE_HEADER;
|
||||
|
||||
typedef struct _STAB_ENTRY {
|
||||
|
@ -133,6 +137,83 @@ typedef struct
|
|||
unsigned long Length;
|
||||
} STR_ENTRY, *PSTR_ENTRY;
|
||||
|
||||
/* COFF symbol table */
|
||||
|
||||
#define E_SYMNMLEN 8 /* # characters in a symbol name */
|
||||
#define E_FILNMLEN 14 /* # characters in a file name */
|
||||
#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
|
||||
|
||||
#define N_BTMASK (0xf)
|
||||
#define N_TMASK (0x30)
|
||||
#define N_BTSHFT (4)
|
||||
#define N_TSHIFT (2)
|
||||
|
||||
/* derived types, in e_type */
|
||||
#define DT_NON (0) /* no derived type */
|
||||
#define DT_PTR (1) /* pointer */
|
||||
#define DT_FCN (2) /* function */
|
||||
#define DT_ARY (3) /* array */
|
||||
|
||||
#define BTYPE(x) ((x) & N_BTMASK)
|
||||
|
||||
#define ISPTR(x) (((x) & N_TMASK) == (DT_PTR << N_BTSHFT))
|
||||
#define ISFCN(x) (((x) & N_TMASK) == (DT_FCN << N_BTSHFT))
|
||||
#define ISARY(x) (((x) & N_TMASK) == (DT_ARY << N_BTSHFT))
|
||||
#define ISTAG(x) ((x)==C_STRTAG||(x)==C_UNTAG||(x)==C_ENTAG)
|
||||
#define DECREF(x) ((((x)>>N_TSHIFT)&~N_BTMASK)|((x)&N_BTMASK))
|
||||
|
||||
#define C_EFCN 0xff /* physical end of function */
|
||||
#define C_NULL 0
|
||||
#define C_AUTO 1 /* automatic variable */
|
||||
#define C_EXT 2 /* external symbol */
|
||||
#define C_STAT 3 /* static */
|
||||
#define C_REG 4 /* register variable */
|
||||
#define C_EXTDEF 5 /* external definition */
|
||||
#define C_LABEL 6 /* label */
|
||||
#define C_ULABEL 7 /* undefined label */
|
||||
#define C_MOS 8 /* member of structure */
|
||||
#define C_ARG 9 /* function argument */
|
||||
#define C_STRTAG 10 /* structure tag */
|
||||
#define C_MOU 11 /* member of union */
|
||||
#define C_UNTAG 12 /* union tag */
|
||||
#define C_TPDEF 13 /* type definition */
|
||||
#define C_USTATIC 14 /* undefined static */
|
||||
#define C_ENTAG 15 /* enumeration tag */
|
||||
#define C_MOE 16 /* member of enumeration */
|
||||
#define C_REGPARM 17 /* register parameter */
|
||||
#define C_FIELD 18 /* bit field */
|
||||
#define C_AUTOARG 19 /* auto argument */
|
||||
#define C_LASTENT 20 /* dummy entry (end of block) */
|
||||
#define C_BLOCK 100 /* ".bb" or ".eb" */
|
||||
#define C_FCN 101 /* ".bf" or ".ef" */
|
||||
#define C_EOS 102 /* end of structure */
|
||||
#define C_FILE 103 /* file name */
|
||||
#define C_LINE 104 /* line # reformatted as symbol table entry */
|
||||
#define C_ALIAS 105 /* duplicate tag */
|
||||
#define C_HIDDEN 106 /* ext symbol in dmert public lib */
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct _EXTERNAL_SYMENT
|
||||
{
|
||||
union
|
||||
{
|
||||
char e_name[E_SYMNMLEN];
|
||||
struct
|
||||
{
|
||||
unsigned long e_zeroes;
|
||||
unsigned long e_offset;
|
||||
}
|
||||
e;
|
||||
}
|
||||
e;
|
||||
unsigned long e_value;
|
||||
short e_scnum;
|
||||
unsigned short e_type;
|
||||
unsigned char e_sclass;
|
||||
unsigned char e_numaux;
|
||||
} EXTERNAL_SYMENT, *PEXTERNAL_SYMENT;
|
||||
#pragma pack(pop)
|
||||
|
||||
char* convert_path(char* origpath)
|
||||
{
|
||||
char* newpath;
|
||||
|
@ -161,6 +242,52 @@ char* convert_path(char* origpath)
|
|||
return(newpath);
|
||||
}
|
||||
|
||||
static void
|
||||
RelocateString(ULONG *Offset, PSTR_ENTRY StrEntry, ULONG *StrCount, PVOID SymbolStringsBase)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
for (i = 0; i < *StrCount; i++)
|
||||
{
|
||||
if (*Offset == StrEntry[i].OldOffset)
|
||||
{
|
||||
*Offset = StrEntry[i].NewOffset;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
StrEntry[*StrCount].OldOffset = *Offset;
|
||||
StrEntry[*StrCount].Name = (char*) SymbolStringsBase + StrEntry[*StrCount].OldOffset;
|
||||
StrEntry[*StrCount].Length = strlen(StrEntry[*StrCount].Name) + 1;
|
||||
if (*StrCount == 0)
|
||||
{
|
||||
StrEntry[*StrCount].NewOffset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
StrEntry[*StrCount].NewOffset = StrEntry[*StrCount - 1].NewOffset
|
||||
+ StrEntry[*StrCount - 1].Length;
|
||||
}
|
||||
*Offset = StrEntry[*StrCount].NewOffset;
|
||||
(*StrCount)++;
|
||||
}
|
||||
|
||||
static int
|
||||
CompareSyment(const PEXTERNAL_SYMENT SymEntry1, const PEXTERNAL_SYMENT SymEntry2)
|
||||
{
|
||||
if (SymEntry1->e_value < SymEntry2->e_value)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (SymEntry2->e_value < SymEntry1->e_value)
|
||||
{
|
||||
return +1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define TRANSFER_SIZE (65536)
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
|
@ -175,6 +302,10 @@ int main(int argc, char* argv[])
|
|||
ULONG SymbolsLength;
|
||||
PVOID SymbolStringsBase;
|
||||
ULONG SymbolStringsLength;
|
||||
PVOID CoffSymbolsBase;
|
||||
ULONG CoffSymbolsLength;
|
||||
PVOID CoffSymbolStringsBase;
|
||||
ULONG CoffSymbolStringsLength;
|
||||
ULONG Idx;
|
||||
char* path1;
|
||||
char* path2;
|
||||
|
@ -188,31 +319,34 @@ int main(int argc, char* argv[])
|
|||
ULONG SymbolsCount;
|
||||
PSTR_ENTRY StrEntry;
|
||||
ULONG StrCount;
|
||||
ULONG j;
|
||||
PSTR_ENTRY CoffStrEntry;
|
||||
ULONG CoffStrCount;
|
||||
PEXTERNAL_SYMENT SymEntry;
|
||||
unsigned NumAux;
|
||||
|
||||
if (argc != 3)
|
||||
{
|
||||
fprintf(stderr, "Too many arguments\n");
|
||||
exit(1);
|
||||
}
|
||||
if (argc != 3)
|
||||
{
|
||||
fprintf(stderr, "Too many arguments\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
path1 = convert_path(argv[1]);
|
||||
path2 = convert_path(argv[2]);
|
||||
path1 = convert_path(argv[1]);
|
||||
path2 = convert_path(argv[2]);
|
||||
|
||||
in = fopen(path1, "rb");
|
||||
if (in == NULL)
|
||||
{
|
||||
perror("Cannot open input file");
|
||||
exit(1);
|
||||
}
|
||||
in = fopen(path1, "rb");
|
||||
if (in == NULL)
|
||||
{
|
||||
perror("Cannot open input file");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
out = fopen(path2, "wb");
|
||||
if (out == NULL)
|
||||
{
|
||||
perror("Cannot open output file");
|
||||
fclose(in);
|
||||
exit(1);
|
||||
}
|
||||
out = fopen(path2, "wb");
|
||||
if (out == NULL)
|
||||
{
|
||||
perror("Cannot open output file");
|
||||
fclose(in);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Check if MZ header exists */
|
||||
n_in = fread(&PEDosHeader, 1, sizeof(PEDosHeader), in);
|
||||
|
@ -302,30 +436,7 @@ int main(int argc, char* argv[])
|
|||
|
||||
for (i = 0; i < Count; i++)
|
||||
{
|
||||
for (j = 0; j < StrCount; j++)
|
||||
{
|
||||
if (StabEntry[i].n_strx == StrEntry[j].OldOffset)
|
||||
{
|
||||
StabEntry[i].n_strx = StrEntry[j].NewOffset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j >= StrCount)
|
||||
{
|
||||
StrEntry[StrCount].OldOffset = StabEntry[i].n_strx;
|
||||
StrEntry[StrCount].Name = (char*)SymbolStringsBase + StrEntry[StrCount].OldOffset;
|
||||
StrEntry[StrCount].Length = strlen(StrEntry[StrCount].Name) + 1;
|
||||
if (StrCount == 0)
|
||||
{
|
||||
StrEntry[StrCount].NewOffset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
StrEntry[StrCount].NewOffset = StrEntry[StrCount-1].NewOffset + StrEntry[StrCount-1].Length;
|
||||
}
|
||||
StabEntry[i].n_strx = StrEntry[StrCount].NewOffset;
|
||||
StrCount++;
|
||||
}
|
||||
RelocateString(&StabEntry[i].n_strx, StrEntry, &StrCount, SymbolStringsBase);
|
||||
}
|
||||
|
||||
SymbolFileHeader.StabsOffset = sizeof(SYMBOLFILE_HEADER);
|
||||
|
@ -333,12 +444,93 @@ int main(int argc, char* argv[])
|
|||
SymbolFileHeader.StabstrOffset = SymbolFileHeader.StabsOffset + SymbolFileHeader.StabsLength;
|
||||
SymbolFileHeader.StabstrLength = StrEntry[StrCount-1].NewOffset + StrEntry[StrCount-1].Length;
|
||||
|
||||
if (0 == PEFileHeader.PointerToSymbolTable || 0 == PEFileHeader.NumberOfSymbols)
|
||||
{
|
||||
/* No COFF symbol table */
|
||||
SymbolFileHeader.SymbolsOffset = 0;
|
||||
SymbolFileHeader.SymbolsLength = 0;
|
||||
SymbolFileHeader.SymbolstrOffset = 0;
|
||||
SymbolFileHeader.SymbolstrLength = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
CoffSymbolsLength = PEFileHeader.NumberOfSymbols * sizeof(EXTERNAL_SYMENT);
|
||||
CoffSymbolsBase = malloc(CoffSymbolsLength);
|
||||
if (NULL == CoffSymbolsBase)
|
||||
{
|
||||
fprintf(stderr, "Unable to allocate %u bytes for COFF symbols\n",
|
||||
(unsigned) CoffSymbolsLength);
|
||||
exit(1);
|
||||
}
|
||||
fseek(in, PEFileHeader.PointerToSymbolTable, SEEK_SET);
|
||||
n_in = fread(CoffSymbolsBase, 1, CoffSymbolsLength, in);
|
||||
|
||||
SymEntry = CoffSymbolsBase;
|
||||
Count = 0;
|
||||
for (i = 0; i < PEFileHeader.NumberOfSymbols; i++)
|
||||
{
|
||||
NumAux = SymEntry[i].e_numaux;
|
||||
if (ISFCN(SymEntry[i].e_type))
|
||||
{
|
||||
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++;
|
||||
}
|
||||
i += NumAux;
|
||||
}
|
||||
|
||||
qsort(CoffSymbolsBase, Count, sizeof(EXTERNAL_SYMENT), (int (*)(const void *, const void *)) CompareSyment);
|
||||
|
||||
n_in = fread(&CoffSymbolStringsLength, 1, sizeof(ULONG), in);
|
||||
CoffSymbolStringsBase = malloc(CoffSymbolStringsLength);
|
||||
if (NULL == CoffSymbolStringsBase)
|
||||
{
|
||||
fprintf(stderr, "Unable to allocate %u bytes for COFF symbol strings\n",
|
||||
(unsigned) CoffSymbolStringsLength);
|
||||
exit(1);
|
||||
}
|
||||
n_in = fread((char *) CoffSymbolStringsBase + sizeof(ULONG), 1, CoffSymbolStringsLength - 4, in);
|
||||
|
||||
CoffStrEntry = malloc(sizeof(STR_ENTRY) * Count);
|
||||
CoffStrCount = 0;
|
||||
|
||||
for (i = 0; i < Count; i++)
|
||||
{
|
||||
if (0 == SymEntry[i].e.e.e_zeroes)
|
||||
{
|
||||
RelocateString(&SymEntry[i].e.e.e_offset, CoffStrEntry, &CoffStrCount, CoffSymbolStringsBase);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
n_out = fwrite(&SymbolFileHeader, 1, sizeof(SYMBOLFILE_HEADER), out);
|
||||
n_out = fwrite(SymbolsBase, 1, SymbolFileHeader.StabsLength, out);
|
||||
for (i = 0; i < StrCount; i++)
|
||||
{
|
||||
fwrite(StrEntry[i].Name, 1, StrEntry[i].Length, out);
|
||||
}
|
||||
n_out = fwrite(CoffSymbolsBase, 1, SymbolFileHeader.SymbolsLength, out);
|
||||
for (i = 0; i < CoffStrCount; i++)
|
||||
{
|
||||
fwrite(CoffStrEntry[i].Name, 1, CoffStrEntry[i].Length, out);
|
||||
}
|
||||
|
||||
fclose(out);
|
||||
exit(0);
|
||||
|
|
Loading…
Reference in a new issue