Index: trunk/src/emx/src/emximp/emximp.c
===================================================================
--- trunk/src/emx/src/emximp/emximp.c	(revision 914)
+++ trunk/src/emx/src/emximp/emximp.c	(revision 915)
@@ -30,4 +30,5 @@
 #include <time.h>
 #include <sys/moddef.h>
+#include <sys/types.h>
 #include <a_out.h>
 #include "defs.h"
@@ -67,5 +68,9 @@
   M_DEF_TO_IMP,                 /* .def -> .imp */
   M_DEF_TO_A,                   /* .def -> .a */
-  M_DEF_TO_LIB                  /* .def -> .lib */
+  M_DEF_TO_LIB,                 /* .def -> .lib */
+  M_DLL_TO_IMP,                 /* .dll -> .imp */
+  M_DLL_TO_A,                   /* .dll -> .a */
+  M_DLL_TO_LIB,                 /* .dll -> .lib */
+  M_DLL_TO_DEF                  /* .dll -> .def */
 };
 
@@ -90,4 +95,5 @@
 static char lib_errmsg[512];
 static char *module_name = NULL;
+static char *description;
 
 
@@ -109,9 +115,13 @@
   puts ("  emximp [-m] -o <output_file>.a <input_file>.imp ...");
   puts ("  emximp [-m] -o <output_file>.a <input_file>.lib ...");
-  puts ("  emximp -o <output_file>.def <input_file>.imp ...");
+  puts ("  emximp [-m] -o <output_file>.a <input_file>.dll ...");
   puts ("  emximp -o <output_file>.imp <input_file>.def ...");
   puts ("  emximp -o <output_file>.imp <input_file>.lib ...");
+  puts ("  emximp -o <output_file>.imp <input_file>.dll ...");
   puts ("  emximp [-p#] -o <output_file>.lib <input_file>.def ...");
   puts ("  emximp [-p#] -o <output_file>.lib <input_file>.imp...");
+  puts ("  emximp [-p#] -o <output_file>.lib <input_file>.dll ...");
+  puts ("  emximp -o <output_file>.def <input_file>.imp ...");
+  puts ("  emximp -o <output_file>.def <input_file>.dll ...");
   puts ("Options:");
   puts ("  -p#  Set page size");
@@ -1032,9 +1042,226 @@
 }
 
+/**
+ * Reads a LX nametable.
+ */
+static void dll_read_names(FILE *phFile, off_t off, int fResident, int fOrdinal0Only, const char *pszFilename)
+{
+    char            szName[256];
+    unsigned        cchName;
+    unsigned        iOrd = 0;
+
+    if (fseek(phFile, off, SEEK_SET))
+        error("`%s': Bad LX format\n", pszFilename);
+
+
+    /* first name is module name / description. */
+    cchName = (unsigned)fgetc(phFile);
+    if (!cchName)
+        error("`%s': Bad LX format\n", pszFilename);
+    iOrd = 0;
+    if (    fread(szName, 1, cchName, phFile) != cchName
+        ||  fread(&iOrd, 1, 2, phFile) != 2)
+        error("`%s': Bad LX format\n", pszFilename);
+    if (iOrd != 0)
+        error("`%s': Bad LX format - expect 0 as first ordinal, found %d\n", pszFilename, iOrd);
+
+    szName[cchName] = '\0';
+    if (fResident)
+        module_name = xstrdup(szName);
+    else
+        description = xstrdup(szName);
+
+    if (fOrdinal0Only)
+        return;
+
+    /* The rest of the names are export names. */
+    for (;;)
+    {
+        cchName = (unsigned)fgetc(phFile);
+        if (!cchName)
+            break;
+        iOrd = 0;
+        if (    fread(szName, 1, cchName, phFile) != cchName
+            ||  fread(&iOrd, 1, 2, phFile) != 2)
+            error("`%s': Bad LX format\n", pszFilename);
+        szName[cchName] = '\0';
+
+        switch (mode)
+        {
+            case M_DLL_TO_IMP:
+                if (!fResident)
+                    fprintf(out_file, "%-23s %-8s %3u ?\n",   szName, module_name, iOrd);
+                else
+                    fprintf(out_file, "%-23s %-8s %-23s ?\n", szName, module_name, szName);
+                if (ferror(out_file))
+                    write_error(out_fname);
+                break;
+            case M_DLL_TO_A:
+                if (!fResident)
+                    write_a_import(szName, module_name, iOrd, NULL);
+                else
+                    write_a_import(szName, module_name, 0, szName);
+                break;
+            case M_DLL_TO_LIB:
+                if (!fResident)
+                    write_lib_import(szName, module_name, iOrd, NULL);
+                else
+                    write_lib_import(szName, module_name, 0, szName);
+                break;
+            case M_DLL_TO_DEF:
+                if (!fResident)
+                    fprintf(out_file, "  \"%s\" @%d\n", szName, iOrd);
+                else
+                    fprintf(out_file, "  \"%s\"\n", szName);
+                if (ferror(out_file))
+                    write_error(out_fname);
+                break;
+            default:
+                abort ();
+        }
+    } /* read restable loop */
+}
+
+/** reads a dll */
+static void read_dll(const char *pszFilename)
+{
+#pragma pack(1)
+#define EMAGIC 0x5A4D
+    struct
+    {
+        unsigned short e_magic;
+        unsigned short e_cblp;
+        unsigned short e_cp;
+        unsigned short e_crlc;
+        unsigned short e_cparhdr;
+        unsigned short e_minalloc;
+        unsigned short e_maxalloc;
+        unsigned short e_ss;
+        unsigned short e_sp;
+        unsigned short e_csum;
+        unsigned short e_ip;
+        unsigned short e_cs;
+        unsigned short e_lfarlc;
+        unsigned short e_ovno;
+        unsigned long  e_sym_tab;
+        unsigned short e_flags;
+        unsigned short e_res;
+        unsigned short e_oemid;
+        unsigned short e_oeminfo;
+        unsigned short e_res2[10];
+        unsigned long  e_lfanew;
+    }           doshdr;
+
+#define E32MAGIC    0x584c /* LX */
+#define E32MODDLL        0x08000L
+#define E32MODPROTDLL    0x18000L
+#define E32MODMASK       0x38000L
+#define E32LIBINIT       0x0004L
+#define E32LIBTERM       0x40000000L
+    struct
+    {
+        unsigned char   e32_magic[2];
+        unsigned char   e32_border;
+        unsigned char   e32_worder;
+        unsigned long   e32_level;
+        unsigned short  e32_cpu;
+        unsigned short  e32_os;
+        unsigned long   e32_ver;
+        unsigned long   e32_mflags;
+        unsigned long   e32_mpages;
+        unsigned long   e32_startobj;
+        unsigned long   e32_eip;
+        unsigned long   e32_stackobj;
+        unsigned long   e32_esp;
+        unsigned long   e32_pagesize;
+        unsigned long   e32_pageshift;
+        unsigned long   e32_fixupsize;
+        unsigned long   e32_fixupsum;
+        unsigned long   e32_ldrsize;
+        unsigned long   e32_ldrsum;
+        unsigned long   e32_objtab;
+        unsigned long   e32_objcnt;
+        unsigned long   e32_objmap;
+        unsigned long   e32_itermap;
+        unsigned long   e32_rsrctab;
+        unsigned long   e32_rsrccnt;
+        unsigned long   e32_restab;
+        unsigned long   e32_enttab;
+        unsigned long   e32_dirtab;
+        unsigned long   e32_dircnt;
+        unsigned long   e32_fpagetab;
+        unsigned long   e32_frectab;
+        unsigned long   e32_impmod;
+        unsigned long   e32_impmodcnt;
+        unsigned long   e32_impproc;
+        unsigned long   e32_pagesum;
+        unsigned long   e32_datapage;
+        unsigned long   e32_preload;
+        unsigned long   e32_nrestab;
+        unsigned long   e32_cbnrestab;
+        unsigned long   e32_nressum;
+        unsigned long   e32_autodata;
+        unsigned long   e32_debuginfo;
+        unsigned long   e32_debuglen;
+        unsigned long   e32_instpreload;
+        unsigned long   e32_instdemand;
+        unsigned long   e32_heapsize;
+        unsigned long   e32_stacksize;
+        unsigned char   e32_res3[20];
+    }           os2hdr;
+#pragma pack()
+    off_t       offLX;
+    FILE       *phFile = fopen(pszFilename, "rb");
+
+    if (!phFile)
+        error("Cannot open input file `%s'", pszFilename);
+
+    /* stub header */
+    if (fread(&doshdr, 1, sizeof(doshdr), phFile) != sizeof(doshdr))
+        error("Error read error while reading `%s'\n", pszFilename);
+    if (doshdr.e_magic != EMAGIC && doshdr.e_magic != E32MAGIC)
+        error("`%s' is not a LX DLL\n", pszFilename);
+    offLX = doshdr.e_magic == EMAGIC ? doshdr.e_lfanew : 0;
+
+    /* LX header */
+    if (fseek(phFile, offLX, SEEK_SET))
+        error("Bad LX .DLL `%s'\n", pszFilename);
+    if (fread(&os2hdr, 1, sizeof(os2hdr), phFile) != sizeof(os2hdr))
+        error("Error read error while reading `%s'\n", pszFilename);
+    if (*(unsigned short*)os2hdr.e32_magic != E32MAGIC || !os2hdr.e32_restab)
+        error("`%s': Bad LX format\n", pszFilename);
+    if (   (os2hdr.e32_mflags & E32MODMASK) != E32MODDLL
+        && (os2hdr.e32_mflags & E32MODMASK) != E32MODPROTDLL)
+        error("`%s': Not a LX DLL\n", pszFilename);
+
+    /* Read the tables. */
+    if (mode == M_DLL_TO_DEF && !first_module)
+    {
+        dll_read_names(phFile, os2hdr.e32_restab + offLX, 1, 1, pszFilename);
+        dll_read_names(phFile, os2hdr.e32_nrestab, 0, 1, pszFilename);
+
+        first_module = xstrdup(module_name);
+        fprintf(out_file, "LIBRARY %s", first_module);
+        fprintf(out_file, (os2hdr.e32_mflags & E32LIBINIT) ? " INITINSTANCE" : " INITGLOBAL");
+        fprintf(out_file, (os2hdr.e32_mflags & E32LIBTERM) ? " TERMINSTANCE" : " TERMGLOBAL");
+        fprintf(out_file, "\n");
+        if (description)
+            fprintf(out_file, "DESCRIPTION '%s'\n", description);
+        fprintf(out_file, "EXPORTS\n");
+        if (ferror(out_file))
+          write_error(out_fname);
+    }
+    dll_read_names(phFile, os2hdr.e32_restab + offLX, 1, 0, pszFilename);
+    if (os2hdr.e32_nrestab)
+        dll_read_names(phFile, os2hdr.e32_nrestab, 0, 0, pszFilename);
+
+    fclose(phFile);
+}
+
 
 int main (int argc, char *argv[])
 {
   int i, c;
-  int imp_count, lib_count, def_count, page_size;
+  int imp_count, lib_count, def_count, dll_count, page_size;
   struct predef *pp1;
   char *q, *ext, *opt_o;
@@ -1090,5 +1317,5 @@
         }
     }
-  imp_count = 0; lib_count = 0; def_count = 0;
+  imp_count = 0; lib_count = 0; def_count = 0; dll_count = 0;
   for (i = optind; i < argc; ++i)
     {
@@ -1100,10 +1327,12 @@
       else if (ext != NULL && stricmp (ext, ".def") == 0)
         ++def_count;
+      else if (ext != NULL && stricmp (ext, ".dll") == 0)
+        ++dll_count;
       else
         error ("Input file `%s' has unknown file name extension", argv[i]);
     }
-  if (imp_count == 0 && lib_count == 0 && def_count == 0)
+  if (imp_count == 0 && lib_count == 0 && def_count == 0 && dll_count == 0)
     usage ();
-  if ((imp_count != 0) + (lib_count != 0) + (def_count != 0) > 1)
+  if ((imp_count != 0) + (lib_count != 0) + (def_count != 0) + (dll_count != 0) > 1)
     error ("More than one type of input files");
   if (opt_o == NULL)
@@ -1115,4 +1344,7 @@
         error ("Cannot convert .def files to %s files",
                (as_name == NULL ? ".s" : ".o"));
+      if (dll_count != 0)
+        error ("Cannot convert .dll files to %s files",
+               (as_name == NULL ? ".s" : ".o"));
       mode = M_IMP_TO_S;
     }
@@ -1124,5 +1356,7 @@
           if (imp_count != 0)
             error ("Cannot convert .imp files to .imp file");
-          if (lib_count != 0)
+          if (dll_count != 0)
+            mode = M_DLL_TO_IMP;
+          else if (lib_count != 0)
             mode = M_LIB_TO_IMP;
           else
@@ -1131,5 +1365,7 @@
       else if (ext != NULL && stricmp (ext, ".a") == 0)
         {
-          if (def_count != 0)
+          if (dll_count != 0)
+            mode = M_DLL_TO_A;
+          else if (def_count != 0)
             mode = M_DEF_TO_A;
           else if (imp_count != 0)
@@ -1144,5 +1380,8 @@
           if (lib_count != 0)
             error ("Cannot convert .lib files to .def file");
-          mode = M_IMP_TO_DEF;
+          if (dll_count != 0)
+            mode = M_DLL_TO_DEF;
+          else
+            mode = M_IMP_TO_DEF;
         }
       else if (ext != NULL && stricmp (ext, ".lib") == 0)
@@ -1150,5 +1389,7 @@
           if (lib_count != 0)
             error ("Cannot convert .lib files to .lib file");
-          if (def_count != 0)
+          if (dll_count != 0)
+            mode = M_DLL_TO_LIB;
+          else if (def_count != 0)
             mode = M_DEF_TO_LIB;
           else
@@ -1172,5 +1413,5 @@
       usage ();
   if (profile_flag && mode != M_DEF_TO_A && mode != M_IMP_TO_A
-      && mode != M_LIB_TO_A)
+      && mode != M_LIB_TO_A && mode != M_DEF_TO_A)
     usage ();
   switch (mode)
@@ -1243,4 +1484,37 @@
         lib_error ();
       break;
+    case M_DLL_TO_A:
+      create_output_file (TRUE);
+      init_archive ();
+      for (i = optind; i < argc; ++i)
+        read_dll (argv[i]);
+      close_output_file ();
+      break;
+    case M_DLL_TO_IMP:
+      create_output_file (FALSE);
+      for (i = optind; i < argc; ++i)
+        read_dll (argv[i]);
+      close_output_file ();
+      break;
+    case M_DLL_TO_LIB:
+      out_lib = omflib_create (out_fname, page_size, lib_errmsg);
+      if (out_lib == NULL)
+        lib_error ();
+      if (omflib_header (out_lib, lib_errmsg) != 0)
+        lib_error ();
+      for (i = optind; i < argc; ++i)
+        read_dll (argv[i]);
+      if (omflib_finish (out_lib, lib_errmsg) != 0
+          || omflib_close (out_lib, lib_errmsg) != 0)
+        lib_error ();
+      break;
+
+    case M_DLL_TO_DEF:
+      create_output_file (FALSE);
+      for (i = optind; i < argc; ++i)
+        read_dll (argv[i]);
+      close_output_file ();
+      break;
+
     default:
       usage ();
