reactos/reactos/tools/rsym.c

254 lines
6.2 KiB
C
Raw Normal View History

2002-07-13 Casper S. Hornstrup <chorns@users.sourceforge.net> * rules.mak (RSYM): Define. * include/ddk/zwtypes.h (DebugDbgLoadSymbols): Add to enum _DEBUG_CONTROL_CODE. * include/ntdll/ldr.h (LDR_SYMBOL_INFO, LdrpLoadUserModuleSymbols): Add. (LdrLoadModuleSymbols): Remove. * include/ntos/kdbgsyms.h (ST_FILENAME, ST_FUNCTION, ST_LINENUMBER): Add. (SYMBOL). Make Name an ANSI_STRING. (IMAGE_SYMBOL_INFO, AreSymbolsParsed): Add. * lib/ntdll/ldr/startup.c (LdrInitializeThunk): Call LdrpLoadUserModuleSymbols() not LdrLoadModuleSymbols(). * lib/ntdll/ldr/utils.c (LdrLoadModuleSymbols): Rename to LdrpLoadUserModuleSymbols. (LdrpLoadUserModuleSymbols): Use DebugDbgLoadSymbols debug control code. (LdrLoadDll): assert if out of memory. (LdrLoadDll): Call LdrpLoadUserModuleSymbols(), not LdrLoadModuleSymbols(). * lib/ntdll/string/ctype.c (_pctype): #undef. * ntoskrnl/dbg/dbgctrl.c (NtSystemDebugControl): Call LdrLoadUserModuleSymbols on DebugDbgLoadSymbols. * ntoskrnl/include/internal/ldr.h (LdrGetAddressInformation): Add. * ntoskrnl/include/internal/module.h (MODULE_TEXT_SECTION): Make SymbolInfo an IMAGE_SYMBOL_INFO. * ntoskrnl/ke/i386/exp.c (LdrGetAddressInformation): Add prototype. (print_address): Change #ifdef KDBG to #ifdef DBG. (KiDoubleFaultHandler, KiDumpTrapFrame, KeDumpStackFrames): Dump one stack frame per line. * ntoskrnl/ke/i386/multiboot.S: Create pagetables for more kernel address space so larger modules can be passed from the boot loader. * ntoskrnl/ke/i386/usertrap.c (LdrGetAddressInformation): Add prototype. (print_user_address): Print symbols using LdrGetAddressInformation(). * ntoskrnl/ldr/loader.c (SYMBOLFILE_HEADER, IMAGE_SYMBOL_INFO_CACHE, STAB_ENTRY, N_FUN, N_SLINE, N_SO, SymbolListHead): Add. (TAG_SYM_BUF): Remove. (LdrInitDebug): Remove unneeded code. (LdrInit1): Prepare for loading symbols. (LdrpReadLine, HexL, LdrpParseLine, LdrpLoadModuleSymbolsFromBuffer, LdrpLoadUserModuleSymbolsFromBuffer): Remove. (LdrpParseImageSymbols, LdrpGetFileName, LdrpGetFunctionName, LdrpGetLineNumber, LdrGetAddressInformation, LdrpLookupUserSymbolInfo): Add. (LdrpLoadModuleSymbols, LdrInitializeBootStartDriver): Change to use new symbol structures. (LdrLoadUserModuleSymbols): Cache symbol buffers. (LdrUnloadModuleSymbols): Implement. (LdrLoadModule, LdrUnloadModule): Change #ifdef KDBG to #ifdef DBG. (LdrPEProcessModule): Split a line into two lines. (LdrPEProcessModule): Setup for loading symbols. * ntoskrnl/ldr/sysdll.c (LdrpMapSystemDll): Open with FILE_SHARE_READ. * ntoskrnl/ps/process.c (PiFreeSymbols): Call LdrUnloadModuleSymbols() to free symbols. (PiDeleteProcess): Change #ifdef KDBG to #ifdef DBG. * ntoskrnl/rtl/ctype.c (_pctype): #undef. * ntoskrnl/rtl/string.c (strncpy): Terminate destination string. * tools/Makefile (rsym): Add target. * tools/helper.mk: Include config and use -g if DBG = 1. svn path=/trunk/; revision=3212
2002-07-13 12:44:09 +00:00
/*
* Usage: rsym input-file output-file
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define IMAGE_DOS_MAGIC 0x5a4d
#define IMAGE_PE_MAGIC 0x00004550
#define IMAGE_SIZEOF_SHORT_NAME 8
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
typedef void* PVOID;
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef signed long LONG;
typedef unsigned long ULONG;
#pragma pack(push,2)
typedef struct _IMAGE_DOS_HEADER {
WORD e_magic;
WORD e_cblp;
WORD e_cp;
WORD e_crlc;
WORD e_cparhdr;
WORD e_minalloc;
WORD e_maxalloc;
WORD e_ss;
WORD e_sp;
WORD e_csum;
WORD e_ip;
WORD e_cs;
WORD e_lfarlc;
WORD e_ovno;
WORD e_res[4];
WORD e_oemid;
WORD e_oeminfo;
WORD e_res2[10];
LONG e_lfanew;
} IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER;
#pragma pack(pop)
#pragma pack(push,4)
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
} IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY;
typedef struct _IMAGE_OPTIONAL_HEADER {
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint;
DWORD BaseOfCode;
DWORD BaseOfData;
DWORD ImageBase;
DWORD SectionAlignment;
DWORD FileAlignment;
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Reserved1;
DWORD SizeOfImage;
DWORD SizeOfHeaders;
DWORD CheckSum;
WORD Subsystem;
WORD DllCharacteristics;
DWORD SizeOfStackReserve;
DWORD SizeOfStackCommit;
DWORD SizeOfHeapReserve;
DWORD SizeOfHeapCommit;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER,*PIMAGE_OPTIONAL_HEADER;
typedef struct _IMAGE_FILE_HEADER {
WORD Machine;
WORD NumberOfSections;
DWORD TimeDateStamp;
DWORD PointerToSymbolTable;
DWORD NumberOfSymbols;
WORD SizeOfOptionalHeader;
WORD Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
typedef struct _IMAGE_SECTION_HEADER {
BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
union {
DWORD PhysicalAddress;
DWORD VirtualSize;
} Misc;
DWORD VirtualAddress;
DWORD SizeOfRawData;
DWORD PointerToRawData;
DWORD PointerToRelocations;
DWORD PointerToLinenumbers;
WORD NumberOfRelocations;
WORD NumberOfLinenumbers;
DWORD Characteristics;
} IMAGE_SECTION_HEADER,*PIMAGE_SECTION_HEADER;
#pragma pack(pop)
typedef struct _SYMBOLFILE_HEADER {
unsigned long StabsOffset;
unsigned long StabsLength;
unsigned long StabstrOffset;
unsigned long StabstrLength;
} SYMBOLFILE_HEADER, *PSYMBOLFILE_HEADER;
char* convert_path(char* origpath)
{
char* newpath;
int i;
newpath = strdup(origpath);
i = 0;
while (newpath[i] != 0)
{
#ifdef UNIX_PATHS
if (newpath[i] == '\\')
{
newpath[i] = '/';
}
#else
#ifdef DOS_PATHS
if (newpath[i] == '/')
{
newpath[i] = '\\';
}
#endif
#endif
i++;
}
return(newpath);
}
#define TRANSFER_SIZE (65536)
int main(int argc, char* argv[])
{
SYMBOLFILE_HEADER SymbolFileHeader;
IMAGE_DOS_HEADER PEDosHeader;
IMAGE_FILE_HEADER PEFileHeader;
PIMAGE_SECTION_HEADER PESectionHeaders;
PVOID SymbolsBase;
ULONG SymbolsLength;
PVOID SymbolStringsBase;
ULONG SymbolStringsLength;
ULONG Idx;
char* path1;
char* path2;
FILE* in;
FILE* out;
char* buf;
int n_in;
int n_out;
if (argc != 3)
{
fprintf(stderr, "Too many arguments\n");
exit(1);
}
path1 = convert_path(argv[1]);
path2 = convert_path(argv[2]);
in = fopen(path1, "rb");
if (in == NULL)
{
perror("Cannot open input file");
exit(1);
}
out = fopen(path2, "wb");
if (out == NULL)
{
perror("Cannot open output file");
fclose(in);
exit(1);
}
/* Check if MZ header exists */
n_in = fread(&PEDosHeader, 1, sizeof(PEDosHeader), in);
if (PEDosHeader.e_magic != IMAGE_DOS_MAGIC && PEDosHeader.e_lfanew != 0L)
{
perror("Input file is not a PE image.\n");
}
/* Read PE file header */
/* sizeof(ULONG) = sizeof(MAGIC) */
fseek(in, PEDosHeader.e_lfanew + sizeof(ULONG), SEEK_SET);
n_in = fread(&PEFileHeader, 1, sizeof(PEFileHeader), in);
/* Read PE section headers */
PESectionHeaders = malloc(PEFileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER));
fseek(in, PEDosHeader.e_lfanew + sizeof(ULONG) + sizeof(IMAGE_FILE_HEADER)
+ sizeof(IMAGE_OPTIONAL_HEADER), SEEK_SET);
n_in = fread(PESectionHeaders, 1, PEFileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER), in);
/* Copy .stab and .stabstr sections if available */
SymbolsBase = NULL;
SymbolsLength = 0;
SymbolStringsBase = NULL;
SymbolStringsLength = 0;
for (Idx = 0; Idx < PEFileHeader.NumberOfSections; Idx++)
{
//printf("section: '%.08s'\n", PESectionHeaders[Idx].Name);
if ((strncmp(PESectionHeaders[Idx].Name, ".stab", 5) == 0)
&& (PESectionHeaders[Idx].Name[5] == 0))
{
//printf(".stab section found. Size %d\n",
// PESectionHeaders[Idx].SizeOfRawData);
SymbolsLength = PESectionHeaders[Idx].SizeOfRawData;
SymbolsBase = malloc(SymbolsLength);
fseek(in, PESectionHeaders[Idx].PointerToRawData, SEEK_SET);
n_in = fread(SymbolsBase, 1, SymbolsLength, in);
}
if (strncmp(PESectionHeaders[Idx].Name, ".stabstr", 8) == 0)
{
//printf(".stabstr section found. Size %d\n",
// PESectionHeaders[Idx].SizeOfRawData);
SymbolStringsLength = PESectionHeaders[Idx].SizeOfRawData;
SymbolStringsBase = malloc(SymbolStringsLength);
fseek(in, PESectionHeaders[Idx].PointerToRawData, SEEK_SET);
n_in = fread(SymbolStringsBase, 1, SymbolStringsLength, in);
}
}
SymbolFileHeader.StabsOffset = sizeof(SYMBOLFILE_HEADER);
SymbolFileHeader.StabsLength = SymbolsLength;
SymbolFileHeader.StabstrOffset = SymbolFileHeader.StabsOffset + SymbolsLength;
SymbolFileHeader.StabstrLength = SymbolStringsLength;
n_out = fwrite(&SymbolFileHeader, 1, sizeof(SYMBOLFILE_HEADER), out);
n_out = fwrite(SymbolsBase, 1, SymbolsLength, out);
n_out = fwrite(SymbolStringsBase, 1, SymbolStringsLength, out);
exit(0);
}