[OBJ2BIN]

- Implement coff relocation

svn path=/trunk/; revision=52141
This commit is contained in:
Timo Kreuzer 2011-06-07 22:45:56 +00:00
parent 26a96b762b
commit 96cf66ac35
2 changed files with 126 additions and 6 deletions

View file

@ -11,18 +11,54 @@ Usage(void)
"Syntax: obj2bin <source file> <dest file>\n");
}
static
void
RelocateImage(
char *pData,
PIMAGE_RELOCATION pReloc,
unsigned int cNumRelocs,
PIMAGE_SYMBOL pSymbols,
unsigned int iOffset)
{
unsigned int i;
WORD *p16;
for (i = 0; i < cNumRelocs; i++)
{
switch (pReloc->Type)
{
case IMAGE_REL_I386_ABSOLUTE:
p16 = (void*)(pData + pReloc->VirtualAddress);
*p16 = (WORD)(pSymbols[pReloc->SymbolTableIndex].Value + iOffset);
break;
default:
printf("Unknown relocatation type %ld\n", pReloc->Type);
}
pReloc++;
}
}
int main(int argc, char *argv[])
{
char *pszSourceFile;
char *pszDestFile;
unsigned long iOffset;
FILE *pSourceFile, *pDestFile;
IMAGE_FILE_HEADER FileHeader;
IMAGE_SECTION_HEADER SectionHeader;
unsigned int i;
size_t nSize;
void *pData;
PIMAGE_RELOCATION pReloc;
PIMAGE_SYMBOL pSymbols;
if ((argc != 3) || (strcmp(argv[1], "--help") == 0)) Usage();
if ((argc != 4) || (strcmp(argv[1], "--help") == 0))
{
Usage();
return -1;
}
pszSourceFile = argv[1];
pszDestFile = argv[2];
@ -41,6 +77,8 @@ int main(int argc, char *argv[])
return -2;
}
iOffset = strtol(argv[3], 0, 16);
/* Load the coff header */
nSize = fread(&FileHeader, 1, sizeof(FileHeader), pSourceFile);
if (nSize != sizeof(FileHeader))
@ -77,33 +115,81 @@ int main(int argc, char *argv[])
return -6;
}
/* Move file pointer to the start of the section*/
if (fseek(pSourceFile, SectionHeader.PointerToRawData, SEEK_SET))
/* Move file pointer to the symbol table */
if (fseek(pSourceFile, FileHeader.PointerToSymbolTable, SEEK_SET))
{
fprintf(stderr, "Failed to set file pointer\n");
return -7;
}
/* Allocate memory for the symbols */
nSize = FileHeader.NumberOfSymbols * sizeof(IMAGE_SYMBOL);
pSymbols = malloc(nSize);
if (!pSymbols)
{
fprintf(stderr, "Failed to allocate %ld bytes\n", nSize);
return -8;
}
/* Read symbol data */
if (!fread(pSymbols, nSize, 1, pSourceFile))
{
fprintf(stderr, "Failed to read section %ld file\n", i);
return -9;
}
/* Move file pointer to the start of the section */
if (fseek(pSourceFile, SectionHeader.PointerToRawData, SEEK_SET))
{
fprintf(stderr, "Failed to set file pointer\n");
return -10;
}
/* Allocate memory for the section */
pData = malloc(SectionHeader.SizeOfRawData);
if (!pData)
{
fprintf(stderr, "Failed to allocate %ld bytes\n", SectionHeader.SizeOfRawData);
return -8;
return -11;
}
/* Read section data */
if (!fread(pData, SectionHeader.SizeOfRawData, 1, pSourceFile))
{
fprintf(stderr, "Failed to read section %ld file\n", i);
return -5;
return -12;
}
/* Allocate memory for the relocation */
nSize = SectionHeader.NumberOfRelocations * sizeof(IMAGE_RELOCATION);
pReloc = malloc(nSize);
if (!pReloc)
{
fprintf(stderr, "Failed to allocate %ld bytes\n", nSize);
return -13;
}
/* Move file pointer to the relocation table */
if (fseek(pSourceFile, SectionHeader.PointerToRelocations, SEEK_SET))
{
fprintf(stderr, "Failed to set file pointer\n");
return -14;
}
/* Read relocation data */
if (!fread(pReloc, nSize, 1, pSourceFile))
{
fprintf(stderr, "Failed to read section %ld file\n", i);
return -15;
}
RelocateImage(pData, pReloc, SectionHeader.NumberOfRelocations, pSymbols, iOffset);
/* Write the section to the destination file */
if (!fwrite(pData, SectionHeader.SizeOfRawData, 1, pDestFile))
{
fprintf(stderr, "Failed to write data\n");
return -9;
return -16;
}
fclose(pDestFile);

View file

@ -41,11 +41,15 @@
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
#define IMAGE_REL_I386_ABSOLUTE 0x0001
typedef unsigned char BYTE;
typedef unsigned char UCHAR;
typedef unsigned short WORD;
typedef short SHORT;
typedef unsigned short USHORT;
typedef unsigned long long ULONGLONG;
#if defined(__x86_64__) && !defined(_WIN64)
typedef signed int LONG;
typedef unsigned int ULONG;
@ -205,3 +209,33 @@ typedef struct _IMAGE_BASE_RELOCATION {
} IMAGE_BASE_RELOCATION,*PIMAGE_BASE_RELOCATION;
#pragma pack(pop)
#pragma pack(push,2)
typedef struct _IMAGE_RELOCATION {
union {
DWORD VirtualAddress;
DWORD RelocCount;
};
DWORD SymbolTableIndex;
WORD Type;
} IMAGE_RELOCATION;
typedef struct _IMAGE_RELOCATION UNALIGNED *PIMAGE_RELOCATION;
#pragma pack(pop)
#pragma pack(push,2)
typedef struct _IMAGE_SYMBOL {
union {
BYTE ShortName[8];
struct {
DWORD Short;
DWORD Long;
} Name;
DWORD LongName[2];
} N;
DWORD Value;
SHORT SectionNumber;
WORD Type;
BYTE StorageClass;
BYTE NumberOfAuxSymbols;
} IMAGE_SYMBOL;
typedef struct _IMAGE_SYMBOL UNALIGNED *PIMAGE_SYMBOL;
#pragma pack(pop)