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" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* #ifndef __dj_ENFORCE_ANSI_FREESTANDING
|
|
||||||
* #ifndef __STRICT_ANSI__
|
|
||||||
* #ifndef _POSIX_SOURCE
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*** coff information for Intel 386/486. */
|
/*** coff information for Intel 386/486. */
|
||||||
|
|
||||||
/********************** FILE HEADER **********************/
|
/********************** FILE HEADER **********************/
|
||||||
|
@ -329,13 +323,6 @@ struct external_reloc {
|
||||||
/* For new sections we havn't heard of before */
|
/* For new sections we havn't heard of before */
|
||||||
#define DEFAULT_SECTION_ALIGNMENT 4
|
#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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,10 @@ typedef struct _IMAGE_SYMBOL_INFO
|
||||||
ULONG_PTR ImageBase;
|
ULONG_PTR ImageBase;
|
||||||
ULONG_PTR ImageSize;
|
ULONG_PTR ImageSize;
|
||||||
PVOID FileBuffer;
|
PVOID FileBuffer;
|
||||||
|
PVOID StabsBase;
|
||||||
|
ULONG StabsLength;
|
||||||
|
PVOID StabStringsBase;
|
||||||
|
ULONG StabStringsLength;
|
||||||
PVOID SymbolsBase;
|
PVOID SymbolsBase;
|
||||||
ULONG SymbolsLength;
|
ULONG SymbolsLength;
|
||||||
PVOID SymbolStringsBase;
|
PVOID SymbolStringsBase;
|
||||||
|
|
|
@ -69,8 +69,8 @@ KdbpStabFindEntry(IN PIMAGE_SYMBOL_INFO SymbolInfo,
|
||||||
PVOID StabsEnd;
|
PVOID StabsEnd;
|
||||||
ULONG_PTR AddrFound = 0;
|
ULONG_PTR AddrFound = 0;
|
||||||
|
|
||||||
StabEntry = SymbolInfo->SymbolsBase;
|
StabEntry = SymbolInfo->StabsBase;
|
||||||
StabsEnd = (PVOID)((ULONG_PTR)SymbolInfo->SymbolsBase + SymbolInfo->SymbolsLength);
|
StabsEnd = (PVOID)((ULONG_PTR)SymbolInfo->StabsBase + SymbolInfo->StabsLength);
|
||||||
if (StartEntry != NULL)
|
if (StartEntry != NULL)
|
||||||
{
|
{
|
||||||
ASSERT((ULONG_PTR)StartEntry >= (ULONG_PTR)StabEntry);
|
ASSERT((ULONG_PTR)StartEntry >= (ULONG_PTR)StabEntry);
|
||||||
|
|
|
@ -16,6 +16,34 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/dbg/kdb_symbols.c
|
* FILE: ntoskrnl/dbg/kdb_symbols.c
|
||||||
|
@ -41,6 +69,7 @@
|
||||||
#include <internal/safe.h>
|
#include <internal/safe.h>
|
||||||
#include <internal/kd.h>
|
#include <internal/kd.h>
|
||||||
#include <rosrtl/string.h>
|
#include <rosrtl/string.h>
|
||||||
|
#include <coff.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
@ -55,6 +84,10 @@ typedef struct _SYMBOLFILE_HEADER {
|
||||||
ULONG StabsLength;
|
ULONG StabsLength;
|
||||||
ULONG StabstrOffset;
|
ULONG StabstrOffset;
|
||||||
ULONG StabstrLength;
|
ULONG StabstrLength;
|
||||||
|
ULONG SymbolsOffset;
|
||||||
|
ULONG SymbolsLength;
|
||||||
|
ULONG SymbolstrOffset;
|
||||||
|
ULONG SymbolstrLength;
|
||||||
} SYMBOLFILE_HEADER, *PSYMBOLFILE_HEADER;
|
} SYMBOLFILE_HEADER, *PSYMBOLFILE_HEADER;
|
||||||
|
|
||||||
typedef struct _IMAGE_SYMBOL_INFO_CACHE {
|
typedef struct _IMAGE_SYMBOL_INFO_CACHE {
|
||||||
|
@ -62,6 +95,10 @@ typedef struct _IMAGE_SYMBOL_INFO_CACHE {
|
||||||
ULONG RefCount;
|
ULONG RefCount;
|
||||||
UNICODE_STRING FileName;
|
UNICODE_STRING FileName;
|
||||||
PVOID FileBuffer;
|
PVOID FileBuffer;
|
||||||
|
PVOID StabsBase;
|
||||||
|
ULONG StabsLength;
|
||||||
|
PVOID StabStringsBase;
|
||||||
|
ULONG StabStringsLength;
|
||||||
PVOID SymbolsBase;
|
PVOID SymbolsBase;
|
||||||
ULONG SymbolsLength;
|
ULONG SymbolsLength;
|
||||||
PVOID SymbolStringsBase;
|
PVOID SymbolStringsBase;
|
||||||
|
@ -282,6 +319,67 @@ KdbSymPrintAddress(IN PVOID Address)
|
||||||
return TRUE;
|
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,
|
/*! \brief Get information for an address (source file, line number,
|
||||||
* function name)
|
* function name)
|
||||||
|
@ -306,12 +404,13 @@ KdbSymGetAddressInformation(IN PIMAGE_SYMBOL_INFO SymbolInfo,
|
||||||
OUT PCH FileName OPTIONAL,
|
OUT PCH FileName OPTIONAL,
|
||||||
OUT PCH FunctionName 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);
|
DPRINT("RelativeAddress = 0x%08x\n", RelativeAddress);
|
||||||
|
|
||||||
if (SymbolInfo->SymbolsBase == NULL || SymbolInfo->SymbolsLength == 0 ||
|
if (SymbolInfo->StabsBase == NULL || SymbolInfo->StabsLength == 0 ||
|
||||||
SymbolInfo->SymbolStringsBase == NULL || SymbolInfo->SymbolStringsLength == 0)
|
SymbolInfo->StabStringsBase == NULL || SymbolInfo->StabStringsLength == 0)
|
||||||
{
|
{
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
@ -330,24 +429,24 @@ KdbSymGetAddressInformation(IN PIMAGE_SYMBOL_INFO SymbolInfo,
|
||||||
if (LineNumber != NULL || FunctionName != NULL)
|
if (LineNumber != NULL || FunctionName != NULL)
|
||||||
{
|
{
|
||||||
/* find stab entry for function */
|
/* find stab entry for function */
|
||||||
FunctionEntry = KdbpStabFindEntry(SymbolInfo, N_FUN, (PVOID)RelativeAddress, NULL);
|
StabsFunctionEntry = KdbpStabFindEntry(SymbolInfo, N_FUN, (PVOID)RelativeAddress, NULL);
|
||||||
if (FunctionEntry == NULL)
|
if (StabsFunctionEntry == NULL)
|
||||||
{
|
{
|
||||||
DPRINT("No function stab entry found. RelativeAddress %p\n", RelativeAddress);
|
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 */
|
/* find stab entry for line number */
|
||||||
ULONG_PTR FunctionRelativeAddress = RelativeAddress - FunctionEntry->n_value;
|
ULONG_PTR FunctionRelativeAddress = RelativeAddress - StabsFunctionEntry->n_value;
|
||||||
ULONG_PTR AddrFound = 0;
|
ULONG_PTR AddrFound = 0;
|
||||||
PSTAB_ENTRY NextLineEntry;
|
PSTAB_ENTRY NextLineEntry;
|
||||||
|
|
||||||
LineEntry = NextLineEntry = FunctionEntry;
|
LineEntry = NextLineEntry = StabsFunctionEntry;
|
||||||
while (NextLineEntry != NULL)
|
while (NextLineEntry != NULL)
|
||||||
{
|
{
|
||||||
NextLineEntry++;
|
NextLineEntry++;
|
||||||
if ((ULONG_PTR)NextLineEntry >= ((ULONG_PTR)SymbolInfo->SymbolsBase + SymbolInfo->SymbolsLength))
|
if ((ULONG_PTR)NextLineEntry >= ((ULONG_PTR)SymbolInfo->StabsBase + SymbolInfo->StabsLength))
|
||||||
break;
|
break;
|
||||||
if (NextLineEntry->n_type == N_FUN)
|
if (NextLineEntry->n_type == N_FUN)
|
||||||
break;
|
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)
|
if (FileName != NULL)
|
||||||
{
|
{
|
||||||
/* find stab entry for file name */
|
/* find stab entry for file name */
|
||||||
|
@ -373,7 +480,7 @@ KdbSymGetAddressInformation(IN PIMAGE_SYMBOL_INFO SymbolInfo,
|
||||||
FileEntry = KdbpStabFindEntry(SymbolInfo, N_SO, (PVOID)RelativeAddress, NULL);
|
FileEntry = KdbpStabFindEntry(SymbolInfo, N_SO, (PVOID)RelativeAddress, NULL);
|
||||||
if (FileEntry != NULL)
|
if (FileEntry != NULL)
|
||||||
{
|
{
|
||||||
p = (PCHAR)SymbolInfo->SymbolStringsBase + FileEntry->n_strx;
|
p = (PCHAR)SymbolInfo->StabStringsBase + FileEntry->n_strx;
|
||||||
Length = strlen(p);
|
Length = strlen(p);
|
||||||
if (p[Length - 1] == '/' || p[Length - 1] == '\\') /* source dir */
|
if (p[Length - 1] == '/' || p[Length - 1] == '\\') /* source dir */
|
||||||
FileEntry = KdbpStabFindEntry(SymbolInfo, N_SO, (PVOID)RelativeAddress, FileEntry + 1);
|
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) &&
|
if (((LineNumber != NULL && LineEntry == NULL) || LineNumber == NULL) &&
|
||||||
((FileName != NULL && FileEntry == NULL) || FileName == NULL) &&
|
((FileName != NULL && FileEntry == NULL) || FileName == NULL) &&
|
||||||
((FunctionName != NULL && FunctionEntry == NULL) || FunctionName == NULL))
|
((FunctionName != NULL && StabsFunctionEntry == NULL && SymbolsFunctionEntry == NULL) ||
|
||||||
|
FunctionName == NULL))
|
||||||
{
|
{
|
||||||
DPRINT("None of the requested information was found!\n");
|
DPRINT("None of the requested information was found!\n");
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
@ -403,18 +511,56 @@ KdbSymGetAddressInformation(IN PIMAGE_SYMBOL_INFO SymbolInfo,
|
||||||
PCHAR Name = "";
|
PCHAR Name = "";
|
||||||
if (FileEntry != NULL)
|
if (FileEntry != NULL)
|
||||||
{
|
{
|
||||||
Name = (PCHAR)SymbolInfo->SymbolStringsBase + FileEntry->n_strx;
|
Name = (PCHAR)SymbolInfo->StabStringsBase + FileEntry->n_strx;
|
||||||
}
|
}
|
||||||
strcpy(FileName, Name);
|
strcpy(FileName, Name);
|
||||||
}
|
}
|
||||||
if (FunctionName != NULL)
|
if (FunctionName != NULL)
|
||||||
{
|
{
|
||||||
PCHAR Name = "", p;
|
PCHAR Name = "", p;
|
||||||
if (FunctionEntry != NULL)
|
if (StabsFunctionEntry != NULL)
|
||||||
Name = (PCHAR)SymbolInfo->SymbolStringsBase + FunctionEntry->n_strx;
|
{
|
||||||
strcpy(FunctionName, Name);
|
if (SymbolsFunctionEntry == NULL ||
|
||||||
if ((p = strchr(FunctionName, ':')) != NULL) /* remove extra info from function name */
|
SymbolsFunctionEntry->e_value <= StabsFunctionEntry->n_value)
|
||||||
*p = '\0';
|
{
|
||||||
|
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;
|
return STATUS_SUCCESS;
|
||||||
|
@ -449,14 +595,14 @@ KdbpSymGetSourceAddress(IN PIMAGE_SYMBOL_INFO SymbolInfo,
|
||||||
|
|
||||||
FileNameLength = strlen(FileName);
|
FileNameLength = strlen(FileName);
|
||||||
FuncNameLength = strlen(FuncName);
|
FuncNameLength = strlen(FuncName);
|
||||||
for (Entry = SymbolInfo->SymbolsBase;
|
for (Entry = SymbolInfo->StabsBase;
|
||||||
(ULONG_PTR)Entry < (ULONG_PTR)(SymbolInfo->SymbolsBase + SymbolInfo->SymbolsLength);
|
(ULONG_PTR)Entry < (ULONG_PTR)(SymbolInfo->StabsBase + SymbolInfo->StabsLength);
|
||||||
Entry++)
|
Entry++)
|
||||||
{
|
{
|
||||||
if (Entry->n_type != N_SO)
|
if (Entry->n_type != N_SO)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
SymbolName = (PCHAR)SymbolInfo->SymbolStringsBase + Entry->n_strx;
|
SymbolName = (PCHAR)SymbolInfo->StabStringsBase + Entry->n_strx;
|
||||||
Length = strlen(SymbolName);
|
Length = strlen(SymbolName);
|
||||||
if (SymbolName[Length - 1] == '/' ||
|
if (SymbolName[Length - 1] == '/' ||
|
||||||
SymbolName[Length - 1] == '\\')
|
SymbolName[Length - 1] == '\\')
|
||||||
|
@ -473,7 +619,7 @@ KdbpSymGetSourceAddress(IN PIMAGE_SYMBOL_INFO SymbolInfo,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Entry++;
|
Entry++;
|
||||||
for (;(ULONG_PTR)Entry < (ULONG_PTR)(SymbolInfo->SymbolsBase + SymbolInfo->SymbolsLength);
|
for (;(ULONG_PTR)Entry < (ULONG_PTR)(SymbolInfo->StabsBase + SymbolInfo->StabsLength);
|
||||||
Entry++)
|
Entry++)
|
||||||
{
|
{
|
||||||
if (Entry->n_type == N_FUN)
|
if (Entry->n_type == N_FUN)
|
||||||
|
@ -487,7 +633,7 @@ KdbpSymGetSourceAddress(IN PIMAGE_SYMBOL_INFO SymbolInfo,
|
||||||
continue;
|
continue;
|
||||||
else /* if (FunctionName != NULL) */
|
else /* if (FunctionName != NULL) */
|
||||||
{
|
{
|
||||||
SymbolName = (PCHAR)SymbolInfo->SymbolStringsBase + Entry->n_strx;
|
SymbolName = (PCHAR)SymbolInfo->StabStringsBase + Entry->n_strx;
|
||||||
p = strchr(SymbolName, ':');
|
p = strchr(SymbolName, ':');
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -589,6 +735,10 @@ KdbpSymAddCachedFile(IN PUNICODE_STRING FileName,
|
||||||
ASSERT(CacheEntry->FileName.Buffer);
|
ASSERT(CacheEntry->FileName.Buffer);
|
||||||
CacheEntry->RefCount = 1;
|
CacheEntry->RefCount = 1;
|
||||||
CacheEntry->FileBuffer = SymbolInfo->FileBuffer;
|
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->SymbolsBase = SymbolInfo->SymbolsBase;
|
||||||
CacheEntry->SymbolsLength = SymbolInfo->SymbolsLength;
|
CacheEntry->SymbolsLength = SymbolInfo->SymbolsLength;
|
||||||
CacheEntry->SymbolStringsBase = SymbolInfo->SymbolStringsBase;
|
CacheEntry->SymbolStringsBase = SymbolInfo->SymbolStringsBase;
|
||||||
|
@ -692,6 +842,10 @@ KdbpSymLoadModuleSymbols(IN PUNICODE_STRING FileName,
|
||||||
{
|
{
|
||||||
DPRINT("Found cached symbol file %wZ\n", &SymFileName);
|
DPRINT("Found cached symbol file %wZ\n", &SymFileName);
|
||||||
SymbolInfo->FileBuffer = CachedSymbolFile->FileBuffer;
|
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->SymbolsBase = CachedSymbolFile->SymbolsBase;
|
||||||
SymbolInfo->SymbolsLength = CachedSymbolFile->SymbolsLength;
|
SymbolInfo->SymbolsLength = CachedSymbolFile->SymbolsLength;
|
||||||
SymbolInfo->SymbolStringsBase = CachedSymbolFile->SymbolStringsBase;
|
SymbolInfo->SymbolStringsBase = CachedSymbolFile->SymbolStringsBase;
|
||||||
|
@ -769,16 +923,23 @@ KdbpSymLoadModuleSymbols(IN PUNICODE_STRING FileName,
|
||||||
|
|
||||||
SymbolFileHeader = (PSYMBOLFILE_HEADER) FileBuffer;
|
SymbolFileHeader = (PSYMBOLFILE_HEADER) FileBuffer;
|
||||||
SymbolInfo->FileBuffer = FileBuffer;
|
SymbolInfo->FileBuffer = FileBuffer;
|
||||||
SymbolInfo->SymbolsBase = FileBuffer + SymbolFileHeader->StabsOffset;
|
SymbolInfo->StabsBase = FileBuffer + SymbolFileHeader->StabsOffset;
|
||||||
SymbolInfo->SymbolsLength = SymbolFileHeader->StabsLength;
|
SymbolInfo->StabsLength = SymbolFileHeader->StabsLength;
|
||||||
SymbolInfo->SymbolStringsBase = FileBuffer + SymbolFileHeader->StabstrOffset;
|
SymbolInfo->StabStringsBase = FileBuffer + SymbolFileHeader->StabstrOffset;
|
||||||
SymbolInfo->SymbolStringsLength = SymbolFileHeader->StabstrLength;
|
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 */
|
/* add file to cache */
|
||||||
KdbpSymAddCachedFile(&SymFileName, SymbolInfo);
|
KdbpSymAddCachedFile(&SymFileName, SymbolInfo);
|
||||||
|
|
||||||
DPRINT("Installed stabs: %wZ (%08x-%08x,%08x)\n",
|
DPRINT("Installed stabs: %wZ (%08x-%08x,%08x) (%08x-%08x,%08x)\n",
|
||||||
FileName,
|
FileName,
|
||||||
|
SymbolInfo->StabsBase,
|
||||||
|
SymbolInfo->StabsLength + SymbolInfo->StabsBase,
|
||||||
|
SymbolInfo->StabStringsBase,
|
||||||
SymbolInfo->SymbolsBase,
|
SymbolInfo->SymbolsBase,
|
||||||
SymbolInfo->SymbolsLength + SymbolInfo->SymbolsBase,
|
SymbolInfo->SymbolsLength + SymbolInfo->SymbolsBase,
|
||||||
SymbolInfo->SymbolStringsBase);
|
SymbolInfo->SymbolStringsBase);
|
||||||
|
@ -800,6 +961,8 @@ KdbpSymUnloadModuleSymbols(IN PIMAGE_SYMBOL_INFO SymbolInfo)
|
||||||
{
|
{
|
||||||
KdbpSymRemoveCachedFile(SymbolInfo);
|
KdbpSymRemoveCachedFile(SymbolInfo);
|
||||||
SymbolInfo->FileBuffer = NULL;
|
SymbolInfo->FileBuffer = NULL;
|
||||||
|
SymbolInfo->StabsBase = NULL;
|
||||||
|
SymbolInfo->StabsLength = 0;
|
||||||
SymbolInfo->SymbolsBase = NULL;
|
SymbolInfo->SymbolsBase = NULL;
|
||||||
SymbolInfo->SymbolsLength = 0;
|
SymbolInfo->SymbolsLength = 0;
|
||||||
}
|
}
|
||||||
|
@ -955,10 +1118,14 @@ KdbSymProcessBootSymbols(IN PCHAR FileName)
|
||||||
KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart);
|
KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart);
|
||||||
|
|
||||||
SymbolInfo->FileBuffer = SymbolFileHeader;
|
SymbolInfo->FileBuffer = SymbolFileHeader;
|
||||||
SymbolInfo->SymbolsBase = (PVOID)SymbolFileHeader + SymbolFileHeader->StabsOffset;
|
SymbolInfo->StabsBase = (PVOID)SymbolFileHeader + SymbolFileHeader->StabsOffset;
|
||||||
SymbolInfo->SymbolsLength = SymbolFileHeader->StabsLength;
|
SymbolInfo->StabsLength = SymbolFileHeader->StabsLength;
|
||||||
SymbolInfo->SymbolStringsBase = (PVOID)SymbolFileHeader + SymbolFileHeader->StabstrOffset;
|
SymbolInfo->StabStringsBase = (PVOID)SymbolFileHeader + SymbolFileHeader->StabstrOffset;
|
||||||
SymbolInfo->SymbolStringsLength = SymbolFileHeader->StabstrLength;
|
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 */
|
/* add file to cache */
|
||||||
RtlInitAnsiString(&AnsiString, SymbolName);
|
RtlInitAnsiString(&AnsiString, SymbolName);
|
||||||
|
@ -966,10 +1133,13 @@ KdbSymProcessBootSymbols(IN PCHAR FileName)
|
||||||
KdbpSymAddCachedFile(&UnicodeString, SymbolInfo);
|
KdbpSymAddCachedFile(&UnicodeString, SymbolInfo);
|
||||||
RtlFreeUnicodeString(&UnicodeString);
|
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,
|
FileName,
|
||||||
ModuleObject->Base,
|
ModuleObject->Base,
|
||||||
ModuleObject->Length + ModuleObject->Base,
|
ModuleObject->Length + ModuleObject->Base,
|
||||||
|
SymbolInfo->StabsBase,
|
||||||
|
SymbolInfo->StabsLength + SymbolInfo->StabsBase,
|
||||||
|
SymbolInfo->StabStringsBase,
|
||||||
SymbolInfo->SymbolsBase,
|
SymbolInfo->SymbolsBase,
|
||||||
SymbolInfo->SymbolsLength + SymbolInfo->SymbolsBase,
|
SymbolInfo->SymbolsLength + SymbolInfo->SymbolsBase,
|
||||||
SymbolInfo->SymbolStringsBase);
|
SymbolInfo->SymbolStringsBase);
|
||||||
|
|
|
@ -111,6 +111,10 @@ typedef struct _SYMBOLFILE_HEADER {
|
||||||
unsigned long StabsLength;
|
unsigned long StabsLength;
|
||||||
unsigned long StabstrOffset;
|
unsigned long StabstrOffset;
|
||||||
unsigned long StabstrLength;
|
unsigned long StabstrLength;
|
||||||
|
unsigned long SymbolsOffset;
|
||||||
|
unsigned long SymbolsLength;
|
||||||
|
unsigned long SymbolstrOffset;
|
||||||
|
unsigned long SymbolstrLength;
|
||||||
} SYMBOLFILE_HEADER, *PSYMBOLFILE_HEADER;
|
} SYMBOLFILE_HEADER, *PSYMBOLFILE_HEADER;
|
||||||
|
|
||||||
typedef struct _STAB_ENTRY {
|
typedef struct _STAB_ENTRY {
|
||||||
|
@ -133,6 +137,83 @@ typedef struct
|
||||||
unsigned long Length;
|
unsigned long Length;
|
||||||
} STR_ENTRY, *PSTR_ENTRY;
|
} 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* convert_path(char* origpath)
|
||||||
{
|
{
|
||||||
char* newpath;
|
char* newpath;
|
||||||
|
@ -161,6 +242,52 @@ char* convert_path(char* origpath)
|
||||||
return(newpath);
|
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)
|
#define TRANSFER_SIZE (65536)
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
|
@ -175,6 +302,10 @@ int main(int argc, char* argv[])
|
||||||
ULONG SymbolsLength;
|
ULONG SymbolsLength;
|
||||||
PVOID SymbolStringsBase;
|
PVOID SymbolStringsBase;
|
||||||
ULONG SymbolStringsLength;
|
ULONG SymbolStringsLength;
|
||||||
|
PVOID CoffSymbolsBase;
|
||||||
|
ULONG CoffSymbolsLength;
|
||||||
|
PVOID CoffSymbolStringsBase;
|
||||||
|
ULONG CoffSymbolStringsLength;
|
||||||
ULONG Idx;
|
ULONG Idx;
|
||||||
char* path1;
|
char* path1;
|
||||||
char* path2;
|
char* path2;
|
||||||
|
@ -188,31 +319,34 @@ int main(int argc, char* argv[])
|
||||||
ULONG SymbolsCount;
|
ULONG SymbolsCount;
|
||||||
PSTR_ENTRY StrEntry;
|
PSTR_ENTRY StrEntry;
|
||||||
ULONG StrCount;
|
ULONG StrCount;
|
||||||
ULONG j;
|
PSTR_ENTRY CoffStrEntry;
|
||||||
|
ULONG CoffStrCount;
|
||||||
|
PEXTERNAL_SYMENT SymEntry;
|
||||||
|
unsigned NumAux;
|
||||||
|
|
||||||
if (argc != 3)
|
if (argc != 3)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Too many arguments\n");
|
fprintf(stderr, "Too many arguments\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
path1 = convert_path(argv[1]);
|
path1 = convert_path(argv[1]);
|
||||||
path2 = convert_path(argv[2]);
|
path2 = convert_path(argv[2]);
|
||||||
|
|
||||||
in = fopen(path1, "rb");
|
in = fopen(path1, "rb");
|
||||||
if (in == NULL)
|
if (in == NULL)
|
||||||
{
|
{
|
||||||
perror("Cannot open input file");
|
perror("Cannot open input file");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
out = fopen(path2, "wb");
|
out = fopen(path2, "wb");
|
||||||
if (out == NULL)
|
if (out == NULL)
|
||||||
{
|
{
|
||||||
perror("Cannot open output file");
|
perror("Cannot open output file");
|
||||||
fclose(in);
|
fclose(in);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if MZ header exists */
|
/* Check if MZ header exists */
|
||||||
n_in = fread(&PEDosHeader, 1, sizeof(PEDosHeader), in);
|
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 (i = 0; i < Count; i++)
|
||||||
{
|
{
|
||||||
for (j = 0; j < StrCount; j++)
|
RelocateString(&StabEntry[i].n_strx, StrEntry, &StrCount, SymbolStringsBase);
|
||||||
{
|
|
||||||
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++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SymbolFileHeader.StabsOffset = sizeof(SYMBOLFILE_HEADER);
|
SymbolFileHeader.StabsOffset = sizeof(SYMBOLFILE_HEADER);
|
||||||
|
@ -333,12 +444,93 @@ int main(int argc, char* argv[])
|
||||||
SymbolFileHeader.StabstrOffset = SymbolFileHeader.StabsOffset + SymbolFileHeader.StabsLength;
|
SymbolFileHeader.StabstrOffset = SymbolFileHeader.StabsOffset + SymbolFileHeader.StabsLength;
|
||||||
SymbolFileHeader.StabstrLength = StrEntry[StrCount-1].NewOffset + StrEntry[StrCount-1].Length;
|
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(&SymbolFileHeader, 1, sizeof(SYMBOLFILE_HEADER), out);
|
||||||
n_out = fwrite(SymbolsBase, 1, SymbolFileHeader.StabsLength, out);
|
n_out = fwrite(SymbolsBase, 1, SymbolFileHeader.StabsLength, out);
|
||||||
for (i = 0; i < StrCount; i++)
|
for (i = 0; i < StrCount; i++)
|
||||||
{
|
{
|
||||||
fwrite(StrEntry[i].Name, 1, StrEntry[i].Length, out);
|
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);
|
fclose(out);
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
Loading…
Reference in a new issue