reactos/sdk/tools/obj2bin/obj2bin.c

179 lines
4.7 KiB
C
Raw Normal View History

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
* Improve the way we create rossym debug info. The effort results in ~85% *smaller* build folder with ninja all with no code changes. [DBGHELPHOST] * Introduce a self-contained, static library version of dbghelp, in order to leverage its PE DWARF support. Thanks to Jerome Gardou for his work on the compatibility layer, and to Thomas Faber for helping me with the review/improvements. * Unify the new host lib with the existing dll codebase using preprocessor conditions. This prevents code duplication. * Skip as much unneeded functionality as possible when compiling dbghelphost to keep it light and straight to the point. [RSYM] * Introduce the required functions that allow parsing DWARF (using dbghelphost) and using it (along with coff symbols) to create the rossym debug info. Brought to you by Awesome Arty with some bugfixes from Jerome Gardou. Many thanks to Thomas Faber for assisting me with the testing/bug hunting. [CMAKE/GCC] * Introduce a combination of dwarf and debug emission flags that ensure the smallest debug info size among all the possible options we have. * Introduce compressed debug sections that I already included the support for in RosBE 2.1. Thanks to the mingw-w64 folks (Kai Tietz) for the patch. * Don't compress debug sections of C++ modules for now due to a bug in the toolchain that leads to spamming the build at link time with a warning. * Don't run rsym on the RC shared libraries. Thanks to Thomas Faber for spotting this. [DBGHELP] * Update the ros diff to reflect the changes introduced by the dbghelphost unification. svn path=/trunk/; revision=59505
2013-07-18 21:03:01 +00:00
#include <typedefs.h>
#include <pecoff.h>
static
void
Usage(void)
{
printf("Converts a coff object file into a raw binary file.\n"
"Syntax: obj2bin <source file> <dest file> <base address>\n");
}
static
int
RelocateSection(
char *pData,
IMAGE_SECTION_HEADER *pSectionHeader,
PIMAGE_SYMBOL pSymbols,
unsigned int iOffset)
{
unsigned int i, nOffset;
PIMAGE_RELOCATION pReloc;
char *pSection;
WORD *p16;
DWORD *p32;
pSection = pData + pSectionHeader->PointerToRawData;
/* Calculate pointer to relocation table */
pReloc = (PIMAGE_RELOCATION)(pData + pSectionHeader->PointerToRelocations);
/* Loop all relocations */
for (i = 0; i < pSectionHeader->NumberOfRelocations; i++)
{
nOffset = pReloc->VirtualAddress - pSectionHeader->VirtualAddress;
if (nOffset > pSectionHeader->SizeOfRawData) continue;
switch (pReloc->Type)
{
case IMAGE_REL_I386_ABSOLUTE:
case 16:
p16 = (void*)(pSection + nOffset);
*p16 += (WORD)(pSymbols[pReloc->SymbolTableIndex].Value + iOffset);
break;
case IMAGE_REL_I386_REL16:
p16 = (void*)(pSection + nOffset);
*p16 += (WORD)(pSymbols[pReloc->SymbolTableIndex].Value + iOffset);
break;
case IMAGE_REL_I386_DIR32:
p32 = (void*)(pSection + nOffset);
*p32 += (DWORD)(pSymbols[pReloc->SymbolTableIndex].Value + iOffset);
break;
default:
printf("Unknown relocation type %u, address 0x%x\n",
pReloc->Type, (unsigned)pReloc->VirtualAddress);
return 0;
}
pReloc++;
}
return 1;
}
int main(int argc, char *argv[])
{
char *pszSourceFile;
char *pszDestFile;
unsigned long nFileSize, nBaseAddress;
FILE *pSourceFile, *pDestFile;
IMAGE_FILE_HEADER *pFileHeader;
IMAGE_SECTION_HEADER *pSectionHeader;
unsigned int i;
char *pData;
PIMAGE_SYMBOL pSymbols;
if ((argc != 4) || (strcmp(argv[1], "--help") == 0))
{
Usage();
return -1;
}
pszSourceFile = argv[1];
pszDestFile = argv[2];
nBaseAddress = strtol(argv[3], 0, 16);
pSourceFile = fopen(pszSourceFile, "rb");
if (!pSourceFile)
{
fprintf(stderr, "Couldn't open source file '%s'\n", pszSourceFile);
return -2;
}
/* Get file size */
fseek(pSourceFile, 0, SEEK_END);
nFileSize = ftell(pSourceFile);
rewind(pSourceFile);
/* Allocate memory for the file */
pData = malloc(nFileSize);
if (!pData)
{
fclose(pSourceFile);
fprintf(stderr, "Failed to allocate %lu bytes\n", nFileSize);
return -3;
}
/* Read the whole source file */
if (!fread(pData, nFileSize, 1, pSourceFile))
{
free(pData);
fclose(pSourceFile);
fprintf(stderr, "Failed to read %lu bytes from source file\n", nFileSize);
return -4;
}
/* Close source file */
fclose(pSourceFile);
/* Open the destination file */
pDestFile = fopen(pszDestFile, "wb");
if (!pDestFile)
{
free(pData);
fprintf(stderr, "Couldn't open destination file '%s'\n", pszDestFile);
return -5;
}
/* Calculate table pointers */
pFileHeader = (IMAGE_FILE_HEADER*)pData;
pSymbols = (void*)(pData + pFileHeader->PointerToSymbolTable);
pSectionHeader = (void*)(((char*)(pFileHeader + 1)) + pFileHeader->SizeOfOptionalHeader);
/* Loop all sections */
for (i = 0; i < pFileHeader->NumberOfSections; i++)
{
/* Check if this is '.text' section */
if ((strcmp((char*)pSectionHeader->Name, ".text") == 0) &&
(pSectionHeader->SizeOfRawData != 0))
{
if (!RelocateSection(pData,
pSectionHeader,
pSymbols,
nBaseAddress))
{
free(pData);
fclose(pDestFile);
return -7;
}
/* Write the section to the destination file */
if (!fwrite(pData + pSectionHeader->PointerToRawData,
pSectionHeader->SizeOfRawData, 1, pDestFile))
{
free(pData);
fclose(pDestFile);
fprintf(stderr, "Failed to write %u bytes to destination file\n",
(unsigned int)pSectionHeader->SizeOfRawData);
return -6;
}
nBaseAddress += pSectionHeader->SizeOfRawData;
}
pSectionHeader++;
}
free(pData);
fclose(pDestFile);
return 0;
}