[TCPIP]
[reactos.git] / reactos / tools / obj2bin / obj2bin.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "../pecoff.h"
5
6 static
7 void
8 Usage(void)
9 {
10 printf("Converts a coff object file into a raw binary file.\n"
11 "Syntax: obj2bin <source file> <dest file> <base address>\n");
12 }
13
14 static
15 void
16 RelocateSection(
17 char *pData,
18 IMAGE_SECTION_HEADER *pSectionHeader,
19 PIMAGE_SYMBOL pSymbols,
20 unsigned int iOffset)
21 {
22 unsigned int i, nOffset;
23 PIMAGE_RELOCATION pReloc;
24 char *pSection;
25 WORD *p16;
26 DWORD *p32;
27
28 pSection = pData + pSectionHeader->PointerToRawData;
29
30 /* Calculate pointer to relocation table */
31 pReloc = (PIMAGE_RELOCATION)(pData + pSectionHeader->PointerToRelocations);
32
33 /* Loop all relocations */
34 for (i = 0; i < pSectionHeader->NumberOfRelocations; i++)
35 {
36 nOffset = pReloc->VirtualAddress - pSectionHeader->VirtualAddress;
37
38 if (nOffset > pSectionHeader->SizeOfRawData) continue;
39
40 switch (pReloc->Type)
41 {
42 case IMAGE_REL_I386_ABSOLUTE:
43 case 16:
44 p16 = (void*)(pSection + nOffset);
45 *p16 += (WORD)(pSymbols[pReloc->SymbolTableIndex].Value + iOffset);
46 break;
47
48 case IMAGE_REL_I386_DIR32:
49 p32 = (void*)(pSection + nOffset);
50 *p32 += (DWORD)(pSymbols[pReloc->SymbolTableIndex].Value + iOffset);
51 break;
52
53 default:
54 printf("Unknown relocatation type %ld address %ld\n",
55 pReloc->Type, pReloc->VirtualAddress);
56 }
57
58 pReloc++;
59 }
60 }
61
62 int main(int argc, char *argv[])
63 {
64 char *pszSourceFile;
65 char *pszDestFile;
66 unsigned long nFileSize, nBaseAddress;
67 FILE *pSourceFile, *pDestFile;
68 IMAGE_FILE_HEADER *pFileHeader;
69 IMAGE_SECTION_HEADER *pSectionHeader;
70 unsigned int i;
71 char *pData;
72 PIMAGE_SYMBOL pSymbols;
73
74 if ((argc != 4) || (strcmp(argv[1], "--help") == 0))
75 {
76 Usage();
77 return -1;
78 }
79
80 pszSourceFile = argv[1];
81 pszDestFile = argv[2];
82 nBaseAddress = strtol(argv[3], 0, 16);
83
84 pSourceFile = fopen(pszSourceFile, "rb");
85 if (!pSourceFile)
86 {
87 fprintf(stderr, "Couldn't open source file '%s'\n", pszSourceFile);
88 return -2;
89 }
90
91 /* Get file size */
92 fseek(pSourceFile, 0, SEEK_END);
93 nFileSize = ftell(pSourceFile);
94 rewind(pSourceFile);
95
96 /* Allocate memory for the file */
97 pData = malloc(nFileSize);
98 if (!pData)
99 {
100 fprintf(stderr, "Failed to allocate %ld bytes\n", nFileSize);
101 return -3;
102 }
103
104 /* Read the whole source file */
105 if (!fread(pData, nFileSize, 1, pSourceFile))
106 {
107 fprintf(stderr, "Failed to read source file: %ld\n", nFileSize);
108 return -4;
109 }
110
111 /* Close source file */
112 fclose(pSourceFile);
113
114 /* Open the destination file */
115 pDestFile = fopen(pszDestFile, "wb");
116 if (!pszDestFile)
117 {
118 fprintf(stderr, "Couldn't open dest file '%s'\n", pszDestFile);
119 return -5;
120 }
121
122 /* Calculate table pointers */
123 pFileHeader = (IMAGE_FILE_HEADER*)pData;
124 pSymbols = (void*)(pData + pFileHeader->PointerToSymbolTable);
125 pSectionHeader = (void*)(((char*)(pFileHeader + 1)) + pFileHeader->SizeOfOptionalHeader);
126
127 /* Loop all sections */
128 for (i = 0; i < pFileHeader->NumberOfSections; i++)
129 {
130 /* Check if this is '.text' section */
131 if ((strcmp(pSectionHeader->Name, ".text") == 0) &&
132 (pSectionHeader->SizeOfRawData != 0))
133 {
134 RelocateSection(pData,
135 pSectionHeader,
136 pSymbols,
137 nBaseAddress);
138
139 /* Write the section to the destination file */
140 if (!fwrite(pData + pSectionHeader->PointerToRawData,
141 pSectionHeader->SizeOfRawData, 1, pDestFile))
142 {
143 fprintf(stderr, "Failed to write data %ld\n",
144 pSectionHeader->SizeOfRawData);
145 return -6;
146 }
147
148 nBaseAddress += pSectionHeader->SizeOfRawData;
149 }
150
151 pSectionHeader++;
152 }
153
154 fclose(pDestFile);
155
156 return 0;
157 }
158