source: branches/swt/src/win32k/ldr/xx2lxmain.cpp

Last change on this file was 22090, checked in by rousseau, 11 years ago

Fixed broken 'xx2lx.exe'

When using VAC, the resident and swap heaps were initialized using VAC
specific '_exeentry' functionality. This does not exist on GCC resulting
in uninitialized heaps causing 'xx2lx.exe' to crash.

File size: 14.8 KB
Line 
1/* $Id: xx2lxmain.cpp,v 1.2 2004-01-15 10:14:48 sandervl Exp $
2 *
3 * Xx2Lx main program. (Ring 3 only!)
4 *
5 * Copyright (c) 1999-2001 knut st. osmundsen
6 *
7 * Project Odin Software License can be found in LICENSE.TXT
8 *
9 */
10
11/*******************************************************************************
12* Defined Constants And Macros *
13*******************************************************************************/
14#define FOR_EXEHDR 1
15#define INCL_BASE
16#define INCL_DOSFILEMGR
17#define INCL_DOSERRORS
18#define INCL_OS2KRNL_LDR
19
20#define DATA16_GLOBAL
21#define OUTPUT_COM2 0x2f8
22
23/*******************************************************************************
24* Header Files *
25*******************************************************************************/
26#include <os2.h>
27#include <peexe.h>
28#include <neexe.h>
29#include <newexe.h>
30#include <exe386.h>
31#include "elf.h"
32#include <malloc.h>
33#include <string.h>
34#include <stdlib.h>
35#include <io.h>
36#include <fcntl.h>
37#include <sys/stat.h>
38#include "OS2Krnl.h"
39#include "modulebase.h"
40#include "pe2lx.h"
41#include "elf2lx.h"
42#include "options.h"
43#include <stdio.h>
44#include <versionos2.h>
45
46
47/*******************************************************************************
48* Global Variables *
49*******************************************************************************/
50char szBackupXxFilename[CCHMAXPATH]; /* too save stack/heap */
51struct options options = DEFAULT_OPTION_ASSIGMENTS;
52
53/*******************************************************************************
54* Internal Functions *
55*******************************************************************************/
56static void syntax();
57
58
59/**
60 * Main function of the Pe2Lx utillity.
61 * @returns 0 on success.
62 * 1 Help.
63 * 2 Syntax error: Invalid argument, '<arg>'.
64 * 3 Syntax error: Too many filenames.
65 * 4 Syntax error: No Xx-file specified.
66 * 80 Fatal error: Can't find Xx-file, <filename>.
67 * 81 Fatal error: Failed to rename the Xx-file, <from> -> <to>
68 * 82 Fatal error: Failed to open Xx-file, <filename>. rc=<rc>
69 * 83 Fatal error: Failed to read file signature. rc=<rc from DosRead(..)>
70 * 84 Fatal error: Failed to convertert the file. rc=<rc from init(..)>
71 * 85 Fatal error: Failed to write the Lx-file. rc=<rc from writeFile(..)>
72 * @param argc Count of arguments.
73 * @param argv Array of argument pointers. argc entries.
74 * @status completely implemented.
75 * @author knut st. osmundsen
76 */
77int main(int argc, char **argv)
78{
79 APIRET rc;
80 ULONG ulAction = 0;
81 PCSZ pszXxFilename = NULL;
82 PCSZ pszLxFilename = NULL;
83 PCSZ psz;
84 int argi;
85
86#ifdef __GNUC__
87 /*
88 * Initialize heaps when using GCC.
89 * When building with GCC, there exists no VAC '_exeentry' stuff.
90 * So the function '_rmem_init()' in 'misc/malloc.c', which would
91 * initialize the resident and swap heaps, is never called under GCC.
92 */
93 rc = heapInit(CB_RES_INIT, CB_RES_MAX, CB_SWP_INIT, CB_SWP_MAX);
94 if (rc != NO_ERROR) {
95 printf("Fatal error: Failed to initialize memory heaps. rc=%d\n", rc);
96 return rc;
97 }
98#endif
99
100 /* special edition for Dave Evans */
101 options.fPEOneObject = FLAGS_PEOO_DISABLED;
102
103 /* read parameters */
104 for (argi = 1; argi < argc; argi++)
105 {
106 /* check if option or filname */
107 if (argv[argi][0] == '-' || argv[argi][0] == '/')
108 { /* option */
109 switch (argv[argi][1])
110 {
111 case '1': /* All-In-One-Object fix - temporary...- -1<-|+|*> */
112 if (argv[argi][2] == '-')
113 options.fPEOneObject = FLAGS_PEOO_DISABLED;
114 else if (argv[argi][2] == '+')
115 options.fPEOneObject = FLAGS_PEOO_ENABLED;
116 else
117 options.fPEOneObject = FLAGS_PEOO_FORCED;
118 break;
119
120
121 case 'h': /* syntax help */
122 case 'H':
123 case '?':
124 syntax();
125 return 1;
126
127 case 'w': /* warning level */
128 case 'W':
129 psz = argv[argi] + (argv[argi][2] == ':' || argv[argi][2] == '=') + 2;
130 if (*psz >= '0' && *psz <= '4' && psz[1] == '\0')
131 {
132 switch (*psz)
133 {
134 case '0': ModuleBase::ulInfoLevel = ModuleBase::Quiet; break;
135 case '1': ModuleBase::ulInfoLevel = ModuleBase::Error; break;
136 case '2': ModuleBase::ulInfoLevel = ModuleBase::Warning; break;
137 case '3': ModuleBase::ulInfoLevel = ModuleBase::Info; break;
138 case '4': ModuleBase::ulInfoLevel = ModuleBase::InfoAll; break;
139 }
140 }
141 else
142 {
143 printf("Syntax error: Incorrect use of argument '%.2s'.\n\n", argv[argi]);
144 return 5;
145 }
146 break;
147
148
149 case 'f': /* ignore internal fixups */
150 case 'F':
151 options.fSkipFixups = TRUE;
152 break;
153
154 case 'r': /* all read-write objects */
155 case 'R':
156 if (argv[argi][2] != 'w' && argv[argi][2] != 'W')
157 {
158 printf("Syntax error: Invalid argument, '%s'\n", argv[argi]);
159 return 5;
160 }
161 options.fAllRWObjects = TRUE;
162 break;
163
164 case 'c': /* custom odin dll name */
165 case 'C':
166 if (!hasCustomExports())
167 {
168 printf("Syntax error: export table file not specified (-o:).\n\n");
169 return 5;
170 }
171 options.pszCustomDll = &argv[argi][3];
172 break;
173
174 case 'o': /* custom odin dll ordinal mapping */
175 case 'O':
176 {
177 int fileIn = open(&argv[argi][3], O_RDONLY, S_IREAD);
178 int sizein = (int)_filelength(fileIn);
179
180 options.pszCustomExports = (PSZ)malloc(sizein+1);
181 memset(options.pszCustomExports, 0, sizein+1);
182 read(fileIn, options.pszCustomExports, sizein);
183 close(fileIn);
184 break;
185 }
186
187 case 'x': /* custombuild exclude dll */
188 case 'X':
189 {
190 int cch = strlen(&argv[argi][3]);
191 if (!cch)
192 {
193 printf("Syntax error: optino -x: requires a dll name!");
194 return 5;
195 }
196 int cchNew = cch + 4;
197 if (options.pszCustomDllExclude)
198 cchNew += strlen(options.pszCustomDllExclude);
199 options.pszCustomDllExclude = (char*)realloc(options.pszCustomDllExclude, cchNew);
200
201 char *psz = options.pszCustomDllExclude;
202 if (cchNew != cch + 4)
203 psz = psz + strlen(psz);
204
205 /* copy the name in uppercase with ';' at both ends. */
206 *psz++ = ';';
207 for (strcpy(psz, &argv[argi][3]); *psz; psz++)
208 if (*psz >= 'a' && *psz <= 'z')
209 *psz += ('A' - 'a');
210 *psz++ =';';
211 *psz = '\0';
212 break;
213 }
214
215 default:
216 printf("Syntax error: Invalid argument, '%s'\n", argv[argi]);
217 syntax();
218 return 2;
219 }
220 }
221 else
222 {
223 if (pszXxFilename == NULL)
224 {
225 pszXxFilename = argv[argi];
226 /* check if exists */
227 rc = DosQueryPathInfo(pszXxFilename,FIL_QUERYFULLNAME,
228 &szBackupXxFilename[0], sizeof(szBackupXxFilename));
229 if (rc != NO_ERROR)
230 {
231 printf("Fatal error: Can't find Xx-file, '%s'.\n", pszXxFilename);
232 return 80;
233 }
234 }
235 else if (pszLxFilename == NULL)
236 pszLxFilename = argv[argi];
237 else
238 {
239 printf("Syntax error: Too many filenames!\n");
240 syntax();
241 return 3;
242 }
243 }
244 } /* for */
245
246 /* check if enough arguments */
247 if (pszXxFilename == NULL)
248 {
249 printf("Syntax error: No Xx-file specified.\n\n");
250 syntax();
251 return 4;
252 }
253
254 /* rename files? */
255 if (pszLxFilename == NULL)
256 {
257 char *pszExt = strrchr(pszXxFilename, '.');
258 if (pszExt == NULL)
259 {
260 //printf("warning: Xx-file don't have an extention\n");
261 strcpy(szBackupXxFilename, pszXxFilename);
262 strcat(szBackupXxFilename, "wbk");
263 }
264 else
265 {
266 memset(szBackupXxFilename, 0, sizeof(szBackupXxFilename));
267 if (stricmp(pszExt + 1, "exe") == 0)
268 {
269 strncpy(szBackupXxFilename, pszXxFilename, pszExt - pszXxFilename + 1);
270 strcat(szBackupXxFilename, "exf");
271 }
272 else
273 {
274 strncpy(szBackupXxFilename, pszXxFilename, pszExt - pszXxFilename + 3);
275 strcat(szBackupXxFilename, "k");
276 }
277 }
278 rc = DosMove(pszXxFilename, szBackupXxFilename);
279 if (rc != NO_ERROR)
280 {
281 printf("Fatal error: Failed to rename the Xx-file, %s -> %s\n",
282 pszXxFilename, szBackupXxFilename);
283 return 81;
284 }
285 printInf(("Backuped %s to %s\n", pszXxFilename, szBackupXxFilename));
286
287 /* switch name */
288 pszLxFilename = pszXxFilename;
289 pszXxFilename = szBackupXxFilename;
290 }
291
292 /*
293 * Open input file
294 */
295 HFILE hFileXx;
296
297 rc = DosOpen(pszXxFilename, &hFileXx, &ulAction, 0UL,
298 FILE_NORMAL,
299 OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
300 OPEN_FLAGS_RANDOMSEQUENTIAL | OPEN_ACCESS_READONLY | OPEN_SHARE_DENYWRITE,
301 NULL);
302 if (rc == NO_ERROR)
303 {
304 ULONG ulSignature; /* Signature (four first bytes) of the file */
305 ULONG cbRead; /* Signature bytes read - ignored */
306
307 /*
308 * Read signature.
309 * If Elf signature Then create elf2lx object.
310 * Else create pe2lx object.
311 * Init the module.
312 * Write LX File.
313 * Dump virtual LX file
314 */
315 rc = DosRead(hFileXx, &ulSignature, sizeof(ulSignature), &cbRead);
316 if (rc == NO_ERROR)
317 {
318 ModuleBase *pModule; /* Pointer to module. */
319
320 if (ulSignature == ELFMAGICLSB)
321 pModule = new Elf2Lx(hFileXx);
322 else
323 pModule = new Pe2Lx(hFileXx);
324
325 rc = pModule->init(pszLxFilename);
326 if (rc == NO_ERROR)
327 {
328 rc = pModule->writeFile(pszLxFilename);
329 if (rc != NO_ERROR)
330 {
331 printf("Fatal error: Failed to write the Lx-file. rc=%d\n", rc);
332 rc = 85;
333 }
334 pModule->dumpVirtualLxFile();
335 }
336 else
337 {
338 printf("Fatal error: Failed to convert the file. rc=%d\n", rc);
339 rc = 84;
340 }
341 }
342 else
343 {
344 printf("Fatal error: Failed to read file signature. rc=%d\n", rc);
345 rc = 83;
346 }
347
348 DosClose(hFileXx);
349 }
350 else
351 {
352 printf("Fatal error: Failed to open Xx-file, %s. rc=%d\n",
353 pszXxFilename, rc);
354 rc = 82;
355 }
356 return (int)rc;
357}
358
359
360/**
361 * Display syntax for this program.
362 * @status completely implemented.
363 * @author knut st. osmundsen
364 */
365static void syntax()
366{
367 printf("Syntax: xx2lx.exe [-W<0|1|2|3>] [-1<+|-|[*]>] <XxFile> [LxFile]\n"
368 "\n"
369 " Global options:\n"
370 " -W<0|1|2|3|4> Message filter level.\n"
371 " -W0: Output only severe and unrecoverable error messages.\n"
372 " -W1: Output error, severe and unrecoverable error messages.\n"
373 " -W2: Output warning, error, severe and unrecoverable error\n"
374 " messages.\n"
375 " -W3: Output nearly all messages.\n"
376 " -W4: Output absolutely all messages.\n"
377 " Default: -W3\n"
378 "\n"
379 " Pe2Lx options:\n"
380 " -1<+|-|[*]> All-in-one-object fix.\n"
381 " +: Fix applied when necessary.\n"
382 " -: Disabled. Never applied.\n"
383 " *: Forced. Applied every time.\n"
384 " Default: -1*\n"
385 " -rw Make all segments writable. For use with -1+. A trick to make\n"
386 " it possible for OS/2 to load the objects following on another.\n"
387 " This of course doesn't solve the alignment difference. So if\n"
388 " you build the program pass /ALIGN:0x10000 to the linker.\n"
389 " -f Strip fixups forcing. Don't use with DLLs, may cause traps.\n"
390 "\n"
391 " Custombuild options:\n"
392 " -o:<ordfile> Ordinal file. form: <W32DLL>.<name/ord> @<CustDLLOrd>\n"
393 " -c:<custdll> Custombuild dll. After -o:!\n"
394 " -x:<dll> Exclude from custombuild. -x:MSVCRT for example.\n"
395 "\n"
396 " XxFile Input PE .\n"
397 " LxFile Output Lx-file. If not specified the Xx-file is\n"
398 " renamed and the Lx-file will use the original name\n"
399 " of the Xx-file.\n"
400 " Xx2Lx version 0.%02d\n",
401 PE2LX_VERSION
402 );
403}
404
405
406
407#if 0
408/**
409 * Debug - see how much of the stack that have been used.
410 * Padd stack, and look in the debug storage view on program end.
411 * @param
412 * @status
413 * @author knut st. osmundsen
414 */
415static void initStack()
416{
417 PTIB pTib;
418 PPIB pPib;
419
420 DosGetInfoBlocks(&pTib, &pPib);
421 memset((PVOID)pTib->tib_pstack, 'k', (size_t)&pTib - 0x30 - (size_t)pTib->tib_pstack);
422}
423#endif
Note: See TracBrowser for help on using the repository browser.