Index: /branches/libc-0.6/src/emx/src/emxomf/weakld.c
===================================================================
--- /branches/libc-0.6/src/emx/src/emxomf/weakld.c	(revision 3752)
+++ /branches/libc-0.6/src/emx/src/emxomf/weakld.c	(revision 3753)
@@ -223,4 +223,8 @@
          */
         WLDSF_WKEXT     = 0x0005,
+        /** Exported name.
+         * This is used when the exported name differs from the internal one.
+         * This name is not considered in the linking, only the internal one. */
+        WLDSF_EXP_NM    = 0x0006,
         /** @} */
 
@@ -249,8 +253,4 @@
         WLDSF_ALIAS     = 0x0800,
 
-        /** Exported symbol.
-         * This symbol is to be exported. */
-        WLDSF_EXPORT    = 0x1000,
-
         /** Internal flags which indicates that the symbol was exported in
          * the definition file. This to select symbols which only appears in
@@ -260,6 +260,5 @@
 
         /** Internal flag to say that we've already aliased this weak
-         * in the definition file.
-         */
+         * in the definition file. */
         WLDSF_WEAKALIASDONE = 0x8000
     }                   fFlags;
@@ -309,9 +308,9 @@
 
     /** Symbol this is an alias for.
-     * Valid when WLDSF_ALIAS is set. */
+     * Valid when WLDSF_ALIAS or WLDSF_EXP_NM are set. */
     struct wldsym *     pAliasFor;
 
     /** @group Export Attributes
-     * Valid when WLDSF_EXPORT is set.
+     * Valid when WLDSF_EXP_NM is set.
      * @{ */
     /** Export flags. */
@@ -369,4 +368,6 @@
     /** Global symbols. */
     WLDSYMTAB           Global;
+    /** Exported symbols. */
+    WLDSYMTAB           Exported;
 
     /** Module definition file. */
@@ -469,5 +470,5 @@
 static void         symDumpReferers(PWLDSYM pSym);
 static void         symDbg(PWLDSYM pSym, const char *pszMsg);
-static PWLDSYM      symAdd(PWLD pWld, PWLDMOD pMod, unsigned fFlags, const char *pachName, int cchName, PWLDSYMACTION peAction);
+static PWLDSYM      symAdd(PWLD pWld, PWLDMOD pMod, unsigned fFlags, const char *pachName, int cchName, PWLDSYMTAB pSymTab, PWLDSYMACTION peAction);
 static PWLDSYM      symAddImport(PWLD pWld, PWLDMOD pMod, int fLibSearch,
                                  const char *pachName, int cchName,
@@ -1251,6 +1252,7 @@
  * @param   pWld    Linker Instance.
  * @param   pszName Name of the symbol to find.
- */
-static PWLDSYM      symLookup(PWLD pWld, const char *pszName)
+ * @param   pSymTab The symbol table to look it up in.
+ */
+static PWLDSYM      symLookupCommon(PWLD pWld, const char *pszName, PWLDSYMTAB pSymTab)
 {
     PWLDSYM     pSym;
@@ -1285,5 +1287,5 @@
 
     /* look it up */
-    for (pSym = pWld->Global.ap[uHash % WLDSYM_HASH_SIZE]; pSym; pSym = pSym->pHashNext)
+    for (pSym = pSymTab->ap[uHash % WLDSYM_HASH_SIZE]; pSym; pSym = pSym->pHashNext)
        if (SYM_EQUAL(pWld, pSym, pszName, fFlags, uHash, cchName))
            return pSym;
@@ -1293,4 +1295,30 @@
 
 
+/**
+ * Find the symbol by the name pszName.
+ *
+ * @returns Pointer to matching symbol.
+ * @returns NULL if not found.
+ * @param   pWld    Linker Instance.
+ * @param   pszName Name of the symbol to find.
+ */
+static PWLDSYM      symLookup(PWLD pWld, const char *pszName)
+{
+    return symLookupCommon(pWld, pszName, &pWld->Global);
+}
+
+
+/**
+ * Find the export symbol by the name pszName.
+ *
+ * @returns Pointer to matching symbol.
+ * @returns NULL if not found.
+ * @param   pWld    Linker Instance.
+ * @param   pszName Name of the symbol to find.
+ */
+static PWLDSYM      symLookupExport(PWLD pWld, const char *pszName)
+{
+    return symLookupCommon(pWld, pszName, &pWld->Exported);
+}
 
 
@@ -1487,4 +1515,5 @@
         case WLDSF_UNDEF:   psz += sprintf(psz, "UNDEF"); break;
         case WLDSF_WKEXT:   psz += sprintf(psz, "WKEXT"); break;
+        case WLDSF_EXP_NM:  psz += sprintf(psz, "EXPORT"); break;
         default:            psz += sprintf(psz, "!!!internal error!!! "); asm("int $3"); break;
     }
@@ -1493,6 +1522,4 @@
     if (pSym->fFlags & WLDSF_ALIAS)
         psz += sprintf(psz, " ALIAS");
-    if (pSym->fFlags & WLDSF_EXPORT)
-        psz += sprintf(psz, " EXPORT");
     if (pSym->fFlags & WLDSF_UNCERTAIN)
         psz += sprintf(psz, " UNCERTAIN");
@@ -1556,9 +1583,9 @@
  * @param   fFlags      Symbol flags.
  *                      All the flags in WLDSF_TYPEMASK, WLDSF_WEAK and WLDSF_LIBSEARCH.
- *                      WLDSF_EXPORT isn't handled and should not be defined.
  *                      WLDSF_ALIAS and WLDSF_UNCERTAIN is ignored as they have no
  *                      sideeffects when resolving symbols.
  * @param   pachName    Pointer to symbol name.
  * @param   cchName     Length to add, use -1 if zeroterminated.
+ * @param   pSymTab     The symbol table to add it to.
  * @param   pflAction   What we actually did.
  *                      WLDSA_NEW, WLDSA_UP, WLDSA_OLD, WLDSA_ERR.
@@ -1595,5 +1622,6 @@
  *
  */
-static PWLDSYM      symAdd(PWLD pWld, PWLDMOD pMod, unsigned fFlags, const char *pachName, int cchName, PWLDSYMACTION peAction)
+static PWLDSYM      symAdd(PWLD pWld, PWLDMOD pMod, unsigned fFlags, const char *pachName, int cchName, 
+                           PWLDSYMTAB pSymTab, PWLDSYMACTION peAction)
 {
     PWLDSYM     pSym;                   /* The symbol. */
@@ -1632,5 +1660,5 @@
 
     /* search for existing symbol  */
-    for (pSym = pWld->Global.ap[uHash % WLDSYM_HASH_SIZE]; pSym; pSym = pSym->pHashNext)
+    for (pSym = pSymTab->ap[uHash % WLDSYM_HASH_SIZE]; pSym; pSym = pSym->pHashNext)
         if (SYM_EQUAL(pWld, pSym, pszName, fFlags, uHash, cchName))
             break;
@@ -1652,6 +1680,6 @@
             WLDINFO(pWld, ("Weak symbol '%s'.", pSym->pszWeakName));
         }
-        pSym->pHashNext = pWld->Global.ap[uHash % WLDSYM_HASH_SIZE];
-        pWld->Global.ap[uHash % WLDSYM_HASH_SIZE] = pSym;
+        pSym->pHashNext = pSymTab->ap[uHash % WLDSYM_HASH_SIZE];
+        pSymTab->ap[uHash % WLDSYM_HASH_SIZE] = pSym;
         if (peAction) *peAction = WLDSA_NEW;
         WLDDBG2(("symAdd: New symbol '%s'", pSym->pszName));
@@ -1668,4 +1696,5 @@
          *      5. adding a WEAK PUBLIC or WEAK COMM where a PUBLIC or COMM exists.
          *      6. adding a WEAK UNDEF where WEAK UNDEF exists.
+         *      7. adding a EXP_NM that already exists.
          */
         if ( (     /* 1 */
@@ -1688,4 +1717,7 @@
                 ((fFlags & (WLDSF_TYPEMASK | WLDSF_WEAK)) == (WLDSF_UNDEF | WLDSF_WEAK))
              && ((pSym->fFlags & (WLDSF_TYPEMASK | WLDSF_WEAK)) == (WLDSF_UNDEF | WLDSF_WEAK))
+            ) || ( /* 7 */
+                ((fFlags & WLDSF_TYPEMASK) == WLDSF_EXP_NM)
+             && ((pSym->fFlags & WLDSF_TYPEMASK) == WLDSF_EXP_NM)
             ))
         {
@@ -1838,5 +1870,5 @@
 
     pSym = symAdd(pWld, pMod, WLDSF_IMPORT | (fLibSearch ? WLDSF_LIBSEARCH : 0),
-                  pachName, cchName, &eAction);
+                  pachName, cchName, &pWld->Global, &eAction);
     if (!pSym)
         return NULL;
@@ -1867,7 +1899,7 @@
         case WLDSA_NEW:
         case WLDSA_UP:
-            pSym->u.import.pszImpMod = pszImpMod;
+            pSym->u.import.pszImpMod  = pszImpMod;
             pSym->u.import.pszImpName = pszImpName;
-            pSym->u.import.uImpOrd   = uOrdinal;
+            pSym->u.import.uImpOrd    = uOrdinal;
             break;
 
@@ -1946,5 +1978,6 @@
                             unsigned uOrdinal)
 {
-    PWLDSYM         pSym;
+    PWLDSYM         pSymExp;
+    PWLDSYM         pSymInt;
 
     /* set default name */
@@ -1954,11 +1987,19 @@
         cchIntName = cchExpName;
     }
+
+    /*
+     * Add the internal name.
+     */
+    pSymInt = symAdd(pWld, pMod, WLDSF_UNDEF | (fLibSearch ? WLDSF_LIBSEARCH : 0),
+                     pachIntName, cchIntName, &pWld->Global, NULL);
+    if (!pSymInt)
+        return NULL;
 
     /*
      * Add external name.
      */
-    pSym = symAdd(pWld, pMod, WLDSF_UNDEF | (fLibSearch ? WLDSF_LIBSEARCH : 0),
-                  pachExpName, cchExpName, NULL);
-    if (!pSym)
+    pSymExp = symAdd(pWld, pMod, WLDSF_EXP_NM | (fLibSearch ? WLDSF_LIBSEARCH : 0),
+                     pachExpName, cchExpName, &pWld->Exported, NULL);
+    if (!pSymExp)
         return NULL;
 
@@ -1966,46 +2007,25 @@
      * Is the exported symbol already exported?
      */
-    if (pSym->fFlags & WLDSF_EXPORT)
-    {
-        if (    (pSym->fExport & WLDSEF_DEF_FILE)
+    if (pSymExp->pAliasFor)
+    {
+        if (pSymExp->pAliasFor != pSymInt)
+            modWarn(pMod, "Export '%s' (int '%s') is already defined with a different resolution '%s'.", 
+                    pSymExp->pszName, pSymInt->pszName, pSymExp->pAliasFor->pszName);
+        else if (    (pSymExp->fExport & WLDSEF_DEF_FILE)
+                 &&  (fExport & WLDSEF_DEF_FILE))
+            modWarn(pMod, "Export '%s' (int '%s') is already defined.", pSymExp->pszName, pSymInt->pszName);
+        
+        if (    !(pSymExp->fExport & WLDSEF_DEF_FILE)
             &&  (fExport & WLDSEF_DEF_FILE))
-            modWarn(pMod, "Export '%s' is already defined.", pSym->pszName);
-        if (    !(pSym->fExport & WLDSEF_DEF_FILE)
-            &&  (fExport & WLDSEF_DEF_FILE))
-            pSym->fExport = fExport;
-    }
-    else
-    {
-        PWLDSYM     pSymAlias;
-
-        pSym->fFlags |= WLDSF_EXPORT;
-
-        /*
-         * Add internal name.
-         */
-        pSymAlias = symAdd(pWld, pMod, WLDSF_UNDEF | (fLibSearch ? WLDSF_LIBSEARCH : 0),
-                           pachIntName, cchIntName, NULL);
-        if (!pSymAlias)
-            return NULL;
-        if (pSymAlias != pSym && (pSym->fFlags & WLDSF_ALIAS) && pSym->pAliasFor != pSymAlias)
-        {
-            modErr(pMod, "Can't export an alias!.");
-            pSym = NULL;
-        }
-        else
-        {
-            if (pSym != pSymAlias)
-            {
-                pSym->fFlags |= WLDSF_ALIAS;
-                pSym->fFlags &= ~WLDSF_UNDEF;
-                pSym->pAliasFor = pSymAlias;
-            }
-            pSym->fExport   = fExport;
-            pSym->cExpWords = cExpWords;
-            pSym->uExpOrd   = uOrdinal;
-        }
-    }
-
-    return pSym;
+            pSymExp->fExport = fExport;
+        return pSymExp;
+    }
+    
+    pSymExp->pAliasFor = pSymInt;
+    pSymExp->fExport   = fExport;
+    pSymExp->cExpWords = cExpWords;
+    pSymExp->uExpOrd   = uOrdinal;
+
+    return pSymExp;
 }
 
@@ -2031,5 +2051,5 @@
 
     pSym = symAdd(pWld, pMod, WLDSF_PUBLIC | (fLibSearch ? WLDSF_LIBSEARCH : 0),
-                  pachName, cchName, NULL);
+                  pachName, cchName, &pWld->Global, NULL);
     if (!pSym)
         return NULL;
@@ -2055,5 +2075,5 @@
 
     pSym = symAdd(pWld, pMod, WLDSF_UNDEF | WLDSF_UNCERTAIN | (fLibSearch ? WLDSF_LIBSEARCH : 0),
-                  pachName, cchName, NULL);
+                  pachName, cchName, &pWld->Global, NULL);
     if (!pSym)
         return NULL;
@@ -2084,5 +2104,5 @@
      */
     pSym = symAdd(pWld, pMod, WLDSF_PUBLIC | WLDSF_ALIAS | (fLibSearch ? WLDSF_LIBSEARCH : 0),
-                  pachAliasName, cchAliasName, &eAction);
+                  pachAliasName, cchAliasName, &pWld->Global, &eAction);
     if (!pSym)
         return NULL;
@@ -2095,5 +2115,5 @@
             {
                 PWLDSYM pSym2 = symAdd(pWld, pMod, WLDSF_UNDEF | (fLibSearch ? WLDSF_LIBSEARCH : 0),
-                                       pachName, cchName, NULL);
+                                       pachName, cchName, &pWld->Global, NULL);
                 if (!pSym2)
                     return NULL;
@@ -2146,5 +2166,5 @@
      */
     pSym = symAdd(pWld, pMod, WLDSF_COMM | (fLibSearch ? WLDSF_LIBSEARCH : 0),
-                  pachName, cchName, &eAction);
+                  pachName, cchName, &pWld->Global, &eAction);
     if (!pSym)
         return NULL;
@@ -2175,4 +2195,28 @@
 
     return pSym;
+}
+
+
+/**
+ * Destroys a symbol table, freeing all symbols 
+ *
+ * @param   pSymTab     The symbol table to destroy.
+ */
+static void symDestroyTab(PWLDSYMTAB pSymTab)
+{
+    unsigned        uHash;
+    for (uHash = 0; uHash < sizeof(pSymTab->ap) / sizeof(pSymTab->ap[0]); uHash++)
+    {
+        PWLDSYM     pSym = pSymTab->ap[uHash];
+        while (pSym)
+        {
+            PWLDSYM pNext = pSym->pHashNext;
+            if (pSym->paReferers)
+                free(pSym->paReferers);
+            free(pSym);
+            pSym = pNext;
+        }
+        pSymTab->ap[uHash] = NULL;
+    }
 }
 
@@ -2632,5 +2676,4 @@
     PWLDMOD     pObj;
     PWLDLIB     pLib;
-    unsigned    uHash;
 
     if (!pWld)
@@ -2665,16 +2708,6 @@
 
     /* free symbols */
-    for (uHash = 0; uHash < sizeof(pWld->Global.ap) / sizeof(pWld->Global.ap[0]); uHash++)
-    {
-        PWLDSYM     pSym = pWld->Global.ap[uHash];
-        while (pSym)
-        {
-            PWLDSYM pNext = pSym->pHashNext;
-            if (pSym->paReferers)
-                free(pSym->paReferers);
-            free(pSym);
-            pSym = pNext;
-        }
-    }
+    symDestroyTab(&pWld->Global);
+    symDestroyTab(&pWld->Exported);
 
     /* members and finally the instance structure. */
@@ -2809,6 +2842,6 @@
                 uOrdinal = pStmt->import.ordinal;
             pSym = symAddImport(pParam->pWld, pParam->pMod, 0,
+                                pStmt->import.internalname[0] ? pStmt->import.internalname : pStmt->import.entryname, -1,
                                 pStmt->import.entryname[0] ? pStmt->import.entryname : pStmt->import.internalname, -1,
-                                pStmt->import.internalname, -1,
                                 pStmt->import.modulename, -1,
                                 uOrdinal);
@@ -3460,5 +3493,5 @@
             PWLDSYM     pSymExp;
 
-            pSymExp = symLookup(pParam->pWld, pStmt->export.entryname);
+            pSymExp = symLookupExport(pParam->pWld, pStmt->export.entryname);
             if (pStmt->export.internalname[0])
                 pSymInt = symLookup(pParam->pWld, pStmt->export.internalname);
@@ -3703,10 +3736,10 @@
                         {
                             if (0)//pWld->fFlags & WLDC_LINKER_WLINK)
-                                rc = symEnum(pWld, &pWld->Global,
-                                             WLDSF_EXPORT | WLDSF_EXPORT_DEF | WLDSF_WEAK, WLDSF_EXPORT | WLDSF_EXPORT_DEF | WLDSF_WEAK | WLDSF_WEAKALIASDONE,
+                                rc = symEnum(pWld, &pWld->Exported,
+                                             WLDSF_EXPORT_DEF | WLDSF_WEAK, WLDSF_EXPORT_DEF | WLDSF_WEAK | WLDSF_WEAKALIASDONE,
                                              wldGenerateDefExportEnum, &param);
                             else
-                                rc = symEnum(pWld, &pWld->Global,
-                                             WLDSF_EXPORT | WLDSF_WEAK, WLDSF_EXPORT | WLDSF_WEAK | WLDSF_EXPORT_DEF | WLDSF_WEAKALIASDONE,
+                                rc = symEnum(pWld, &pWld->Exported,
+                                             WLDSF_WEAK, WLDSF_WEAK | WLDSF_EXPORT_DEF | WLDSF_WEAKALIASDONE,
                                              wldGenerateDefExportEnum, &param);
                         }
