From 96cf66ac354aa350a11a72a75f4feabe54b509fd Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Tue, 7 Jun 2011 22:45:56 +0000 Subject: [PATCH] [OBJ2BIN] - Implement coff relocation svn path=/trunk/; revision=52141 --- reactos/tools/obj2bin/obj2bin.c | 98 +++++++++++++++++++++++++++++++-- reactos/tools/pecoff.h | 34 ++++++++++++ 2 files changed, 126 insertions(+), 6 deletions(-) diff --git a/reactos/tools/obj2bin/obj2bin.c b/reactos/tools/obj2bin/obj2bin.c index 8f71cf55e15..97cad423235 100644 --- a/reactos/tools/obj2bin/obj2bin.c +++ b/reactos/tools/obj2bin/obj2bin.c @@ -11,18 +11,54 @@ Usage(void) "Syntax: obj2bin \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); diff --git a/reactos/tools/pecoff.h b/reactos/tools/pecoff.h index d3a32502c09..288255a8835 100644 --- a/reactos/tools/pecoff.h +++ b/reactos/tools/pecoff.h @@ -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)