reactos/reactos/tools/rsym.c
guido 85c1893693 fix some warnings
----------------------------------------------------------------------

svn path=/trunk/; revision=3926
2003-01-03 00:28:07 +00:00

253 lines
6.2 KiB
C

/*
* 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);
}