Index: /trunk/src/emx/src/emxomf/emxomfld.c
===================================================================
--- /trunk/src/emx/src/emxomf/emxomfld.c	(revision 941)
+++ /trunk/src/emx/src/emxomf/emxomfld.c	(revision 942)
@@ -47,4 +47,5 @@
 {
   struct name_list *next;
+  unsigned flags;
   char *name;
 } name_list;
@@ -89,5 +90,7 @@
    command line is added to this list.  The -l option also adds an
    entry to this list. add_lib_fnames is used to add another entry at
-   the end of the list. */
+   the end of the list.
+   The flags member indicates library search method. If set search for
+   static lib, if clear search for shared lib before search for static lib. */
 static name_list *lib_fnames = NULL;
 static name_list **add_lib_fnames = &lib_fnames;
@@ -163,5 +166,5 @@
 extern void *xrealloc (void *ptr, size_t n);
 extern char *xstrdup (const char *s);
-static void add_name_list (name_list ***add, const char *src);
+static void add_name_list (name_list ***add, const char *src, unsigned flags);
 static void conv_path (char *name);
 static void put_arg (const char *src, int path, int quotable);
@@ -234,13 +237,14 @@
    list. */
 
-static void add_name_list (name_list ***add, const char *src)
-{
-  name_list *new;
-
-  new = xmalloc (sizeof (name_list));
-  new->next = NULL;
-  new->name = xstrdup (src);
-  *(*add) = new;
-  (*add) = &new->next;
+static void add_name_list (name_list ***add, const char *src, unsigned flags)
+{
+  name_list *node;
+
+  node = xmalloc (sizeof (name_list));
+  node->next  = NULL;
+  node->name  = xstrdup (src);
+  node->flags = flags;
+  *(*add) = node;
+  (*add) = &node->next;
 }
 
@@ -469,57 +473,115 @@
 }
 
-/* Check if the given file is a valid OMF library. */
-
-static int check_omf_library (FILE *f)
+/**
+ * Checks if the stream phFile is an OMF library.
+ *
+ * @returns 1 if OMF library.
+ * @returns 0 if not OMF library.
+ * @param   phFile  Filestream to check.
+ */
+static int check_omf_library(FILE *phFile)
 {
 #pragma pack(1)
-  struct
-  {
-    byte rec_type;
-    word rec_len;
-    dword dict_offset;
-    word dict_blocks;
-    byte flags;
-  } libhdr;
+    struct
+    {
+        byte rec_type;
+        word rec_len;
+        dword dict_offset;
+        word dict_blocks;
+        byte flags;
+    } libhdr;
 #pragma pack()
 
-  if (fread (&libhdr, 1, sizeof(libhdr), f) == sizeof (libhdr)
-   && !fseek (f, 0, SEEK_SET)
-   && libhdr.rec_type == LIBHDR
-   && libhdr.flags <= 1 /* ASSUME only first bit is used... */
-      )
-    {
-      int page_size = libhdr.rec_len + 3;
-      if (page_size >= 16
-       && page_size <= 32768
-       && !(page_size & (page_size - 1)) != 0)
+    if (    fread(&libhdr, 1, sizeof(libhdr), phFile) == sizeof (libhdr)
+        &&  !fseek(phFile, 0, SEEK_SET)
+        &&  libhdr.rec_type == LIBHDR
+        &&  libhdr.flags <= 1 /* ASSUME only first bit is used... */
+       )
+    {
+        int page_size = libhdr.rec_len + 3;
+        if (page_size >= 16
+            && page_size <= 32768
+            && !(page_size & (page_size - 1)) != 0)
+            return 1;
+    }
+    return 0;
+}
+
+
+/**
+ * Checks if the stream phFile is an OMF object or library.
+ *
+ * @returns 1 if OMF.
+ * @returns 0 if not OMF.
+ * @param   phFile  Filestream to check.
+ */
+static int check_omf(FILE *phFile)
+{
+#pragma pack(1)
+    struct
+    {
+        byte rec_type;
+        word rec_len;
+    } omfhdr;
+#pragma pack()
+    if (    fread(&omfhdr, 1, sizeof(omfhdr), phFile) == sizeof (omfhdr)
+        &&  omfhdr.rec_type == THEADR
+        &&  omfhdr.rec_len >= sizeof(omfhdr)
+        &&  !fseek(phFile, 0, SEEK_SET)
+       )
         return 1;
-    }
-
-  return 0;
-}
-
-
-/* Checks if the file handle is to an omf object or library file. */
-
-static int check_omf (FILE *f)
-{
-#pragma pack(1)
-  struct
-  {
-    byte rec_type;
-    word rec_len;
-  } omfhdr;
-#pragma pack()
-  if (fread (&omfhdr, 1, sizeof(omfhdr), f) == sizeof (omfhdr)
-   && omfhdr.rec_type == THEADR
-   && omfhdr.rec_len >= sizeof(omfhdr)
-   && !fseek (f, 0, SEEK_SET)
-      )
-    {
-      return 1;
-    }
-
-  return !fseek (f, 0, SEEK_SET) && check_omf_library (f);
+
+    return !fseek(phFile, 0, SEEK_SET)
+        && check_omf_library(phFile);
+}
+
+
+/**
+ * Checks if the stream phFile is an LX DLL.
+ *
+ * @returns 1 if LX DLL.
+ * @returns 0 if not LX DLL.
+ * @param   phFile  File stream to check.
+ */
+static int check_lx_dll(FILE *phFile)
+{
+    unsigned long   ul;
+    char            achMagic[2];
+
+    if (    fseek(phFile, 0, SEEK_SET)
+        ||  fread(&achMagic, 1, 2, phFile) != 2)
+        goto thats_not_it;
+
+    if (!memcmp(achMagic, "MZ", 2))
+    {
+        if (    fseek(phFile, 0x3c, SEEK_SET)
+            ||  fread(&ul, 1, 4, phFile) != 4 /* offset of the 'new' header */
+            ||  ul < 0x40
+            ||  ul >= 0x10000000 /* 512MB stubs sure */
+            ||  fseek(phFile, ul, SEEK_SET)
+            ||  fread(&achMagic, 1, 2, phFile) != 2)
+            goto thats_not_it;
+    }
+
+    if (    memcmp(achMagic, "LX", 2)
+        ||  fseek(phFile, 14, SEEK_CUR)
+        ||  fread(&ul, 1, 4, phFile) != 4) /*e32_mflags*/
+        goto thats_not_it;
+
+#define E32MODDLL        0x08000L
+#define E32MODPROTDLL    0x18000L
+#define E32MODMASK       0x38000L
+    if (   (ul & E32MODMASK) != E32MODDLL
+        && (ul & E32MODMASK) != E32MODPROTDLL)
+        goto thats_not_it;
+
+    /* it's a LX DLL! */
+    fseek(phFile, 0, SEEK_SET);
+    return 1;
+
+
+thats_not_it:
+    fseek(phFile, 0, SEEK_SET);
+    return 0;
 }
 
@@ -533,10 +595,12 @@
  * @param   pszPrefix   Prefix.
  * @param   pszSuffix   Suffix.
+ * @param   pszLooklike Filename which name is to be incorporated into the temp filename.
  * @remark  The code is nicked from the weak linker.
  */
-static int      make_tempfile(char *pszFile, const char *pszPrefix, const char *pszSuffix)
+static int      make_tempfile(char *pszFile, const char *pszPrefix, const char *pszSuffix, const char *pszLooklike)
 {
     struct stat     s;
     unsigned        c = 0;
+    char            szLooklike[32];
     pid_t           pid = getpid();
     const char *    pszTmp = getenv("TMP");
@@ -544,4 +608,23 @@
     if (!pszTmp)    pszTmp = getenv("TEMP");
     if (!pszTmp)    pszTmp = ".";
+    if (pszLooklike)
+    {
+        int     cch;
+        char   *psz = (char*)pszLooklike; /* we're nice fellows. */
+        while ((psz = strpbrk(psz, ":/\\")) != NULL)
+            pszLooklike = ++psz;
+        cch = strlen(pszLooklike);
+        if (cch + 3 > sizeof(szLooklike))
+            cch = sizeof(szLooklike) - 3;
+        szLooklike[0] = '_';
+        memcpy(&szLooklike[1], pszLooklike, cch);
+        szLooklike[cch + 1] = '_';
+        szLooklike[cch + 2] = '\0';
+        pszLooklike = psz = &szLooklike[0];
+        while ((psz = strpbrk(psz, ".@%^&#()")) != NULL)
+            *psz++ = '_';
+    }
+    else
+        pszLooklike = "";
 
     do
@@ -551,5 +634,5 @@
             return -1;
         gettimeofday(&tv, NULL);
-        sprintf(pszFile, "%s\\%s%x%lx%d%lx%s", pszTmp, pszPrefix, pid, tv.tv_sec, c, tv.tv_usec, pszSuffix);
+        sprintf(pszFile, "%s\\%s%s%x%lx%d%lx%s", pszTmp, pszPrefix, pszLooklike, pid, tv.tv_sec, c, tv.tv_usec, pszSuffix);
     } while (!stat(pszFile, &s));
 
@@ -558,11 +641,16 @@
 
 
-/* Converts the file indicated by pf & pszFilename to omf closing f and
-   updating filename with the new (temporary filename). A successful
-   return from the function returns a pointe to the filestream for the
-   converted file. On failure NULL is returned, f is closed adn filename
-   is undefined. */
-
-static FILE *aout_to_omf (FILE *pf, char *pszFilename, int fLibrary)
+/**
+ * Converts the file indicated by phFile & pszFilename to omf closing
+ * phFile and updating pszFilename with the new (temporary filename).
+ *
+ * @returns Pointer to an filestream for the converted file and pszFilename
+ *          containing the name of the converted file.
+ * @returns exit the program
+ * @param   phFile      Filestream of the file to convert. (close this)
+ * @param   pszFilename Name of the file to convert on entry.
+ *                      Name of the converted file on return.
+ */
+static FILE *aout_to_omf(FILE *pf, char *pszFilename, int fLibrary)
 {
     int         rc;
@@ -573,6 +661,6 @@
 
     if (opt_t)
-      fprintf(stderr, "emxomfld: info: converting %s %s to OMF.\n",
-              fLibrary ? "lib" : "obj", pszFilename);
+        fprintf(stderr, "emxomfld: info: converting %s %s to OMF.\n",
+                fLibrary ? "lib" : "obj", pszFilename);
 
     /*
@@ -581,5 +669,5 @@
     pName = xmalloc(sizeof(name_list));
     pName->name = pszNewFile = xmalloc(_MAX_PATH);
-    if (make_tempfile(pszNewFile, "ldconv", fLibrary ? ".lib" : ".obj"))
+    if (make_tempfile(pszNewFile, "ldconv", fLibrary ? ".lib" : ".obj", pszFilename))
     {
         free(pszNewFile);
@@ -590,6 +678,5 @@
      * Do the conversion.
      */
-    rc = spawnlp(P_WAIT, "emxomf.exe", "emxomf.exe",
-                 "-o", pszNewFile, pszFilename, NULL);
+    rc = spawnlp(P_WAIT, "emxomf.exe", "emxomf.exe", "-o", pszNewFile, pszFilename, NULL);
     if (!rc)
     {
@@ -605,6 +692,6 @@
 
             if (opt_t)
-              fprintf(stderr, "emxomfld: info: convert result '%s'.\n",
-                      pszFilename);
+                fprintf(stderr, "emxomfld: info: convert result '%s'.\n",
+                        pszFilename);
             return pf;
         }
@@ -614,18 +701,23 @@
     free(pName);
 
-    fprintf (stderr, "emxomfld: a.out to omf conversion failed for '%s'.\n",
-             pszFilename);
-    exit (2);
+    fprintf(stderr, "emxomfld: a.out to omf conversion failed for '%s'.\n",
+            pszFilename);
+    exit(1);
     return NULL;
 }
 
 
-/* Converts the file indicated by pf & pszFilename to omf closing f and
-   updating filename with the new (temporary filename). A successful
-   return from the function returns a pointe to the filestream for the
-   converted file. On failure NULL is returned, f is closed adn filename
-   is undefined. */
-
-static FILE *lx_to_omf (FILE *pf, char *pszFilename)
+/**
+ * Converts the file indicated by phFile & pszFilename to omf closing
+ * phFile and updating pszFilename with the new (temporary filename).
+ *
+ * @returns Pointer to an filestream for the converted file and pszFilename
+ *          containing the name of the converted file.
+ * @returns exit the program
+ * @param   phFile      Filestream of the file to convert. (close this)
+ * @param   pszFilename Name of the file to convert on entry.
+ *                      Name of the converted file on return.
+ */
+static FILE *lx_to_omf(FILE *pf, char *pszFilename)
 {
     int         rc;
@@ -636,6 +728,6 @@
 
     if (opt_t)
-      fprintf(stderr, "emxomfld: info: converting %s %s to an OMF import lib.\n",
-             "lib", pszFilename);
+        fprintf(stderr, "emxomfld: info: converting %s %s to an OMF import lib.\n",
+                "lib", pszFilename);
 
     /*
@@ -644,5 +736,5 @@
     pName = xmalloc(sizeof(name_list));
     pName->name = pszNewFile = xmalloc(_MAX_PATH);
-    if (make_tempfile(pszNewFile, "ldconv", ".lib"))
+    if (make_tempfile(pszNewFile, "ldconv", ".lib", pszFilename))
     {
         free(pszNewFile);
@@ -653,6 +745,5 @@
      * Do the conversion.
      */
-    rc = spawnlp(P_WAIT, "emximp.exe", "emximp.exe",
-                 "-o", pszNewFile, pszFilename, NULL);
+    rc = spawnlp(P_WAIT, "emximp.exe", "emximp.exe", "-o", pszNewFile, pszFilename, NULL);
     if (!rc)
     {
@@ -677,160 +768,239 @@
     free(pName);
 
-    fprintf (stderr, "emxomfld: a.out to omf conversion failed for '%s'.\n",
-             pszFilename);
-    exit (2);
+    fprintf(stderr, "emxomfld: lx dll to omf conversion failed for '%s'.\n",
+            pszFilename);
+    exit(2);
     return NULL;
 }
 
 
-
-/* Finds the full path of a OMF library or object file.
-
-   This function may perform conversion from a.out to omf if that feature
-   is enabled.
-
-   Object files and libraries will be searched for using the LIB env.var
-   (which is exported so that it is used by ILINK/LINK386 as well),
-   if not found by their path directly. Note that finding object files in
-   the LIB paths contradicts the standard Unix behaviour, so it is a kind
-   of a hack, but this is the way ILINK and LINK386 work.
-
-   If file has no extension, the .obj and .o extensions are tried in turn
-   for object files, and .lib then .a are tried in turn for libraries.
-   Additionaly, for libraries we check for a file with the 'lib' prefix,
-   if one without the 'lib' prefix was not found. The '.o' and '.a'
-   extensions are tried in the last case since otherwise we can find
-   a 'something.a' when 'libsomething.lib' is available.
-
-   We support linking with DLLs if they have a path as we're not yet ready
-   to start searching for them or anything of that kind of real UNIXy
-   behaviour.
-
-   Returns pointer to file stream and FULLNAME set to it's name on success.
-   Returns NULL and FULLNAME a copy of NAME on failure.
-   */
-
-static FILE *find_objlib (char *fullname, const char *name, int is_library)
-{
-  static const char *exts [2][2] = { { ".obj", ".o" }, { ".lib", ".a" } };
-  FILE *f;
-  size_t pathlen, namelen = strlen (name);
-  const char *libpath, *x;
-  int i, has_ext = 0, is_dll = 0, has_path;
-
-  /* Check if the file name has a path. If it has, we won't check the
-     LIB directories, and won't check if it has a object file extension. */
-  has_path = (strpbrk (name, ":/\\") != NULL);
-  if (has_path)
-    {
-      has_ext = 1;
-      x = strrchr (name, '.');
-      if (x && !stricmp(x, ".dll"))
-        is_dll = 1;
-    }
-  else
-    {
-      /* Check if file has a real extension. If it is a object file it should
-         have either .o or .obj, and if it is a library it should have either
-         the .a or .lib extension. Otherwise we don't consider it a extension. */
-      x = strrchr (name, '.');
-      if (x)
-        for (i = 0; i < 2; i++)
-          if (!stricmp (x, exts [is_library][i]))
+/**
+ * Finds the full path of a OMF object file and opens the file.
+ *
+ * This function may perform conversion from a.out to omf if that feature
+ * is enabled.
+ *
+ * We choose to be UNIX compatible her, and not search the LIB env.var.
+ * for unqualified objects. Nor will we add any suffixes to the name
+ * if it's witout any extension.
+ *
+ * @returns Pointer to a file stream for the object file to use in the link.
+ * @returns NULL on failure with pszFullname containing a copy of
+ *          pszName (or something like that).
+ * @param   pszFullname Where to store the name of the file to be used
+ *                      in the linking (and which stream is returned).
+ * @param   pszName     Object name given to on the linker commandline.
+ */
+static FILE *find_obj(char *pszFullname, const char *pszName)
+{
+    FILE   *phFile;
+    char   *psz;
+
+    /*
+     * Make abspath with slashes the desired way and such.
+     */
+    if (_abspath(pszFullname, pszName, _MAX_PATH + 1))
+    {
+        printf("emxomfld: _abspath failed on '%s'!!!\n", pszName);
+        exit(1);
+    }
+
+    psz = pszFullname;
+    while ((psz = strchr(psz, '/')) != NULL)
+      *psz++ = '\\';
+
+    /*
+     * Try open the file.
+     */
+    phFile = fopen(pszFullname, "rb");
+    if (!phFile)
+        return NULL;
+
+    /*
+     * If autoconversion check if such is needed.
+     */
+    if (    autoconvert_flag
+        &&  !check_omf(phFile))
+        phFile = aout_to_omf(phFile, pszFullname, FALSE);
+
+    return phFile;
+}
+
+
+
+/* Finds the full path of a library file and opens the file.
+ *
+ * This function may perform conversion from a.out to omf if that feature
+ * is enabled.
+ *
+ * The function assumes that LIB has been updated with all the search paths
+ * specified on the commandline.
+ *
+ * Library names with no extension are given extensions after the rules
+ * indicated by the IS_SHARED parameter. If IS_SHARED is set then libraries
+ * with suffixes indicating shared libraries will be looked for before
+ * libraries with suffixes indicated static libraries. The list is as
+ * follows for set IS_SHARED:
+ *      1. _dll.lib
+ *      2. .lib
+ *      3. .dll
+ *      4. _s.lib
+ *
+ * If IS_SHARED is clear:
+ *      1. _s.lib
+ *      2. .lib
+ *
+ * Library names with no path is searched for in the semicolon separated list
+ * of paths the env.var. LIB contains. For each directory in LIB we'll start
+ * by see if it contains a 'lib' prefixed file, if not found we'll check for
+ * the unprefixed filename. If we're appending suffixes too, we'll loop thru
+ * all the possible suffixes for each directory before advancing to the next,
+ * having the prefixing as the inner most loop.
+ *
+ * @returns Pointer to a file stream for the library file to use in the link.
+ * @returns NULL on failure with pszFullname containing a copy of
+ *          pszName (or something like that).
+ * @param   pszFullname Where to store the name of the file to be used
+ *                      in the linking (and which stream is returned).
+ * @param   pszName     Library name given to on the linker commandline.
+ */
+static FILE *find_lib(char *pszFullname, const char *pszName, int fShared)
+{
+    /* Suffix list for shared linking. */
+    static const char *apszSharedSuff[]     = { "_dll.lib", "_dll.a", ".lib",  ".a", ".dll", "_s.lib", "_s.a", NULL };
+    /* Suffix list for static linking. */
+    static const char *apszStaticSuff[]     = { "_s.lib", "_s.a", ".lib",  ".a", NULL };
+    /* Suffix list for names with extension. */
+    static const char *apszExtensionSuff[]  = { "", NULL };
+    /* Prefix list for names with path. */
+    static const char *apszWithPathPref[]   = { "", NULL };
+    /* Prefix list for names with no path. */
+    static const char *apszWithoutPathPref[]= { "lib", "", NULL };
+    int             fPath;              /* set if the library name have a path. */
+    int             fExt;               /* set if the library name have an extension. */
+    const char    **papszSuffs;         /* Pointer to the suffix list. */
+    const char    **papszPrefs;         /* Pointer to the prefix list. */
+    const char     *pszLibPath;         /* The path we're searching. */
+    size_t          cchCurPath;         /* Size of the current path. */
+    size_t          cchName = strlen(pszName);
+    const char     *psz;
+
+    /*
+     * Check if the file name has a path.
+     * (If it has, we won't check the LIB directories.)
+     * Choose the prefix list accordingly.
+     */
+    fPath = (strpbrk(pszName, ":/\\") != NULL);
+    papszPrefs = fPath ? apszWithPathPref : apszWithoutPathPref;
+
+    /*
+     * Check if the file has a real extension.
+     * Real extension means, .lib, .dll or .a. It also implies something
+     * before the dot.
+     * Choose the suffix list accordingly.
+     */
+    fExt = (    (cchName > 4 && !stricmp(pszName + cchName - 4, ".lib"))
+            ||  (cchName > 4 && !stricmp(pszName + cchName - 4, ".dll"))
+            ||  (cchName > 2 && !stricmp(pszName + cchName - 2, ".a")) );
+
+    if (!fExt)
+        papszSuffs = fShared ? &apszSharedSuff[0] : &apszStaticSuff[0];
+    else
+        papszSuffs = apszExtensionSuff;
+
+    /*
+     * Loop 1: LIB (with a fake .\ as the first iteration)
+     * (Looping on pszLibPath, with preinitiated cchCurPath & pszFullname.)
+     */
+    cchCurPath = 0;
+    if (!fPath)
+    {
+        cchCurPath = 2;
+        memcpy(pszFullname, ".\\", 2);
+    }
+    pszLibPath = getenv("LIB");
+    do
+    {
+        /*
+         * Loop2: Suffixes.
+         */
+        int iSuff;
+        for (iSuff = 0; papszSuffs[iSuff]; iSuff++)
+        {
+            /*
+             * Loop3: Prefixes.
+             */
+            int iPref;
+            for (iPref = 0; papszPrefs[iPref]; iPref++)
             {
-              has_ext = 1;
+                FILE   *phFile;
+                int     cch = strlen(papszPrefs[iPref]);
+
+                /*
+                 * Construct name.
+                 */
+                memcpy(&pszFullname[cchCurPath], papszPrefs[iPref], cch);
+                cch = cchCurPath + cch;
+                memcpy(&pszFullname[cch], pszName, cchName);
+                cch += cchName;
+                strcpy(&pszFullname[cch], papszSuffs[iSuff]);
+
+                /*
+                 * Open and if necessary convert it.
+                 */
+                phFile = fopen(pszFullname, "rb");
+                if (phFile)
+                {
+                    if (autoconvert_flag)
+                    {
+                        if (check_lx_dll(phFile))
+                            phFile = lx_to_omf(phFile, pszFullname);
+                        else if (!check_omf(phFile))
+                            phFile = aout_to_omf(phFile, pszFullname, TRUE);
+                    }
+
+                    /* Replace forward slashes with backslashes (link386). */
+                    while ((pszFullname = strchr(pszFullname, '/')) != NULL)
+                      *pszFullname++ = '\\';
+                    return phFile;
+                }
+            } /* next prefix */
+        } /* next suffix */
+
+        /*
+         * If a path was specified or no LIB we're done now.
+         */
+        if (fPath || !pszLibPath)
+            break;
+
+        /*
+         * Next LIB part.
+         */
+        for (;;)
+        {
+            psz = strchr(pszLibPath, ';');
+            if (!psz)
+                psz = strchr(pszLibPath, '\0');
+            cchCurPath = psz - pszLibPath;
+            if (cchCurPath)
+            {
+                memcpy(pszFullname, pszLibPath, cchCurPath);
+                pszLibPath = psz + (*psz == ';');
+                /* Append last slash if it is not there */
+                if (   pszFullname[cchCurPath - 1] != '/'
+                    && pszFullname[cchCurPath - 1] != '\\')
+                    pszFullname[cchCurPath++] = '\\';
+                break;
+              }
+            if (!*psz)
               break;
-            }
-    }
-
-  /* First loop search file name as-is, then search the paths
-     in the LIB environment variable. */
-  libpath = getenv ("LIB");
-  pathlen = 0;
-  if (!has_path)
-    {
-      memcpy(fullname, ".\\", 2);
-      pathlen = 2;
-    }
-  do
-    {
-      /* Step 0: check path+filename (+'.obj/.lib' if !has_ext)
-       * Step 1: if is_library check path+'lib'+filename (+'.lib' if !has_ext)
-       * Step 2: check path+filename (+'.o/.a' if !has_ext)
-       * Step 3: if is_library check path+'lib'+filename (+'.a' if !has_ext)
-       */
-      for (i = 0; i < 4; i++)
-        {
-          char *cur = fullname + pathlen;
-
-          if ((i & 1) && (!is_library || has_path))
-            continue;
-
-          if (i & 1)
-            {
-              memcpy (cur, "lib", 3);
-              cur += 3;
-            }
-
-          /* Include final zero in the case we won't append the extension */
-          memcpy (cur, name, namelen + 1);
-          cur += namelen;
-
-          if (!has_ext)
-            {
-              strcpy (cur, exts [is_library][i/2]);
-              cur = strchr (cur, 0);
-            }
-
-          f = fopen (fullname, "rb");
-          if (f)
-            {
-              if (autoconvert_flag && is_dll && is_library)
-                f = lx_to_omf (f, fullname);
-              else if (autoconvert_flag && !check_omf (f))
-                f = aout_to_omf (f, fullname, is_library);
-
-              if (is_library && !check_omf_library (f) /* not sure if this makes sense */)
-                fclose (f);
-              else
-                {
-                  /* Replace forward slashes with backslashes (link386). */
-                  while ((fullname = strchr (fullname, '/')) != NULL)
-                    *fullname++ = '\\';
-                  return f;
-                }
-            }
+            pszLibPath = psz + 1;
         }
-
-      if (!libpath || has_path)
-        break;
-
-      /* Find the next LIB component.
-         We're skipping empty components. */
-      for (;;)
-        {
-          x = strchr (libpath, ';');
-          if (!x) x = strchr (libpath, 0);
-          pathlen = x - libpath;
-          if (pathlen)
-            {
-              memcpy (fullname, libpath, pathlen);
-              libpath = x + (*x == ';');
-              /* Append last slash if it is not there */
-              if (fullname [pathlen - 1] != '/'
-               && fullname [pathlen - 1] != '\\')
-                fullname [pathlen++] = '\\';
-              break;
-            }
-          if (!*x)
-            break;
-          libpath = x + (*x == ';');
-        }
-    } while (pathlen);
-
-
-  strcpy (fullname, name);
-  return NULL;
-}
+    } while (cchCurPath);
+
+    /* failure */
+    return NULL;
+}
+
 
 /* Weak prelinking for Method 2 Weak support. */
@@ -894,5 +1064,5 @@
       for (pcur = obj_fnames; !rc && pcur; pcur = pcur->next)
         {
-          phfile = find_objlib (szname, pcur->name, FALSE);
+          phfile = find_obj (szname, pcur->name);
           rc = WLDAddObject (pwld, phfile, szname);
         }
@@ -901,5 +1071,5 @@
       for (pcur = lib_fnames; !rc && pcur; pcur = pcur->next)
         {
-          phfile = find_objlib (szname, pcur->name, TRUE);
+          phfile = find_lib (szname, pcur->name, !pcur->flags);
           rc = WLDAddLibrary (pwld, phfile, szname);
           free(pcur->name);
@@ -923,5 +1093,5 @@
         rc = WLDGenerateWeakAliases (pwld, weakobj_fname, weakdef_fname);
       if (!rc && weakobj_fname[0])
-        add_name_list (&add_obj_fnames, weakobj_fname);
+        add_name_list (&add_obj_fnames, weakobj_fname, 0);
       if (!rc && weakdef_fname[0])
         def_fname = weakdef_fname;
@@ -1097,38 +1267,37 @@
 static void usage (void)
 {
-  fprintf (stderr, "emxomfld " VERSION INNOTEK_VERSION "\n"
-           "Copyright (c) 1992-1996 by Eberhard Mattes\n"
-           "Copyright (c) 2003 by InnoTek Systemberatung GmbH\n\n");
-
-  fprintf (stderr,
-           "Usage: emxomfld -o <file> [-l <lib>] [-L <libdir>] [-T <base>] [-igtsS]\n"
-           "                [-Zexe] [-Zdll] [-Zstack <size>] [-Zmap[=<map_file>]]\n"
-           "                [-Z[no-]autoconv] [-O <option>] [-static] [-non_shared]\n"
-           "                [-Bstatic] [-dn] [call_shared] [-Bshared] [-dy] <file>...\n"
-           "\n"
-           "Options:\n"
-           " -Zno-autoconv / -Zautoconv:\n"
-           "    Turns off/on the automatic conversion of a.out libs and objs.\n"
-           "    default: -Zautoconv\n"
-           " -Bstatic, -non_shared, -dn, -static:\n"
-           "    Link with static libraries.\n"
-           "    The search order is then changed to: lib<name>_s.lib, <name>_s.lib,\n"
-           "    lib<name>.lib, <name>.lib\n"
-           " -Bshared, -call_shared, -dy:\n"
-           "    Link with shared libraries. This is default.\n"
-           "    The search order is then changed to: lib<name>_dll.lib, <name>_dll.lib,\n"
-           "    lib<name>.lib, <name>.lib, <name>.dll, lib<name>_s.lib, <name>_s.lib.\n"
-           "\n"
-           "Environment variables:\n"
-           "  EMXOMFLD_TYPE:\n"
-           "    The type of linker we're using. Values: VAC365, VAC308, LINK386.\n"
-           "        VAC365   ilink.exe from IBM C and C++ Compilers for OS/2 v3.6 or later.\n"
-           "        VAC308   ilink.exe from Visual Age for C++ v3.08.\n"
-           "        LINK386  link386 form OS/2 install or DDK.\n"
-           "  EMXOMFLD_LINKER:\n"
-           "    Name of the linker to use and optionally extra parameters. Spaces in the\n"
-           "    linker name or path is not supported. Quotes are not supported either.\n"
-           "The default values for these two variables are VAC365 and ilink.exe.\n"
-           );
+  fputs ("emxomfld " VERSION INNOTEK_VERSION "\n"
+         "Copyright (c) 1992-1996 by Eberhard Mattes\n"
+         "Copyright (c) 2003 by InnoTek Systemberatung GmbH\n"
+         "Copyright (c) 2003-2004 by Knut St. Osmundsen\n"
+         "\n", stderr);
+  fputs ("Usage: emxomfld -o <file> [-l <lib>] [-L <libdir>] [-T <base>] [-igtsS]\n"
+         "                [-Zexe] [-Zdll] [-Zstack <size>] [-Zmap[=<map_file>]]\n"
+         "                [-Z[no-]autoconv] [-O <option>] [-static] [-non_shared]\n"
+         "                [-Bstatic] [-dn] [call_shared] [-Bshared] [-dy] <file>...\n"
+         "\n", stderr);
+  fputs ("Options:\n"
+         " -Zno-autoconv / -Zautoconv:\n"
+         "    Turns off/on the automatic conversion of a.out libs and objs.\n"
+         "    default: -Zautoconv\n"
+         " -Bstatic, -non_shared, -dn, -static:\n"
+         "    Link with static libraries.\n"
+         "    The search order is then changed to: lib<name>_s.lib, <name>_s.lib,\n"
+         "    lib<name>.lib, <name>.lib\n", stderr);
+  fputs (" -Bshared, -call_shared, -dy:\n"
+         "    Link with shared libraries. This is default.\n"
+         "    The search order is then changed to: lib<name>_dll.lib, <name>_dll.lib,\n"
+         "    lib<name>.lib, <name>.lib, <name>.dll, lib<name>_s.lib, <name>_s.lib.\n"
+         "\n", stderr);
+  fputs ("Environment variables:\n"
+         "  EMXOMFLD_TYPE:\n"
+         "    The type of linker we're using. Values: VAC365, VAC308, LINK386.\n"
+         "        VAC365   ilink.exe from IBM C and C++ Compilers for OS/2 v3.6 or later.\n"
+         "        VAC308   ilink.exe from Visual Age for C++ v3.08.\n"
+         "        LINK386  link386 form OS/2 install or DDK.\n", stderr);
+  fputs ("  EMXOMFLD_LINKER:\n"
+         "    Name of the linker to use and optionally extra parameters. Spaces in the\n"
+         "    linker name or path is not supported. Quotes are not supported either.\n"
+         "The default values for these two variables are VAC365 and ilink.exe.\n", stderr);
   exit (1);
 }
@@ -1185,4 +1354,5 @@
   char execname[512];
   name_list *pcur;
+  int   opt_libs_static = 0;
   int   longind;
 
@@ -1205,5 +1375,4 @@
 
   /* Parse the command line options and other arguments. */
-  //while ((c = getopt_long (argc, argv, "o:O:itl:vL:T:sSxX", longopts, &longind)) != EOF)
   while ((c = getopt_long_only (argc, argv, "-l:y:L:", longopts, &longind)) != EOF)
     {
@@ -1216,5 +1385,5 @@
           break;
 
-        case 0:                   /* Non-option argument */
+        case 1:                   /* Non-option argument */
 
           /* Extract the extension to see what to do with this
@@ -1230,5 +1399,5 @@
 
               sprintf (tmp, "%s.", optarg);
-              add_name_list (&add_obj_fnames, tmp);
+              add_name_list (&add_obj_fnames, tmp, 0);
             }
 
@@ -1266,10 +1435,10 @@
 
           else if (stricmp (ext, ".lib") == 0 || stricmp (ext, ".a") == 0 || stricmp (ext, ".dll") == 0)
-            add_name_list (&add_lib_fnames, optarg);
+            add_name_list (&add_lib_fnames, optarg, opt_libs_static);
 
           /* Otherwise, assume it's an object file. */
 
           else
-            add_name_list (&add_obj_fnames, optarg);
+            add_name_list (&add_obj_fnames, optarg, 0);
           ++files;
           break;
@@ -1281,5 +1450,5 @@
 
         case 'l':                 /* Add library */
-          add_name_list (&add_lib_fnames, optarg);
+          add_name_list (&add_lib_fnames, optarg, opt_libs_static);
           break;
 
@@ -1289,5 +1458,5 @@
 
         case 'L':                 /* Add library directory */
-          add_name_list (&add_libdirs, optarg);
+          add_name_list (&add_libdirs, optarg, 0);
           break;
 
@@ -1309,5 +1478,5 @@
 
         case 'O':                 /* Specify Linker option */
-          add_name_list (&add_options, optarg);
+          add_name_list (&add_options, optarg, 0);
           break;
 
@@ -1337,6 +1506,6 @@
             usage ();
           errno = 0;
-          stack_size = strtol (argv[optind], &t, 0);
-          if (errno != 0 || *t != 0 || t == argv[optind])
+          stack_size = strtol (optarg, &t, 0);
+          if (errno != 0 || *t != 0 || t == optarg)
             usage ();
           break;
@@ -1347,4 +1516,12 @@
         case OPT_ZNO_AUTOCONV:
           autoconvert_flag = 0;
+          break;
+
+        case OPT_LIBS_STATIC:
+          opt_libs_static = 1;
+          break;
+        case OPT_LIBS_SHARED:
+          opt_libs_static = 0;
+          break;
 
         default:
@@ -1419,5 +1596,5 @@
     {
       char szname[_MAX_PATH + 1];
-      FILE *phfile = find_objlib (szname, pcur->name, FALSE);
+      FILE *phfile = find_obj (szname, pcur->name);
       if (!phfile)
         continue;
@@ -1430,5 +1607,5 @@
     {
       char szname[_MAX_PATH + 1];
-      FILE *phfile = find_objlib (szname, pcur->name, TRUE);
+      FILE *phfile = find_lib (szname, pcur->name, !pcur->flags);
       if (!phfile)
         continue;
Index: /trunk/src/emx/src/ld/ld.c
===================================================================
--- /trunk/src/emx/src/ld/ld.c	(revision 941)
+++ /trunk/src/emx/src/ld/ld.c	(revision 942)
@@ -27,4 +27,5 @@
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdarg.h>
 #include <io.h>
 #include <process.h>
@@ -437,7 +438,6 @@
 
 /* Demangler for C++.  */
-extern char *cplus_demangle ();
 #include "demangle.h"
-static char *my_cplus_demangle ();
+static char *my_cplus_demangle (const char *);
 int demangle_options;
 
@@ -659,4 +659,8 @@
      Also default text_start to after this file's bss. */
   char just_syms_flag;
+
+  /* 1 means search for dynamic libs before static.
+     0 means search only static libs. */
+  char dynamic;
 };
 
@@ -863,40 +867,71 @@
 int cl_refs_allocated;
 
-char *xmalloc ();
-char *xrealloc ();
-void usage ();
-void fatal ();
-void fatal_with_file ();
-void perror_name ();
-void perror_file ();
-void error ();
-
-int parse ();
-void initialize_text_start ();
-void initialize_data_start ();
-void digest_symbols ();
-void print_symbols ();
-void load_symbols ();
-void decode_command ();
-void list_undefined_symbols ();
-void list_unresolved_references ();
-void write_output ();
-void write_header ();
-void write_text ();
-void read_file_relocation ();
-void write_data ();
-void write_rel ();
-void write_syms ();
-void write_symsegs ();
-void mywrite ();
-void symtab_init ();
-void padfile ();
-char *concat ();
-char *get_file_name ();
-symbol *getsym (), *getsym_soft ();
-void do_warnings ();
+char *xmalloc (int);
+void *xrealloc (void *, int);
+void usage (char *, char *);
+void fatal (char *, ...);
+void fatal_with_file (char *, struct file_entry *);
+void perror_name (char *);
+void perror_file (struct file_entry *);
+void error (char *, char *, char *, char *);
+
+int parse (char *, char *, char *);
+void initialize_text_start (void);
+void initialize_data_start (void);
+void digest_symbols (void);
+void print_symbols (FILE *);
+void load_symbols (void);
+void decode_command (int, char **);
+void write_output (void);
+void write_header (void);
+void write_text (void);
+void read_file_relocation (struct file_entry *);
+void write_data (void);
+void write_rel (void);
+void write_syms (void);
+void write_symsegs (void);
+void mywrite (void *, int, int, int);
+void symtab_init (void);
+void padfile (int, int);
+char *concat (const char *, const char *, const char *);
+char *get_file_name (struct file_entry *);
+symbol *getsym (char *), *getsym_soft (char *);
+void do_warnings (FILE *);
 void check_exe (void);
 char *lx_to_aout (const char *pszFilename);
+int check_lx_dll(int fd);
 void cleanup (void);
+
+void add_cmdline_ref (struct glosym *sp);
+void prline_file_name (struct file_entry *entry, FILE *outfile);
+void deduce_file_type(int desc, struct file_entry *entry);
+void read_a_out_header (int desc, struct file_entry *entry);
+void read_header (int desc, struct file_entry *entry);
+void read_entry_symbols (int desc, struct file_entry *entry);
+void read_entry_strings (int desc, struct file_entry *entry);
+unsigned long contains_symbol (struct file_entry *entry, struct nlist *n_ptr);
+void process_subentry (int desc, struct file_entry *subentry, struct file_entry *entry, struct file_entry **prev_addr);
+void consider_file_section_lengths (struct file_entry *entry);
+void relocate_file_addresses (struct file_entry *entry);
+void describe_file_sections (struct file_entry *entry, FILE *outfile);
+void list_file_locals (struct file_entry *entry, FILE *outfile);
+int relocation_entries_relation (struct relocation_info *rel1, struct relocation_info *rel2);
+void do_relocation_warnings (struct file_entry *entry, int data_segment, FILE *outfile, unsigned char *nlist_bitvector);
+void do_file_warnings (struct file_entry *entry, FILE *outfile);
+void initialize_a_out_text_start (void);
+void initialize_a_out_data_start (void);
+void compute_a_out_section_offsets (void);
+void compute_more_a_out_section_offsets (void);
+void write_a_out_header (void);
+int hash_string (char *key);
+void read_file_symbols (struct file_entry *entry);
+void compute_section_offsets (void);
+void compute_more_section_offsets (void);
+void read_relocation (void);
+int assign_string_table_index (char *name);
+unsigned long check_each_file (register unsigned long (*function)(), register int arg);
+
+
+
 
 
@@ -1033,5 +1068,4 @@
   {"z", 0, 0, 'z'},
   {"A", 1, 0, 'A'},
-  {"Bstatic", 0, 0, 129},	/* For Sun compatibility. */
   {"D", 1, 0, 'D'},
   {"M", 0, 0, 'M'},
@@ -1052,4 +1086,13 @@
   {"V", 1, 0, 'V'},
   {"X", 0, 0, 'X'},
+#define OPT_LIBS_STATIC     0x1000
+  {"Bstatic", 0, 0, OPT_LIBS_STATIC},
+  {"non_shared", 0, 0, OPT_LIBS_STATIC},
+  {"dn", 0, 0, OPT_LIBS_STATIC},
+  {"static", 0, 0, OPT_LIBS_STATIC},
+#define OPT_LIBS_SHARED     0x1001
+  {"Bshared", 0, 0, OPT_LIBS_SHARED},
+  {"call_shared", 0, 0, OPT_LIBS_SHARED},
+  {"dy", 0, 0, OPT_LIBS_SHARED},
   {0, 0, 0, 0}
 };
@@ -1071,4 +1114,5 @@
   int optc, longind;
   register struct file_entry *p;
+  int opt_libs_static = 0;
 
   number_of_files = 0;
@@ -1178,8 +1222,4 @@
 	case 'A':
 	  number_of_files++;
-	  break;
-
-	case 129:		/* -Bstatic. */
-	  /* Ignore. */
 	  break;
 
@@ -1271,4 +1311,9 @@
 	  discard_locals = DISCARD_L;
 	  break;
+
+        case OPT_LIBS_STATIC:
+        case OPT_LIBS_SHARED:
+          /* processed later */
+          break;
 	}
     }
@@ -1327,5 +1372,5 @@
 	case 'A':
 	  if (p != file_table)
-	    usage ("-A specified before an input file other than the first");
+	    usage ("-A specified before an input file other than the first", NULL);
 	  p->filename = optarg;
 	  p->local_sym_name = optarg;
@@ -1335,9 +1380,17 @@
 
 	case 'l':
-	  p->filename = concat ("", optarg, ".a");
+	  p->filename = concat ("", optarg, "");
 	  p->local_sym_name = concat ("-l", optarg, "");
 	  p->search_dirs_flag = 1;
+          p->dynamic = !opt_libs_static;
 	  p++;
 	  break;
+
+        case OPT_LIBS_STATIC:
+          opt_libs_static = 1;
+          break;
+        case OPT_LIBS_SHARED:
+          opt_libs_static = 0;
+          break;
 	}
     }
@@ -1398,5 +1451,5 @@
 }
 
-int
+static int
 set_element_prefixed_p (name)
      char *name;
@@ -1419,5 +1472,5 @@
 /* Convenient functions for operating on one or all files being
    loaded.  */
-void print_file_name ();
+void print_file_name (struct file_entry *entry, FILE *outfile);
 
 /* Call FUNCTION on each input file entry.
@@ -1427,5 +1480,5 @@
    FUNCTION receives two arguments: the entry, and ARG.  */
 
-void
+static void
 each_file (function, arg)
      register void (*function)();
@@ -1483,5 +1536,5 @@
 /* Like `each_file' but ignore files that were just for symbol definitions.  */
 
-void
+static void
 each_full_file (function, arg)
      register void (*function)();
@@ -1508,5 +1561,5 @@
 /* Close the input file that is now open.  */
 
-void
+static void
 file_close ()
 {
@@ -1520,5 +1573,5 @@
    a new open is not actually done.  */
 
-int
+static int
 file_open (entry)
      register struct file_entry *entry;
@@ -1536,31 +1589,52 @@
   if (entry->search_dirs_flag && n_search_dirs)
     {
+      /* !we're searching for libraries here! */
+      static const char *dynamic_suffs[] = { "_dll.a", ".a", ".dll", "_s.a", NULL };
+      static const char *static_suffs[]  = { "_s.a", ".a", NULL };
+      const char **suffs = entry->dynamic ? dynamic_suffs : static_suffs;
+      int lenname = strlen (entry->filename);
       int i;
 
       for (i = 0; i < n_search_dirs; i++)
 	{
-	  register char *string
-	    = concat (search_dirs[i], "/", entry->filename);
-	  desc = open (string, O_RDONLY|O_BINARY, 0);
-
-          if (desc < 0)
-          {
-            char *tmp = _getext (entry->filename);
-            if (tmp && (tolower(tmp[1]) == 'a') && (tmp[2] == 0))
+          int lendir = strlen (search_dirs[i]);
+	  register char *string = xmalloc (lendir + lenname + 4 + 6 + 1);
+          int j;
+
+          memcpy (string, search_dirs[i], lendir);
+          string[lendir++] = '/';
+          for (j = 0; suffs[j]; j++)
             {
-              /* Try libxxx */
-              free (string);
-	      string = concat (search_dirs[i], "/lib", entry->filename);
-	      desc = open (string, O_RDONLY|O_BINARY, 0);
-            }
-          }
-	  if (desc > 0)
-	    {
-	      entry->filename = string;
-	      entry->search_dirs_flag = 0;
-	      break;
-	    }
+              static const char *prefixes[] = { "lib", ""};
+              int k;
+              for (k = 0; k < sizeof(prefixes) / sizeof(prefixes[0]); k++)
+                {
+                  int len = strlen (prefixes[k]);
+                  memcpy (string + lendir, prefixes[k], len);
+                  len += lendir;
+                  memcpy (string + len, entry->filename, lenname);
+                  len += lenname;
+                  strcpy (string + len, suffs[j]);
+
+                  desc = open (string, O_RDONLY|O_BINARY, 0);
+                  if (desc > 0)
+                    {
+                      /* convert? */
+                      if (check_lx_dll (desc))
+                        {
+                          string = lx_to_aout (string);
+                          if (!string || (desc = open (string, O_RDONLY|O_BINARY, 0)) < 0)
+                            perror_file (entry);
+                        }
+                      entry->filename = string;
+                      entry->search_dirs_flag = 0;
+                      input_file = entry;
+                      input_desc = desc;
+                      return desc;
+                    }
+                } /* prefix loop */
+            } /* suffix loop */
 	  free (string);
-	}
+	} /* dir loop */
     }
   else
@@ -1816,6 +1890,6 @@
 void
 read_entry_strings (desc, entry)
+     int desc;
      struct file_entry *entry;
-     int desc;
 {
   if (!entry->header_read_flag)
@@ -1830,9 +1904,10 @@
 /* Read in the symbols of all input files.  */
 
-void read_file_symbols (), read_entry_symbols (), read_entry_strings ();
-void enter_file_symbols (), enter_global_ref (), search_library ();
-
-void
-load_symbols ()
+void enter_file_symbols (struct file_entry *entry);
+void enter_global_ref (register struct nlist *nlist_p, char *name, struct file_entry *entry);
+void search_library (int desc, struct file_entry *entry);
+
+void
+load_symbols (void)
 {
   register int i;
@@ -2169,6 +2244,7 @@
 /* Searching libraries */
 
-struct file_entry *decode_library_subfile ();
-void linear_library (), symdef_library ();
+struct file_entry * decode_library_subfile (int desc, struct file_entry *library_entry, int subfile_offset, int *length_loc);
+void symdef_library (int desc, struct file_entry *entry, int member_length);
+void linear_library (int desc, struct file_entry *entry);
 
 /* Search the library ENTRY, already open on descriptor DESC.
@@ -2266,5 +2342,5 @@
 
 
-int subfile_wanted_p ();
+int subfile_wanted_p (struct file_entry *);
 
 /* Search a library that has a __.SYMDEF member.
@@ -2557,5 +2633,5 @@
 
 void
-digest_symbols ()
+digest_symbols (void)
 {
   register int i;
@@ -2996,4 +3072,7 @@
 };
 
+int next_debug_entry (int use_data_symbols, struct line_debug_entry state_pointer[3]);
+struct line_debug_entry * init_debug_scan (int use_data_symbols, struct file_entry *entry);
+int address_to_line (unsigned long address, struct line_debug_entry state_pointer[3]);
 void qsort ();
 /*
@@ -3232,5 +3311,5 @@
 
   qsort (reloc_start, reloc_size, sizeof (struct relocation_info),
-	 relocation_entries_relation);
+	 (int (*)(const void *, const void *))relocation_entries_relation);
 
   for (reloc = reloc_start;
@@ -3512,5 +3591,5 @@
 
 void
-initialize_a_out_text_start ()
+initialize_a_out_text_start (void)
 {
   int magic = 0;
@@ -3562,5 +3641,5 @@
 
 void
-initialize_a_out_data_start ()
+initialize_a_out_data_start (void)
 {
   outheader.a_text = text_size;
@@ -3572,5 +3651,5 @@
 
 void
-compute_a_out_section_offsets ()
+compute_a_out_section_offsets (void)
 {
   outheader.a_data = data_size;
@@ -3635,5 +3714,5 @@
 
 void
-compute_more_a_out_section_offsets ()
+compute_more_a_out_section_offsets (void)
 {
   output_symseg_offset = output_strs_offset + output_strs_size;
@@ -3643,5 +3722,5 @@
 
 void
-write_a_out_header ()
+write_a_out_header (void)
 {
   lseek (outdesc, 0L, 0);
@@ -3659,5 +3738,5 @@
 
 void
-initialize_text_start ()
+initialize_text_start (void)
 {
 #ifdef A_OUT
@@ -3675,5 +3754,5 @@
 
 void
-initialize_data_start ()
+initialize_data_start (void)
 {
 #ifdef A_OUT
@@ -3690,5 +3769,5 @@
 
 void
-compute_section_offsets ()
+compute_section_offsets (void)
 {
 #ifdef A_OUT
@@ -3705,5 +3784,5 @@
    is finalized.  */
 void
-compute_more_section_offsets ()
+compute_more_section_offsets (void)
 {
 #ifdef A_OUT
@@ -3719,5 +3798,5 @@
 /* Write the output file header, once everything is known.  */
 void
-write_header ()
+write_header (void)
 {
 #ifdef A_OUT
@@ -3800,5 +3879,5 @@
 
 void
-write_output ()
+write_output (void)
 {
   struct stat statbuf;
@@ -3982,5 +4061,8 @@
 
 
-void modify_location (), perform_relocation (), copy_text (), copy_data ();
+void copy_text (struct file_entry *entry);
+void copy_data (struct file_entry *entry);
+void perform_relocation ( char *data, int pc_relocation, int data_size,
+    struct relocation_info *reloc_info, int reloc_size, struct file_entry *entry);
 
 /* Relocate the text segment of each input file
@@ -4007,5 +4089,5 @@
 
 void
-read_relocation ()
+read_relocation (void)
 {
   each_full_file (read_file_relocation, 0);
@@ -4356,5 +4438,6 @@
    relocating the addresses-to-be-relocated.  */
 
-void coptxtrel (), copdatrel ();
+void coptxtrel (struct file_entry *entry);
+void copdatrel (struct file_entry *entry);
 
 void
@@ -4420,5 +4503,5 @@
 	    RELOC_ADDRESS (&reloc)
 	      = set_sect_start + i * sizeof (unsigned long) - data_start;
-	    mywrite ((char *)&reloc, sizeof (reloc), 1, outdesc);
+	    mywrite (&reloc, sizeof (reloc), 1, outdesc);
 	    break;
 	  case N_ABS:
@@ -4579,6 +4662,6 @@
 
 
-void write_file_syms ();
-void write_string_table ();
+void write_file_syms (struct file_entry *entry, int *syms_written_addr);
+void write_string_table (void);
 
 /* Total size of string table strings allocated so far,
@@ -4620,5 +4703,5 @@
 
 void
-write_string_table ()
+write_string_table (void)
 {
   register int i;
@@ -4927,5 +5010,5 @@
    except that we store some information into the beginning of it.  */
 
-void write_file_symseg ();
+void write_file_symseg (struct file_entry *entry);
 
 void
@@ -5153,10 +5236,11 @@
    STRING is a printf format string and ARG is one arg for it.  */
 
-void
-fatal (string, arg)
-     char *string, *arg;
-{
+void fatal (char *string, ...)
+{
+  va_list args;
   fprintf (stderr, "%s: ", progname);
-  fprintf (stderr, string, arg);
+  va_start (args, string);
+  vfprintf (stderr, string, args);
+  va_end (args);
   fprintf (stderr, "\n");
   exit (1);
@@ -5229,5 +5313,5 @@
 void
 mywrite (buf, count, eltsize, desc)
-     char *buf;
+     void *buf;
      int count;
      int eltsize;
@@ -5242,5 +5326,5 @@
       if (val <= 0)
 	perror_name (output_filename);
-      buf += val;
+      buf = (char*)buf + val;
       bytes -= val;
     }
@@ -5269,5 +5353,5 @@
 char *
 concat (s1, s2, s3)
-     char *s1, *s2, *s3;
+     const char *s1, *s2, *s3;
 {
   register int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
@@ -5288,5 +5372,5 @@
 int
 parse (arg, format, error)
-     char *arg, *format;
+     char *arg, *format, *error;
 {
   int x;
@@ -5310,7 +5394,7 @@
 /* Like realloc but get fatal error if memory is exhausted.  */
 
-char *
+void *
 xrealloc (ptr, size)
-     char *ptr;
+     void *ptr;
      int size;
 {
@@ -5413,4 +5497,55 @@
 }
 
+
+/**
+ * Checks if the file FD is an LX DLL.
+ *
+ * @returns 1 if LX DLL.
+ * @returns 0 if not LX DLL.
+ * @param   fd  Handle to file to check.
+ */
+int check_lx_dll(int fd)
+{
+    unsigned long   ul;
+    char            achMagic[2];
+
+    if (    lseek(fd, 0, SEEK_SET)
+        ||  read(fd, &achMagic, 2) != 2)
+        goto thats_not_it;
+
+    if (!memcmp(achMagic, "MZ", 2))
+    {
+        if (    lseek(fd, 0x3c, SEEK_SET)
+            ||  read(fd, &ul, 4) != 4 /* offset of the 'new' header */
+            ||  ul < 0x40
+            ||  ul >= 0x10000000 /* 512MB stubs sure */
+            ||  lseek(fd, ul, SEEK_SET)
+            ||  read(fd, &achMagic, 2) != 2)
+            goto thats_not_it;
+    }
+
+    if (    memcmp(achMagic, "LX", 2)
+        ||  lseek(fd, 14, SEEK_CUR)
+        ||  read(fd, &ul, 4) != 4) /*e32_mflags*/
+        goto thats_not_it;
+
+#define E32MODDLL        0x08000L
+#define E32MODPROTDLL    0x18000L
+#define E32MODMASK       0x38000L
+    if (   (ul & E32MODMASK) != E32MODDLL
+        && (ul & E32MODMASK) != E32MODPROTDLL)
+        goto thats_not_it;
+
+    /* it's a LX DLL! */
+    lseek(fd,  0, SEEK_SET);
+    return 1;
+
+
+thats_not_it:
+    lseek(fd, 0, SEEK_SET);
+    return 0;
+}
+
+
 /* atexit worker */
 void cleanup (void)
