Index: trunk/src/emx/src/emxomf/weakld.c
===================================================================
--- trunk/src/emx/src/emxomf/weakld.c	(revision 516)
+++ trunk/src/emx/src/emxomf/weakld.c	(revision 517)
@@ -54,5 +54,6 @@
 #define WLDINTERR(pWld, pMod)   wldIntErr(pWld, pMod, __FILE__, __LINE__, __FUNCTION__);
 
-#if 0 /*def DEBUG*/
+/*#define WLD_ENABLED_DBG*/
+#ifdef WLD_ENABLED_DBG
 #define SYMDBG(pSym, pszMsg)    symDbg(pSym, pszMsg);
 #define WLDDBG(a)               wldDbg a
@@ -82,4 +83,5 @@
 #include <sys/types.h>
 #include <sys/omflib.h>
+#include <sys/moddef.h>
 #include "defs.h"
 #include "grow.h"
@@ -234,6 +236,8 @@
              * Valid when type is WLDSF_IMPORT.
              * @{ */
+            /** Import name. */
+            const char *        pszImpName;
             /** Import module. */
-            const char*         pszImpMod;
+            const char *        pszImpMod;
             /** Import Ordinal (WLDSF_IMPORT).
              * 0 means no ordinal. */
@@ -318,4 +322,7 @@
     WLDSYMTAB           Global;
 
+    /** Module definition file. */
+    PWLDMOD             pDef;
+
     /** Linked list (FIFO) of objects included in the link. */
     PWLDMOD             pObjs;
@@ -342,9 +349,23 @@
 /** @group Weak LD - Linker Methods (Private)
  * @{ */
+#ifdef WLD_ENABLED_DBG
 static void         wldDbg(const char *pszFormat, ...);
+#endif
 static void         wldInfo(const char *pszFormat, ...);
+static int          wldWarn(PWLD pWld, const char *pszFormat, ...);
 static int          wldErr(PWLD pWld, const char *pszFormat, ...);
 static void         wldIntErr(PWLD pWld, PWLDMOD pMod, const char *pszFile, unsigned iLine, const char *pszFunction);
 static unsigned     pass1ReadOMFMod(PWLD pWld, PWLDMOD pMod, int fLibSearch);
+/** Parameter structure for wldDefCallback(). */
+typedef struct wldDefCallback_param
+{
+    /** Linker instance. */
+    PWLD        pWld;
+    /** Name of .def file. */
+    PWLDMOD     pMod;
+    /** Callback return code. Zero ok; non-zero failure; */
+    int         rc;
+} WLDDEFCBPARAM, *PWLDDEFCBPARAM;
+static int          wldDefCallback(struct _md *pMD, const _md_stmt *pStmt, _md_token eToken, void *pvArg);
 /** @} */
 
@@ -358,5 +379,7 @@
 static int          libLoadUndefSymbols(PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded);
 static int          libErr(PWLDLIB pLib, const char *pszFormat, ...);
+#if 0
 static void         libWarn(PWLDLIB pLib, const char *pszFormat, ...);
+#endif
 /** @} */
 
@@ -388,8 +411,11 @@
 static int          symSearchLibEnum(PWLD pWld, PWLDSYM pSym, void *pvUser);
 static inline unsigned symHash(const char* pszSym, unsigned cch);
+#ifdef WLD_ENABLED_DBG
 static void         symDbg(PWLDSYM pSym, const char *pszMsg);
+#endif
 static PWLDSYM      symAdd(PWLD pWld, PWLDMOD pMod, unsigned fFlags, const char *pachName, int cchName, PWLDSYMACTION peAction);
 static PWLDSYM      symAddImport(PWLD pWld, PWLDMOD pMod, int fLibSearch,
-                                 const char *pachIntName, int cchIntName,
+                                 const char *pachName, int cchName,
+                                 const char *pachImpName, int cchImpName,
                                  const char *pachModName, int cchModName,
                                  unsigned uOrdinal);
@@ -422,5 +448,5 @@
 *******************************************************************************/
 
-#ifdef DEBUG
+#ifdef WLD_ENABLED_DBG
 /**
  * Put out a debug message.
@@ -459,5 +485,23 @@
 
 /**
- * Put out a info message.
+ * Put out a warning message.
+ * @param   pszFormat   Format string.
+ * @param   ...         Format arguments.
+ */
+static int          wldWarn(PWLD pWld, const char *pszFormat, ...)
+{
+    va_list     args;
+    fprintf(stderr, "weakld: warning: ");
+
+    va_start(args, pszFormat);
+    vfprintf(stderr, pszFormat, args);
+    va_end(args);
+    if (pszFormat[strlen(pszFormat) - 1] != '\n')
+        fputc('\n', stderr);
+    return 4;
+}
+
+/**
+ * Put out a error message.
  * @param   pszFormat   Format string.
  * @param   ...         Format arguments.
@@ -918,4 +962,5 @@
 }
 
+#if 0
 /**
  * Put out a warning for this library.
@@ -935,5 +980,5 @@
         fputc('\n', stderr);
 }
-
+#endif
 
 
@@ -1232,5 +1277,5 @@
 
 
-#ifdef DEBUG
+#ifdef WLD_ENABLED_DBG
 /**
  * Symbol debug output.
@@ -1522,13 +1567,16 @@
  * @param   pMod        Pointer to module
  * @param   fLibSearch  Set if we're doing library search at this time.
- * @param   pachIntName Internal name, the one which can be referenced in this module.
- * @param   cchIntName  Length of that name. -1 if zero terminated string.
+ * @param   pachName    The name which can be referenced in this module.
+ * @param   cchName     Length of that name. -1 if zero terminated string.
+ * @param   pachImpName Internal name, the name used to import the symbol.
+ * @param   cchImpName  Length of that name. -1 if zero terminated string.
  * @param   pachModName Module name where the export should be resolved on load time.
  * @param   cchModName  Length of that name. -1 if zero terminated string.
  * @param   uOrdinal    The ordinal it's exported with from the module.
- *                      0 if exported by the name pachIntName represent.
+ *                      0 if exported by the name pachImpName represent.
  */
 PWLDSYM symAddImport(PWLD pWld, PWLDMOD pMod, int fLibSearch,
-                     const char *pachIntName, int cchIntName,
+                     const char *pachName, int cchName,
+                     const char *pachImpName, int cchImpName,
                      const char *pachModName, int cchModName,
                      unsigned uOrdinal)
@@ -1536,12 +1584,26 @@
     WLDSYMACTION    eAction;
     PWLDSYM         pSym;
+    const char *    pszImpName;
     const char *    pszImpMod;
 
     pSym = symAdd(pWld, pMod, WLDSF_IMPORT | (fLibSearch ? WLDSF_LIBSEARCH : 0),
-                  pachIntName, cchIntName, &eAction);
+                  pachName, cchName, &eAction);
     if (!pSym)
         return NULL;
 
+    /* Add the strings we'll need them very soon */
     pszImpMod = strpool_addnu(pWld->pStrMisc, pachModName, cchModName);
+    pszImpName = NULL;
+    if (!uOrdinal)
+    {
+        if (!pachImpName || cchImpName == 0 )
+        {
+            pachImpName = pachName;
+            cchImpName = cchName;
+        }
+        pszImpName = strpool_addn(pWld->pStrMisc, pachImpName, cchImpName);
+    }
+
+    /* Process the symbol */
     switch (eAction)
     {
@@ -1549,4 +1611,5 @@
         case WLDSA_UP:
             pSym->u.import.pszImpMod = pszImpMod;
+            pSym->u.import.pszImpName = pszImpName;
             pSym->u.import.uImpOrd   = uOrdinal;
             break;
@@ -1559,4 +1622,5 @@
                 {
                     pSym->u.import.pszImpMod = pszImpMod;
+                    pSym->u.import.pszImpName = pszImpName;
                     pSym->u.import.uImpOrd = uOrdinal;
                 }
@@ -1564,8 +1628,19 @@
                 {
                     if (    pSym->u.import.pszImpMod != pszImpMod
+                        &&  pSym->u.import.pszImpName != pszImpName
                         &&  pSym->u.import.uImpOrd != uOrdinal)
                     {
-                        modWarn(pMod, "Existing import '%s' have different module name than the new ('%s' != '%s') and different ordinal (%d != %d).",
-                                pSym->pszName, pSym->u.import.pszImpMod, pszImpMod, pSym->u.import.uImpOrd, uOrdinal);
+                        modWarn(pMod, "Existing import '%s' have different module name than the new ('%s' != '%s'), different ordinal (%d != %d), and different name (%s != %s).",
+                                pSym->pszName, pSym->u.import.pszImpMod, pszImpMod, pSym->u.import.uImpOrd, uOrdinal, pSym->u.import.pszImpName, pszImpName);
+                    }
+                    else if (pSym->u.import.pszImpMod != pszImpMod)
+                    {
+                        modWarn(pMod, "Existing import '%s' have different module name than the new ('%s' != '%s').",
+                                pSym->pszName, pSym->u.import.pszImpMod, pszImpMod);
+                    }
+                    else if (pSym->u.import.pszImpName != pszImpName)
+                    {
+                        modWarn(pMod, "Existing import '%s' have different import name (%s != %s).",
+                                pSym->pszName, pSym->u.import.pszImpName, pszImpName);
                     }
                     else if (pSym->u.import.uImpOrd != uOrdinal)
@@ -1573,9 +1648,4 @@
                         modWarn(pMod, "Existing import '%s' have different ordinal (%d != %d).",
                                 pSym->pszName, pSym->u.import.uImpOrd, uOrdinal);
-                    }
-                    else if (pSym->u.import.pszImpMod != pszImpMod)
-                    {
-                        modWarn(pMod, "Existing import '%s' have different module name than the new ('%s' != '%s').",
-                                pSym->pszName, pSym->u.import.pszImpMod, pszImpMod);
                     }
                 }
@@ -2035,4 +2105,5 @@
                                 pSym = symAddImport(pWld, pMod, fLibSearch,
                                                     u1.pch + 1, *u1.puch,
+                                                    u1.pch + 1, *u1.puch,
                                                     u2.pch + 1, *u2.puch,
                                                     ul);
@@ -2282,6 +2353,5 @@
         return 8;
     }
-    if (pWld->fFlags & WLDC_VERBOSE)
-        fprintf(stderr, "weakld: info: adding object %s.\n", pszName);
+    WLDINFO(pWld, ("adding object %s.\n", pszName));
 
     /*
@@ -2348,4 +2418,93 @@
 
 /**
+ * Callback function for parsing a module definition file.
+ *
+ * @returns 0 on success.
+ * @returns -1 to stop the parsing.
+ * @param   pMD     Pointer to module definition file handle.
+ * @param   pStmt   Statement we're processing.
+ * @param   eToken  Token we're processing.
+ * @param   pvArg   Private arguments - pointer to an WLDDEFCBPARAM structure.
+ *                  On failure, we'll update the structures rc member.
+ */
+static int wldDefCallback(struct _md *pMD, const _md_stmt *pStmt, _md_token eToken, void *pvArg)
+{
+    unsigned        fFlags;
+    unsigned        uOrdinal;
+    unsigned        cWords;
+    PWLDSYM         pSym;
+    PWLDDEFCBPARAM  pParam = (PWLDDEFCBPARAM)pvArg;
+
+    switch (eToken)
+    {
+        /*
+         * One import.
+         */
+        case _MD_IMPORTS:
+            uOrdinal = 0;
+            if (pStmt->import.flags & _MDIP_ORDINAL)
+                uOrdinal = pStmt->import.ordinal;
+            pSym = symAddImport(pParam->pWld, pParam->pMod, 0,
+                                pStmt->import.entryname, -1,
+                                pStmt->import.internalname, -1,
+                                pStmt->import.modulename, -1,
+                                uOrdinal);
+            if (!pSym)
+            {
+                pParam->rc = -3;
+                return -3;
+            }
+            break;
+
+
+        /*
+         * One export.
+         */
+        case _MD_EXPORTS:
+            fFlags = uOrdinal = cWords = 0;
+            if (pStmt->export.flags & _MDEP_ORDINAL)
+                uOrdinal = pStmt->export.ordinal;
+            if (pStmt->export.flags & _MDEP_RESIDENTNAME)
+                fFlags |= WLDSEF_NONRESIDENT;
+            else if (pStmt->export.flags & _MDEP_NONAME)
+                fFlags |= WLDSEF_NONAME;
+            else
+                fFlags |= WLDSEF_DEFAULT;
+            if (pStmt->export.flags & _MDEP_NODATA)
+                fFlags |= WLDSEF_NODATA;
+            if (pStmt->export.flags & _MDEP_PWORDS)
+                cWords = pStmt->export.pwords;
+            pSym = symAddExport(pParam->pWld, pParam->pMod, 0,
+                                fFlags, cWords,
+                                pStmt->export.entryname, -1,
+                                pStmt->export.internalname, -1,
+                                uOrdinal);
+            if (!pSym)
+            {
+                pParam->rc = -4;
+                return -4;
+            }
+            break;
+
+        /*
+         * Parse error.
+         */
+        case _MD_parseerror:
+            modErr(pParam->pMod, "Parse error %d on line %d. (errorcode=%d stmt=%d)",
+                   _md_get_linenumber(pMD), pStmt->error.code, pStmt->error.stmt);
+            pParam->rc = -2;
+            break;
+
+        /*
+         * Ignore everything else (it's here to get rid of gcc warnings).
+         */
+        default:
+            break;
+    }
+    return 0;
+}
+
+
+/**
  * Adds an definition file to the linking process.
  * The definition file will be analysed and the file handle closed.
@@ -2363,16 +2522,46 @@
 int     wldAddDefFile(PWLD pWld, FILE *phFile, const char *pszName)
 {
+    struct _md *    pMD;
+    int             rc = -1;
     if (!phFile)
         phFile = fopen(pszName, "r");
     if (!phFile)
     {
-        fprintf(stderr, "weakld: cannot open deffile file '%s'.\n", pszName);
+        wldErr(pWld, "cannot open deffile file '%s'.\n", pszName);
         return 8;
     }
-    if (pWld->fFlags & WLDC_VERBOSE)
-        fprintf(stderr, "weakld: info: adding deffile %s\n", pszName);
-
-
-    return 0;
+    WLDINFO(pWld, ("adding deffile %s\n", pszName));
+
+    if (pWld->pDef)
+        wldWarn(pWld, "%s: There is already a definition file '%s' loaded.", pszName, pWld->pDef->pszModName);
+
+    /*
+     * Process the .def file and be done with it.
+     */
+    pMD = _md_use_file(phFile);
+    if (pMD)
+    {
+        PWLDMOD         pMod;
+        WLDDEFCBPARAM   param;
+
+        pMod = xmalloc(sizeof(*pMod));
+        memset(pMod, 0, sizeof(*pMod));
+        pMod->off = -1;
+        pMod->pszModName = strpool_add(pWld->pStrMisc, pszName);
+        pWld->pDef = pMod;
+
+        /* parse it */
+        _md_next_token(pMD);
+        param.pWld      = pWld;
+        param.pMod      = pMod;
+        param.rc        = 0;
+        rc = _md_parse(pMD, wldDefCallback, &param);
+        _md_close(pMD);
+    }
+    else
+        wldErr(pWld, "_md_use_file on '%s'.\n", pszName);
+
+    fclose(phFile);
+    return rc;
 }
 
@@ -2403,6 +2592,5 @@
         return 8;
     }
-    if (pWld->fFlags & WLDC_VERBOSE)
-        fprintf(stderr, "weakld: info: adding library %s\n", pszName);
+    WLDINFO(pWld, ("adding library %s\n", pszName));
 
     /* add it to the link, do nothing till we're asked to do the searching. */
