[ros-diffs] [tkreuzer] 52141: [OBJ2BIN] - Implement coff relocation

tkreuzer at svn.reactos.org tkreuzer at svn.reactos.org
Tue Jun 7 22:45:58 UTC 2011


Author: tkreuzer
Date: Tue Jun  7 22:45:56 2011
New Revision: 52141

URL: http://svn.reactos.org/svn/reactos?rev=52141&view=rev
Log:
[OBJ2BIN]
- Implement coff relocation

Modified:
    trunk/reactos/tools/obj2bin/obj2bin.c
    trunk/reactos/tools/pecoff.h

Modified: trunk/reactos/tools/obj2bin/obj2bin.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/tools/obj2bin/obj2bin.c?rev=52141&r1=52140&r2=52141&view=diff
==============================================================================
--- trunk/reactos/tools/obj2bin/obj2bin.c [iso-8859-1] (original)
+++ trunk/reactos/tools/obj2bin/obj2bin.c [iso-8859-1] Tue Jun  7 22:45:56 2011
@@ -11,18 +11,54 @@
            "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;
-
-    if ((argc != 3) || (strcmp(argv[1], "--help") == 0)) Usage();
+    PIMAGE_RELOCATION pReloc;
+    PIMAGE_SYMBOL pSymbols;
+
+    if ((argc != 4) || (strcmp(argv[1], "--help") == 0))
+    {
+        Usage();
+        return -1;
+    }
 
     pszSourceFile = argv[1];
     pszDestFile = argv[2];
@@ -40,6 +76,8 @@
         fprintf(stderr, "Couldn't open dest file '%s'\n", pszDestFile);
         return -2;
     }
+
+    iOffset = strtol(argv[3], 0, 16);
 
     /* Load the coff header */
     nSize = fread(&FileHeader, 1, sizeof(FileHeader), pSourceFile);
@@ -77,11 +115,34 @@
         return -6;
     }
 
-    /* Move file pointer to the start of the section*/
+    /* 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 -7;
+        return -10;
     }
 
     /* Allocate memory for the section */
@@ -89,21 +150,46 @@
     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);

Modified: trunk/reactos/tools/pecoff.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/tools/pecoff.h?rev=52141&r1=52140&r2=52141&view=diff
==============================================================================
--- trunk/reactos/tools/pecoff.h [iso-8859-1] (original)
+++ trunk/reactos/tools/pecoff.h [iso-8859-1] Tue Jun  7 22:45:56 2011
@@ -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 @@
 } 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)




More information about the Ros-diffs mailing list