+++ /dev/null
-/*
- * 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>
-#include <assert.h>
-
-#include "rsym.h"
-
-int
-IsDebugSection(PIMAGE_SECTION_HEADER Section)
-{
- /* This is a hack, but works for us */
- return (Section->Name[0] == '/');
-}
-
-int main(int argc, char* argv[])
-{
- unsigned int i;
- PSYMBOLFILE_HEADER SymbolFileHeader;
- PIMAGE_NT_HEADERS NtHeaders;
- PIMAGE_DOS_HEADER DosHeader;
- PIMAGE_FILE_HEADER FileHeader;
- PIMAGE_OPTIONAL_HEADER OptionalHeader;
- PIMAGE_SECTION_HEADER SectionHeaders, LastSection;
- char* path1;
- char* path2;
- FILE* out;
- size_t FileSize;
- void *FileData;
- char elfhdr[] = { '\377', 'E', 'L', 'F' };
-
- if (argc != 3)
- {
- fprintf(stderr, "Usage: rsym <exefile> <symfile>\n");
- exit(1);
- }
-
- path1 = convert_path(argv[1]);
- path2 = convert_path(argv[2]);
-
- /* Load the input file into memory */
- FileData = load_file( path1, &FileSize);
- if ( !FileData )
- {
- fprintf(stderr, "An error occured loading '%s'\n", path1);
- exit(1);
- }
-
- /* Check if MZ header exists */
- DosHeader = (PIMAGE_DOS_HEADER) FileData;
- if (DosHeader->e_magic != IMAGE_DOS_MAGIC || DosHeader->e_lfanew == 0L)
- {
- /* Ignore elf */
- if (!memcmp(DosHeader, elfhdr, sizeof(elfhdr)))
- exit(0);
- perror("Input file is not a PE image.\n");
- free(FileData);
- exit(1);
- }
-
- /* Locate the headers */
- NtHeaders = (PIMAGE_NT_HEADERS)((char*)FileData + DosHeader->e_lfanew);
- FileHeader = &NtHeaders->FileHeader;
- OptionalHeader = &NtHeaders->OptionalHeader;
-
- /* Locate PE section headers */
- SectionHeaders = (PIMAGE_SECTION_HEADER)((char*)OptionalHeader +
- FileHeader->SizeOfOptionalHeader);
-
- /* Loop all sections */
- for (i = 0; i < FileHeader->NumberOfSections; i++)
- {
- /* Check if this is a debug section */
- if (IsDebugSection(&SectionHeaders[i]))
- {
- /* Make sure we have the correct characteristics */
- SectionHeaders[i].Characteristics |= IMAGE_SCN_CNT_INITIALIZED_DATA;
- SectionHeaders[i].Characteristics &= ~(IMAGE_SCN_MEM_PURGEABLE | IMAGE_SCN_MEM_DISCARDABLE);
- }
- }
-
- /* Get a pointer to the last section header */
- LastSection = &SectionHeaders[FileHeader->NumberOfSections - 1];
-
- /* Set the size of the last section to cover the rest of the PE */
- LastSection->SizeOfRawData = FileSize - LastSection->PointerToRawData;
-
- /* Check if the virtual section size is smaller than the raw data */
- if (LastSection->Misc.VirtualSize < LastSection->SizeOfRawData)
- {
- /* Make sure the virtual size of the section cover the raw data */
- LastSection->Misc.VirtualSize = ROUND_UP(LastSection->SizeOfRawData,
- OptionalHeader->SectionAlignment);
-
- /* Fix up image size */
- OptionalHeader->SizeOfImage = LastSection->VirtualAddress +
- LastSection->Misc.VirtualSize;
- }
-
- /* Open the output file */
- out = fopen(path2, "wb");
- if (out == NULL)
- {
- perror("Cannot open output file");
- free(FileData);
- exit(1);
- }
-
- /* Write the output file */
- fwrite(FileData, 1, FileSize, out);
- fclose(out);
- free(FileData);
-
- return 0;
-}
-
-/* EOF */