| 1 | /* $Id: elf2lxmain.cpp,v 1.1 2000-02-27 02:12:34 bird Exp $
 | 
|---|
| 2 |  *
 | 
|---|
| 3 |  * Elf2Lx main program. (Ring 3 only!)
 | 
|---|
| 4 |  *
 | 
|---|
| 5 |  * Copyright (c) 1999 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 | 
 | 
|---|
| 19 | 
 | 
|---|
| 20 | /*******************************************************************************
 | 
|---|
| 21 | *   Header Files                                                               *
 | 
|---|
| 22 | *******************************************************************************/
 | 
|---|
| 23 | #include <os2.h>
 | 
|---|
| 24 | #include "types.h"
 | 
|---|
| 25 | #include <newexe.h>
 | 
|---|
| 26 | #include <exe386.h>
 | 
|---|
| 27 | #include <malloc.h>
 | 
|---|
| 28 | #include <string.h>
 | 
|---|
| 29 | #include <stdlib.h>
 | 
|---|
| 30 | #include "OS2Krnl.h"
 | 
|---|
| 31 | #include "elf.h"
 | 
|---|
| 32 | #include "modulebase.h"
 | 
|---|
| 33 | #include "elf2lx.h"
 | 
|---|
| 34 | #include <stdio.h>
 | 
|---|
| 35 | 
 | 
|---|
| 36 | 
 | 
|---|
| 37 | /*******************************************************************************
 | 
|---|
| 38 | *   Global Variables                                                           *
 | 
|---|
| 39 | *******************************************************************************/
 | 
|---|
| 40 | char szBackupElfFilename[CCHMAXPATH]; /* too save stack/heap */
 | 
|---|
| 41 | 
 | 
|---|
| 42 | 
 | 
|---|
| 43 | /*******************************************************************************
 | 
|---|
| 44 | *   Internal Functions                                                         *
 | 
|---|
| 45 | *******************************************************************************/
 | 
|---|
| 46 | static void syntax();
 | 
|---|
| 47 | 
 | 
|---|
| 48 | 
 | 
|---|
| 49 | /**
 | 
|---|
| 50 |  * Main function of the Elf2Lx utillity.
 | 
|---|
| 51 |  * @returns    0 on success.
 | 
|---|
| 52 |  *             1 Help.
 | 
|---|
| 53 |  *             2 Syntax error: Invalid argument, '<arg>'.
 | 
|---|
| 54 |  *             3 Syntax error: Too many filenames.
 | 
|---|
| 55 |  *             4 Syntax error: No Win32-file specified.
 | 
|---|
| 56 |  *            80 Fatal error: Can't find Win32-file, <filename>.
 | 
|---|
| 57 |  *            81 Fatal error: Failed to rename the Win32-file, <from> -> <to>
 | 
|---|
| 58 |  *            82 Fatal error: Failed to open Win32-file, <filename>. rc=<rc>
 | 
|---|
| 59 |  *            83 Fatal error: Failed to convertert the file. rc=<rc from init(..)>
 | 
|---|
| 60 |  *            84 Fatal error: Failed to write the Lx-file. rc=<rc from writeLXFile(..)>
 | 
|---|
| 61 |  * @param     argc  Count of arguments.
 | 
|---|
| 62 |  * @param     argv  Array of argument pointers. argc entries.
 | 
|---|
| 63 |  * @status    completely implemented.
 | 
|---|
| 64 |  * @author    knut st. osmundsen
 | 
|---|
| 65 |  */
 | 
|---|
| 66 | int main(int argc, char **argv)
 | 
|---|
| 67 | {
 | 
|---|
| 68 |     APIRET rc;
 | 
|---|
| 69 |     ULONG  ulAction = 0;
 | 
|---|
| 70 |     PCSZ   pszElfFilename = NULL;
 | 
|---|
| 71 |     PCSZ   pszOS2NIXFilename = NULL;
 | 
|---|
| 72 |     PCSZ   psz;
 | 
|---|
| 73 |     int    argi;
 | 
|---|
| 74 | 
 | 
|---|
| 75 |     /* read parameters */
 | 
|---|
| 76 |     for (argi = 1; argi < argc; argi++)
 | 
|---|
| 77 |     {
 | 
|---|
| 78 |         /* check if option or filname */
 | 
|---|
| 79 |         if (argv[argi][0] == '-' || argv[argi][0] == '/')
 | 
|---|
| 80 |         {   /* option */
 | 
|---|
| 81 |             switch (argv[argi][1])
 | 
|---|
| 82 |             {
 | 
|---|
| 83 |                 case 'h': /* syntax help */
 | 
|---|
| 84 |                 case 'H':
 | 
|---|
| 85 |                 case '?':
 | 
|---|
| 86 |                     syntax();
 | 
|---|
| 87 |                     return 1;
 | 
|---|
| 88 | 
 | 
|---|
| 89 |                 case 'w': /* warning level */
 | 
|---|
| 90 |                 case 'W':
 | 
|---|
| 91 |                     psz = argv[argi] + (argv[argi][2] == ':' || argv[argi][2] == '=') + 2;
 | 
|---|
| 92 |                     if (*psz >= '0' && *psz <= '4' && psz[1] == '\0')
 | 
|---|
| 93 |                     {
 | 
|---|
| 94 |                         switch (*psz)
 | 
|---|
| 95 |                         {
 | 
|---|
| 96 |                             case '0': ModuleBase::ulInfoLevel = ModuleBase::Quiet; break;
 | 
|---|
| 97 |                             case '1': ModuleBase::ulInfoLevel = ModuleBase::Error; break;
 | 
|---|
| 98 |                             case '2': ModuleBase::ulInfoLevel = ModuleBase::Warning; break;
 | 
|---|
| 99 |                             case '3': ModuleBase::ulInfoLevel = ModuleBase::Info; break;
 | 
|---|
| 100 |                             case '4': ModuleBase::ulInfoLevel = ModuleBase::InfoAll; break;
 | 
|---|
| 101 |                         }
 | 
|---|
| 102 |                     }
 | 
|---|
| 103 |                     else
 | 
|---|
| 104 |                     {
 | 
|---|
| 105 |                         printf("Syntax error: Incorrect use of argument '%.2s'.\n\n", argv[argi]);
 | 
|---|
| 106 |                         return 5;
 | 
|---|
| 107 |                     }
 | 
|---|
| 108 |                     break;
 | 
|---|
| 109 | 
 | 
|---|
| 110 |                 default:
 | 
|---|
| 111 |                     printf("Syntax error: Invalid argument, '%s'\n", argv[argi]);
 | 
|---|
| 112 |                     syntax();
 | 
|---|
| 113 |                     return 2;
 | 
|---|
| 114 |             }
 | 
|---|
| 115 |         }
 | 
|---|
| 116 |         else
 | 
|---|
| 117 |         {
 | 
|---|
| 118 |             if (pszElfFilename == NULL)
 | 
|---|
| 119 |             {
 | 
|---|
| 120 |                 pszElfFilename = argv[argi];
 | 
|---|
| 121 |                 /* check if exists */
 | 
|---|
| 122 |                 rc = DosQueryPathInfo(pszElfFilename,FIL_QUERYFULLNAME,
 | 
|---|
| 123 |                                       &szBackupElfFilename[0], sizeof(szBackupElfFilename));
 | 
|---|
| 124 |                 if (rc != NO_ERROR)
 | 
|---|
| 125 |                 {
 | 
|---|
| 126 |                     printf("Fatal error: Can't find Win32-file, '%s'.\n", pszElfFilename);
 | 
|---|
| 127 |                     return 80;
 | 
|---|
| 128 |                 }
 | 
|---|
| 129 |             }
 | 
|---|
| 130 |             else if (pszOS2NIXFilename == NULL)
 | 
|---|
| 131 |                 pszOS2NIXFilename = argv[argi];
 | 
|---|
| 132 |             else
 | 
|---|
| 133 |             {
 | 
|---|
| 134 |                 printf("Syntax error: Too many filenames!\n");
 | 
|---|
| 135 |                 syntax();
 | 
|---|
| 136 |                 return 3;
 | 
|---|
| 137 |             }
 | 
|---|
| 138 |         }
 | 
|---|
| 139 |     } /* for */
 | 
|---|
| 140 | 
 | 
|---|
| 141 |     /* check if enough arguments */
 | 
|---|
| 142 |     if (pszElfFilename == NULL)
 | 
|---|
| 143 |     {
 | 
|---|
| 144 |         printf("Syntax error: No Win32-file specified.\n\n");
 | 
|---|
| 145 |         syntax();
 | 
|---|
| 146 |         return 4;
 | 
|---|
| 147 |     }
 | 
|---|
| 148 | 
 | 
|---|
| 149 |     /* rename files? */
 | 
|---|
| 150 |     if (pszOS2NIXFilename == NULL)
 | 
|---|
| 151 |     {
 | 
|---|
| 152 |         char *pszExt = strrchr(pszElfFilename, '.');
 | 
|---|
| 153 |         if (pszExt == NULL)
 | 
|---|
| 154 |         {
 | 
|---|
| 155 |             printf("warning: Elf-file don't have an extention\n");
 | 
|---|
| 156 |             strcpy(szBackupElfFilename, pszElfFilename);
 | 
|---|
| 157 |             strcat(szBackupElfFilename, "ebk");
 | 
|---|
| 158 |         }
 | 
|---|
| 159 |         else
 | 
|---|
| 160 |         {
 | 
|---|
| 161 |             memset(szBackupElfFilename, 0, sizeof(szBackupElfFilename));
 | 
|---|
| 162 |             if (stricmp(pszExt + 1, "exe") == 0)
 | 
|---|
| 163 |             {
 | 
|---|
| 164 |                 strncpy(szBackupElfFilename, pszElfFilename, pszExt - pszElfFilename + 1);
 | 
|---|
| 165 |                 strcat(szBackupElfFilename, "exf");
 | 
|---|
| 166 |             }
 | 
|---|
| 167 |             else
 | 
|---|
| 168 |             {
 | 
|---|
| 169 |                 strncpy(szBackupElfFilename, pszElfFilename, pszExt - pszElfFilename + 3);
 | 
|---|
| 170 |                 strcat(szBackupElfFilename, "k");
 | 
|---|
| 171 |             }
 | 
|---|
| 172 |         }
 | 
|---|
| 173 |         rc = DosMove(pszElfFilename, szBackupElfFilename);
 | 
|---|
| 174 |         if (rc != NO_ERROR)
 | 
|---|
| 175 |         {
 | 
|---|
| 176 |             printf("Fatal error: Failed to rename the Elf-file, %s -> %s\n",
 | 
|---|
| 177 |                     pszElfFilename, szBackupElfFilename);
 | 
|---|
| 178 |             return 81;
 | 
|---|
| 179 |         }
 | 
|---|
| 180 |         printInf(("Backuped %s to %s\n", pszElfFilename, szBackupElfFilename));
 | 
|---|
| 181 | 
 | 
|---|
| 182 |         /* switch name */
 | 
|---|
| 183 |         pszOS2NIXFilename = pszElfFilename;
 | 
|---|
| 184 |         pszElfFilename = szBackupElfFilename;
 | 
|---|
| 185 |     }
 | 
|---|
| 186 | 
 | 
|---|
| 187 |     /* open input file */
 | 
|---|
| 188 |     HFILE hFileWin32;
 | 
|---|
| 189 | 
 | 
|---|
| 190 |     rc = DosOpen(pszElfFilename, &hFileWin32, &ulAction, 0UL,
 | 
|---|
| 191 |                  FILE_NORMAL,
 | 
|---|
| 192 |                  OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
 | 
|---|
| 193 |                  OPEN_FLAGS_RANDOMSEQUENTIAL | OPEN_ACCESS_READONLY | OPEN_SHARE_DENYWRITE,
 | 
|---|
| 194 |                  NULL);
 | 
|---|
| 195 |     if (rc == NO_ERROR)
 | 
|---|
| 196 |     {
 | 
|---|
| 197 |         Elf2Lx elf2lx(hFileWin32);
 | 
|---|
| 198 |         rc = elf2lx.init(pszOS2NIXFilename);
 | 
|---|
| 199 |         if (rc == NO_ERROR)
 | 
|---|
| 200 |         {
 | 
|---|
| 201 |             rc = elf2lx.writeFile(pszOS2NIXFilename);
 | 
|---|
| 202 |             if (rc != NO_ERROR)
 | 
|---|
| 203 |             {
 | 
|---|
| 204 |                 printf("Fatal error: Failed to write the Lx-file. rc=%d\n", rc);
 | 
|---|
| 205 |                 rc = 84;
 | 
|---|
| 206 |             }
 | 
|---|
| 207 |             elf2lx.dumpVirtualLxFile();
 | 
|---|
| 208 |         }
 | 
|---|
| 209 |         else
 | 
|---|
| 210 |         {
 | 
|---|
| 211 |             printf("Fatal error: Failed to convertert the file. rc=%d\n", rc);
 | 
|---|
| 212 |             rc = 83;
 | 
|---|
| 213 |         }
 | 
|---|
| 214 |         DosClose(hFileWin32);
 | 
|---|
| 215 |     }
 | 
|---|
| 216 |     else
 | 
|---|
| 217 |     {
 | 
|---|
| 218 |         printf("Fatal error: Failed to open Elf-file, %s. rc=%d\n",
 | 
|---|
| 219 |                 pszElfFilename, rc);
 | 
|---|
| 220 |         rc = 82;
 | 
|---|
| 221 |     }
 | 
|---|
| 222 |     return (int)rc;
 | 
|---|
| 223 | }
 | 
|---|
| 224 | 
 | 
|---|
| 225 | 
 | 
|---|
| 226 | /**
 | 
|---|
| 227 |  * Display syntax for this program.
 | 
|---|
| 228 |  * @status    completely implemented.
 | 
|---|
| 229 |  * @author    knut st. osmundsen
 | 
|---|
| 230 |  */
 | 
|---|
| 231 | static void syntax()
 | 
|---|
| 232 | {
 | 
|---|
| 233 |     printf("Syntax: elf2lx.exe -W<0|1|2|3> <ElfFile> [OS2NIXFile]\n"
 | 
|---|
| 234 |            "\n"
 | 
|---|
| 235 |            "  -W<0|1|2|3|4> Message filter level.\n"
 | 
|---|
| 236 |            "                   -W0: Output only severe and unrecoverable error messages.\n"
 | 
|---|
| 237 |            "                   -W1: Output error, severe and unrecoverable error messages.\n"
 | 
|---|
| 238 |            "                   -W2: Output warning, error, severe and unrecoverable error\n"
 | 
|---|
| 239 |            "                        messages.\n"
 | 
|---|
| 240 |            "                   -W3: Output nearly all messages.\n"
 | 
|---|
| 241 |            "                   -W4: Output absolutely all messages.\n"
 | 
|---|
| 242 |            "                Default: -W3\n"
 | 
|---|
| 243 |            "  ElfFile       Input Elf executable or share library file.\n"
 | 
|---|
| 244 |            "  OS2NIXFile    Output OS2NIX-file. If not specified the Elf-file is\n"
 | 
|---|
| 245 |            "                renamed and the OS2NIX-file will use the original name\n"
 | 
|---|
| 246 |            "                of the Elf-file.\n"
 | 
|---|
| 247 |            " Elf2Lx version 0.%02d\n",
 | 
|---|
| 248 |            0
 | 
|---|
| 249 |            );
 | 
|---|
| 250 | }
 | 
|---|
| 251 | 
 | 
|---|
| 252 | 
 | 
|---|
| 253 | 
 | 
|---|
| 254 | #if 0
 | 
|---|
| 255 | /**
 | 
|---|
| 256 |  * Debug - see how much of the stack that have been used.
 | 
|---|
| 257 |  * Padd stack, and look in the debug storage view on program end.
 | 
|---|
| 258 |  * @param
 | 
|---|
| 259 |  * @status
 | 
|---|
| 260 |  * @author    knut st. osmundsen
 | 
|---|
| 261 |  */
 | 
|---|
| 262 | static void initStack()
 | 
|---|
| 263 | {
 | 
|---|
| 264 |     PTIB  pTib;
 | 
|---|
| 265 |     PPIB  pPib;
 | 
|---|
| 266 | 
 | 
|---|
| 267 |     DosGetInfoBlocks(&pTib, &pPib);
 | 
|---|
| 268 |     memset((PVOID)pTib->tib_pstack, 'k', (size_t)&pTib - 0x30 - (size_t)pTib->tib_pstack);
 | 
|---|
| 269 | }
 | 
|---|
| 270 | #endif
 | 
|---|