Changeset 1410


Ignore:
Timestamp:
Apr 30, 2004, 10:40:31 AM (21 years ago)
Author:
bird
Message:

Long symbols should work now.

Location:
trunk/src/emx/src/emxomf
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified trunk/src/emx/src/emxomf/emxomf.c

    • Property cvs2svn:cvs-rev changed from 1.37 to 1.38
    r1409 r1410  
    351351static char base_dir[256];
    352352
    353 /* This variable holds a normalized module name used with weak syms.  See get_mod_name(). */
    354 static char weak_mod_name[256];
     353/* This variable holds the simple weak marker for the current module. See get_mod_name(). */
     354static char weak_marker_simple[128];
     355static int  weak_marker_simple_size;
     356
     357/* This variable holds the timestamped weak marker for the current module. See get_mod_name(). */
     358static char weak_marker_ts[148];
     359static int  weak_marker_ts_size;
    355360
    356361/* This growing array holds the file name table for generating line
     
    777782  buffer_init (&sst);
    778783  buffer_init (&sst_reloc);
     784
     785  /* Init weak markers */
     786
     787  weak_marker_simple[0] = '\0';
     788  weak_marker_simple_size = 0;
     789  weak_marker_ts[0] = '\0';
     790  weak_marker_ts_size = 0;
    779791}
    780792
     
    913925
    914926
    915 /* Put the null-terminated string SRC into the current OMF record.  In
    916    the OMF record, the string is preceded by a length byte.  The
     927/* Put the null-terminated string pszName into the current OMF record. 
     928   In the OMF record, the string is preceded by a length byte.  The
    917929   string length must not exceed 255; if it is too long, display a
    918930   warning and truncate the string.  Moreover, there must be enough
     
    920932   message and abort. */
    921933
    922 static void put_str (const char *src)
    923 {
    924   char sz[256];
    925   int len;
    926 
    927   len = strlen (src);
    928   if (len > 255)
    929     { /* Hash the symbol to help making it unique. */
    930       const char *  psz = src;
    931       unsigned      uhash = 0;
    932       char          szhash[16];
    933       warning ("Symbol length truncated to 255 characters for `%s'", src);
    934       for (; *psz; psz++)
    935         uhash = ((uhash << 3) ^ (*psz & 0x15)); /** @todo fix this rather bad hash algorithm. */
    936       len = sprintf(szhash, "!_%X", 0x7fffffff & uhash);
    937       memcpy(sz, src, 255);
    938       memcpy(sz + 255 - len, szhash, len + 1);
    939       len = 255;
    940       src = &sz[0];
    941     }
    942   if (!fits (1+len))
    943     doesn_fit ();
    944   out_data[out_idx++] = (byte)len;
    945   memcpy (out_data+out_idx, src, len);
    946   out_idx += len;
     934static void put_str(const char *pszName)
     935{
     936    int cch = strlen(pszName);
     937    if (cch > 255)
     938    {
     939        /* Hash the symbol to help making it unique.
     940         * NOTE that the hash algorithm is not fixed, so is the !_%X marker too.
     941         *      the weakld is parsing it!
     942         */
     943        char        szHash[16];
     944        int         cch2;
     945        const char *psz;
     946        unsigned    uHash;
     947        for (psz = pszName, uHash = 5381; *psz; psz++)   /* hash alg: original djb2. */
     948            uHash += (uHash << 5) + *psz;
     949        cch2 = sprintf(szHash, "!_%X", 0x7fffffff & uHash);
     950
     951        if (!fits(1+255))
     952            doesn_fit();
     953        out_data[out_idx++] = 255;
     954        memcpy(out_data + out_idx, pszName, 255);
     955        memcpy(out_data + out_idx + 255 - cch2, szHash, cch2);
     956        out_idx += 255;
     957
     958        warning ("Symbol length truncated to 255 characters (from %d) for `%s'", cch, pszName);
     959    }
     960    else
     961    {
     962        if (!fits(1+cch))
     963            doesn_fit();
     964        out_data[out_idx++] = (byte)cch;
     965        memcpy(out_data+out_idx, pszName, cch);
     966        out_idx += cch;
     967    }
    947968}
    948969
     
    12641285 *                      new name will be written.
    12651286 * @param   cchName     Size of the buffer pointed to by pachName.
     1287 *                      This must be at least 256, the code make this assumption!
    12661288 * @remark I'm sorry this function is written in my coding style - not!
    12671289 * @remark Weak Hack Method 2.
     
    12871309        case N_WEAKB:               /* 0x11  Weak bss symbol. */
    12881310        {
    1289             if (!opt_weakts)
    1290                 snprintf(pachName, cchName, "%s$w$%s",
    1291                          pszOrgName, weak_mod_name);
    1292             else
     1311            int cch = strlen(pszOrgName);
     1312            int cch2;
     1313           
     1314            /* Init the markers if not done already. */
     1315            if (!weak_marker_simple[0])
    12931316            {
    1294                 struct timeval tv = {0, 0};
     1317                static struct timeval   tv_prev;
     1318                static unsigned         iOpaque = 1;
     1319                struct timeval          tv = {0, 0};
     1320                const char             *p1;
     1321                char                   *p2, *p3;
     1322
     1323                /* simple */
     1324                memcpy(weak_marker_simple, "$w$", 4);
     1325                for (p1 = "\\/:", p2 = mod_name; *p1; p1++)
     1326                  if ((p3 = strrchr(p2, *p1)) != NULL)
     1327                    p2 = p3 + 1;
     1328                p1 = &weak_marker_simple[sizeof(weak_marker_simple) - 1];
     1329                for (p3 = &weak_marker_simple[3]; *p2 && p3 < p1; p2++)
     1330                  if (isalnum(*p2) || *p2 == '_' || *p2 == '@')
     1331                      *p3++ = *p2;
     1332                  else if (*p2 == '.')
     1333                      *p3++ = '_';
     1334                *p3 = '\0';
     1335                weak_marker_simple_size = p3 - &weak_marker_simple[0];
     1336
     1337                /* timestamped: $w$[1-7][1-4]#[-1-7]#[1-123] */
    12951338                gettimeofday(&tv, NULL);
    1296                 snprintf(pachName, cchName, "%s$w$%s%lx%lx",
    1297                          pszOrgName, weak_mod_name, tv.tv_sec, tv.tv_usec);
     1339                memcpy(&weak_marker_ts[0], "$w$", 4);
     1340                ltoa(tv.tv_sec, &weak_marker_ts[3], 36);
     1341                cch2 = 3 + strlen(&weak_marker_ts[3]);
     1342                ltoa(tv.tv_usec, &weak_marker_ts[cch2], 36);
     1343                cch2 += strlen(&weak_marker_ts[cch2]);
     1344                weak_marker_ts[cch2++] = '#';
     1345                if (tv_prev.tv_usec == tv.tv_usec && tv_prev.tv_sec == tv.tv_sec)
     1346                {
     1347                    if (!iOpaque)   
     1348                    {
     1349                        unsigned short seed[3];
     1350                        seed[0] = (unsigned short)tv.tv_usec;
     1351                        seed[1] = (unsigned short)tv.tv_sec;
     1352                        seed[2] = (unsigned short)tv.tv_sec >> 16;
     1353                        iOpaque = nrand48(seed);
     1354                    }
     1355                    iOpaque++;
     1356                    ltoa(tv.tv_usec, &weak_marker_ts[cch2], 36);
     1357                    cch2 += strlen(&weak_marker_ts[cch2]);
     1358                    weak_marker_ts[cch2++] = '#';
     1359                }
     1360                tv_prev = tv;
     1361                memcpy(&weak_marker_ts[cch2], &weak_marker_simple[3], weak_marker_simple_size - 3 + 1);
     1362                weak_marker_ts_size = cch2 + weak_marker_simple_size - 3;
    12981363            }
     1364
     1365
     1366            /* generate the weak symbol name. */
     1367            if (!opt_weakts && cch + weak_marker_simple_size < 255) /* total is one byte short of full length. */
     1368                snprintf(pachName, cchName, "%s%s", pszOrgName, weak_marker_simple);
     1369            else if (cch + weak_marker_ts_size < 255)
     1370                snprintf(pachName, cchName, "%s%s", pszOrgName, weak_marker_ts);
     1371            else if (cch + 24 < 255)
     1372                snprintf(pachName, cchName, "%s%.16s", pszOrgName, weak_marker_ts);
     1373            else
     1374            {   /* too long. */
     1375                int         cch3 = weak_marker_ts_size > 24 ? 24 : weak_marker_ts_size;
     1376                char        szHash[16];
     1377                const char *psz;
     1378                unsigned    uHash;   
     1379                for (psz = pszOrgName, uHash = 5381; *psz; psz++)   /* hash alg: original djb2. */
     1380                    uHash += (uHash << 5) + *psz;
     1381
     1382                cch2 = sprintf(szHash, "!_%X", 0x7fffffff & uHash);
     1383                memcpy(pachName, pszOrgName, cch > 255 ? 255 : cch);
     1384                memcpy(&pachName[255 - cch3 - cch2], szHash, cch2);
     1385                memcpy(&pachName[255 - cch3], weak_marker_ts, cch3);
     1386                pachName[255] = '\0';
     1387                warning ("Symbol length truncated to 255 characters (from %d) for `%s'", cch, pszOrgName);
     1388            }
     1389
    12991390            return pachName;
    13001391        }
     
    28222913  int i, len, ok;
    28232914  const char *p1, *p2;
    2824   char *p3;
    28252915
    28262916  base_dir[0] = '\0';
     
    28852975      base_dir[1] = ':';
    28862976    }
    2887 
    2888   /* Find the base name and length (excluding extension)
    2889      This is used for weak symbol handling. */
    2890   for (p1 = "\\/:", p2 = mod_name; *p1; p1++)
    2891     if ((p3 = strrchr(p2, *p1)) != NULL)
    2892       p2 = p3 + 1;
    2893   for (p3 = weak_mod_name; *p2; p2++)
    2894     if (isalnum(*p2) || *p2 == '$' || *p2 == '_' || *p2 == '@')
    2895         *p3++ = *p2;
    2896     else if (*p2 == '.')
    2897         *p3++ = '_';
    2898   *p3 = '\0';
    28992977}
    29002978
  • TabularUnified trunk/src/emx/src/emxomf/weakld.c

    • Property cvs2svn:cvs-rev changed from 1.27 to 1.28
    r1409 r1410  
    5454#define WLDINTERR(pWld, pMod)   wldIntErr(pWld, pMod, __FILE__, __LINE__, __FUNCTION__);
    5555
    56 /*#define WLD_ENABLED_DBG*/
     56//#define WLD_ENABLED_DBG
    5757#ifdef WLD_ENABLED_DBG
    5858#define SYMDBG(pSym, pszMsg)    symDbg(pSym, pszMsg);
     
    7272                                  )
    7373
     74/** Compares a existing symbol with a new symbol. */
     75#define SYM_EQUAL(pWld, pSym, _pszName, _fFlags, _uHash, _cchName) \
     76    (   (pSym)->uHash == (_uHash)                                                   \
     77     && ( !((_fFlags) & WLDSF_TRUNCATED) && !((pSym)->fFlags & WLDSF_TRUNCATED)     \
     78         ? (pSym)->pszName == (_pszName)                                            \
     79         : symCompareTrucated(pWld, pSym, _pszName, _cchName) )                     \
     80      )
     81     
     82/** Compares a existing symbol with a potential symbol. */
     83#define SYM_EQUAL2(pWld, pSym, _pszName, _fFlags, _uHash, _cchName, _pfn) \
     84    (   (pSym)->uHash == (_uHash)                                                   \
     85     && ( !((_fFlags) & WLDSF_TRUNCATED) && !((pSym)->fFlags & WLDSF_TRUNCATED)     \
     86         ? !_pfn((pSym)->pszName, (_pszName), (_cchName)) && !(pSym)->pszName[(_cchName)] \
     87         : symCompareTrucated(pWld, pSym, _pszName, _cchName) )                     \
     88      )
     89
    7490
    7591
     
    8197#include <stdarg.h>
    8298#include <string.h>
     99#include <ctype.h>
    83100#include <sys/types.h>
    84101#include <sys/time.h>
     
    170187
    171188/**
     189 * Truncated EXTDEF name.
     190 */
     191typedef struct wldsymtrunc
     192{
     193    /** Full name. */
     194    const char *        pszName;
     195    /** Pointer to the next symbol. */
     196    struct wldsymtrunc *pNext;
     197} WLDSYMTRUNC, *PWLDSYMTRUNC;
     198
     199/**
    172200 * Symbol structure.
    173201 */
     
    178206    /** Weak name - for weak symbols only. */
    179207    const char *        pszWeakName;
     208    /** The full hash value. */
     209    unsigned            uHash;
     210    /** LIFO of truncated name variations. */
     211    PWLDSYMTRUNC        pTrunc;
    180212
    181213    /** Symbol flags. */
     
    241273         */
    242274        WLDSF_WEAKALIASDONE = 0x8000,
     275       
     276        /** Internal flag which indicates that the symbol have been
     277         * truncated by emxomf. */
     278        WLDSF_TRUNCATED = 0x10000,
     279         
    243280    }                   fFlags;
    244281
     
    441478} WLDSLEPARAM, *PWLDSLEPARAM;
    442479static int          symSearchLibEnum(PWLD pWld, PWLDSYM pSym, void *pvUser);
    443 static inline unsigned symHash(const char* pszSym, unsigned cch);
     480static inline unsigned symHash(const char* pszSym, unsigned cch, unsigned fWldCaseFlag);
     481static int          symCompareTrucated(PWLD pWld, PWLDSYM pSym1, const char *pszName2, unsigned cchName2);
    444482static const char * symGetDescr(PWLDSYM pSym);
    445483static void         symDumpReferers(PWLDSYM pSym);
     
    11911229 * Calculate the hash value of a symbol.
    11921230 * @returns hash value.
    1193  * @param   pszSym  Symbol to calculate it for.
    1194  * @param   cch     Symbol length.
     1231 * @param   pszSym          Symbol to calculate it for.
     1232 * @param   cch             Symbol length.
     1233 * @param   fWldCaseFlag    Case flag from the linker instance.
     1234 *                          Not implemented yet.
    11951235 * @todo    This ain't respecting case sensitivity.
    11961236 */
    1197 static inline unsigned symHash(const char* pszSym, unsigned cch)
    1198 {
    1199     unsigned uHash = 0;
     1237static inline unsigned symHash(const char* pszSym, unsigned cch, unsigned fWldCaseFlag)
     1238{
     1239    /* hash alg: original djb2. */
     1240    unsigned uHash = 5381;
    12001241    while (     cch
    12011242           &&   (pszSym[0] != '$' || pszSym[1] != 'w' || pszSym[2] != '$')
    12021243             )
    12031244    {
    1204         uHash = uHash * 63377 + *pszSym;
     1245        if (    pszSym[0] == '!'
     1246            &&  pszSym[1] == '_'
     1247            &&  cch > 200)
     1248        {
     1249            uHash = strtol(&pszSym[2], NULL, 16);
     1250            break;
     1251        }
     1252        uHash += (uHash << 5) + *pszSym;
    12051253        pszSym++;
    12061254        cch--;
    12071255    }
    1208     uHash %= WLDSYM_HASH_SIZE;
    12091256    return uHash;
    12101257}
     1258
     1259
     1260/**
     1261 * Internal worker for SYM_EQUAL()
     1262 *
     1263 * Compares truncated symbols. The hash for these symbols matches and at least
     1264 * one of them is truncated.
     1265 *
     1266 * @returns 1 if matches
     1267 * @returns 0 if not matching.
     1268 * @param   pWld        Linker Instance.
     1269 * @param   pSym1       Symbol 1.
     1270 * @param   pszName2    Symbol 2 name.
     1271 * @param   cchName2    Symbol 2 name length.
     1272 */
     1273static int symCompareTrucated(PWLD pWld, PWLDSYM pSym1, const char *pszName2, unsigned cchName2)
     1274{
     1275    /* Truncated string comparision means comparing MIN(cchName2, strlen(pSym1->pszName)) chars. */
     1276    const char *pszName1 = pSym1->pszName;
     1277    if (pWld->fFlags & WLDC_CASE_INSENSITIVE)
     1278    {
     1279        while (cchName2-- > 0 && *pszName1)
     1280        {
     1281            if (toupper(*pszName1) != toupper(*pszName2))
     1282                return 0;
     1283            pszName1++;
     1284            pszName2++;
     1285        }
     1286    }
     1287    else
     1288    {
     1289        while (cchName2-- > 0 && *pszName1)
     1290        {
     1291            if (*pszName1 != *pszName2)
     1292                return 0;
     1293            pszName1++;
     1294            pszName2++;
     1295        }
     1296    }
     1297    return 1;
     1298}
     1299
     1300
    12111301
    12121302/**
     
    12221312    const char *psz;
    12231313    unsigned    cchName;
    1224     unsigned    uHash;
     1314    unsigned    fFlags = 0;
     1315    unsigned    uHash = 0;
    12251316
    12261317    /*
    1227      * Calculate the hash of the symbol
    1228      *
    12291318     * It's easier just to add it to the string table than starting to
    12301319     * check the correct case function and such. As there is a good
     
    12331322     * (if possible) and gain everywhere.
    12341323     */
    1235     psz = strstr(pszName, "$w$");
    1236     cchName = psz ? psz - pszName : strlen(pszName);
     1324
     1325    /* look for weak suffix and trucation */
     1326    cchName = strlen(pszName);
     1327    for (psz = pszName + cchName - 1; psz > pszName; psz--)
     1328        if (    psz[0] == '$'
     1329            &&  psz[1] == 'w'
     1330            &&  psz[2] == '$')
     1331        {
     1332            cchName = psz - pszName;
     1333            if (cchName > 200)
     1334                break;
     1335        }
     1336        else if (    psz[0] == '!'
     1337                 &&  psz[1] == '_'
     1338                 &&  psz - psz > 200)
     1339        {
     1340            uHash = strtol(&psz[2], NULL, 16);
     1341            fFlags |= WLDSF_TRUNCATED;
     1342            cchName = psz - pszName;
     1343            break;
     1344        }
     1345
    12371346    pszName = (pWld->fFlags & WLDC_CASE_INSENSITIVE ? strpool_addnu : strpool_addn)(pWld->pStrMisc, pszName, cchName);
    1238     uHash = symHash(pszName, cchName);
     1347    if (!fFlags)
     1348        uHash = symHash(pszName, cchName, pWld->fFlags & WLDC_CASE_INSENSITIVE);
    12391349
    12401350    /* look it up */
    1241     for (pSym = pWld->Global.ap[uHash]; pSym; pSym = pSym->pHashNext)
    1242        if (pSym->pszName == pszName)
     1351    for (pSym = pWld->Global.ap[uHash % WLDSYM_HASH_SIZE]; pSym; pSym = pSym->pHashNext)
     1352       if (SYM_EQUAL(pWld, pSym, pszName, fFlags, uHash, cchName))
    12431353           return pSym;
    12441354
     
    13831493static int          symMatchUnDef(PWLD pWld, const unsigned char *pachPascalString, PWLDSYM pSym)
    13841494{
    1385     int         cch = *pachPascalString;
    1386     const char *psz = pachPascalString + 1;
    1387     const char *pszWeak;
    1388     int (*pfn)(const char *, const char *, size_t) = (pWld->fFlags & WLDC_CASE_INSENSITIVE) ? strnicmp : strncmp;
    1389 
    1390     /* look for weak suffix */
    1391     for (pszWeak = psz + cch - 1; pszWeak > psz; pszWeak--)
    1392         if (    pszWeak[0] == '$'
    1393             &&  pszWeak[1] == 'w'
    1394             &&  pszWeak[2] == '$')
    1395         {
    1396             cch = pszWeak - psz;
     1495    int         cchName = *pachPascalString;
     1496    const char *pszName = pachPascalString + 1;
     1497    const char *psz;
     1498    unsigned    fFlags = 0;
     1499    unsigned    uHash = 0;
     1500    int        (*pfn)(const char *, const char *, size_t) = pWld->fFlags & WLDC_CASE_INSENSITIVE ? strnicmp : strncmp;
     1501
     1502    /* look for weak suffix and trucation */
     1503    for (psz = pszName + cchName - 1; psz > pszName; psz--)
     1504        if (    psz[0] == '$'
     1505            &&  psz[1] == 'w'
     1506            &&  psz[2] == '$')
     1507        {
     1508            cchName = psz - pszName;
     1509            if (cchName > 200)
     1510                break;
     1511        }
     1512        else if (    psz[0] == '!'
     1513                 &&  psz[1] == '_'
     1514                 &&  psz - pszName > 200)
     1515        {
     1516            uHash = strtol(&psz[2], NULL, 16);
     1517            fFlags |= WLDSF_TRUNCATED;
     1518            cchName = psz - pszName;
    13971519            break;
    13981520        }
     1521
     1522    /* @todo: this isn't 100% correct when we're talking case in sensitivity. */
     1523    if (!fFlags)
     1524        uHash = symHash(pszName, cchName, pWld->fFlags & WLDC_CASE_INSENSITIVE);
    13991525
    14001526    /* compare */
    14011527    if (pSym)
    1402         return !pfn(pSym->pszName, psz, cch) && !pSym->pszName[cch];
     1528        return SYM_EQUAL2(pWld, pSym, pszName, fFlags, uHash, cchName, pfn);
    14031529    else
    14041530    {
    1405         /* @todo: this isn't 100% correct when we're talking case in sensitivity. */
    1406         unsigned uHash = symHash(psz, cch);
    1407         for (pSym = pWld->Global.ap[uHash]; pSym; pSym = pSym->pHashNext)
     1531        for (pSym = pWld->Global.ap[uHash % WLDSYM_HASH_SIZE]; pSym; pSym = pSym->pHashNext)
    14081532        {
    14091533            if ((pSym->fFlags & (WLDSF_TYPEMASK | WLDSF_WEAK)) == WLDSF_UNDEF)
    14101534            {
    1411                 if (!pfn(pSym->pszName, psz, cch) && !pSym->pszName[cch])
     1535                if (SYM_EQUAL2(pWld, pSym, pszName, fFlags, uHash, cchName, pfn))
    14121536                    return 1;
    14131537            }
     
    15501674    const char *pszName;                /* The symbol name in the string pool */
    15511675    int         cchNameWeak = 0;        /* Indicator and length of the weak name. (0 if not weak) */
     1676    int         cchNameTrunc = 0;       /* Full length of truncated symbol name.  */
    15521677    /* general stuff */
    15531678    const char *    pach;
     
    15581683        cchName = strlen(pachName);
    15591684
    1560     /* adjust namelength / check for weak name / hash name */
     1685    /* adjust namelength / check for weak name and trucation / hash name */
    15611686    pach = pachName + cchName - 2;      /* "$w$" */
    15621687    while (pach-- > pachName)
     1688    {
    15631689        if (    pach[0] == '$'
    15641690            &&  pach[1] == 'w'
     
    15711697            if ((fFlags & WLDSF_TYPEMASK) == WLDSF_WKEXT)
    15721698                fFlags = (fFlags & ~WLDSF_TYPEMASK) | WLDSF_UNDEF;
     1699           
     1700            if (cchName <= 200)
     1701                break;
     1702        }
     1703        else if (    pach[0] == '!'
     1704                 &&  pach[1] == '_'
     1705                 &&  pach - pachName > 200)
     1706        {
     1707            uHash = strtol(&pach[2], NULL, 16);
     1708            fFlags |= WLDSF_TRUNCATED;
     1709            cchNameTrunc = cchNameWeak ? cchNameWeak : cchName;
     1710            cchName = pach - pachName;
    15731711            break;
    15741712        }
     1713    }
    15751714    pszName = (pWld->fFlags & WLDC_CASE_INSENSITIVE ? strpool_addnu : strpool_addn)(pWld->pStrMisc, pachName, cchName);
    1576     uHash = symHash(pszName, cchName);
     1715    if (!(fFlags & WLDSF_TRUNCATED))
     1716        uHash = symHash(pszName, cchName, pWld->fFlags & WLDC_CASE_INSENSITIVE);
    15771717
    15781718    /* search for existing symbol  */
    1579     pSym = pWld->Global.ap[uHash];
    1580     while (pSym && pSym->pszName != pszName)
    1581         pSym = pSym->pHashNext;
     1719    for (pSym = pWld->Global.ap[uHash % WLDSYM_HASH_SIZE]; pSym; pSym = pSym->pHashNext)
     1720        if (SYM_EQUAL(pWld, pSym, pszName, fFlags, uHash, cchName))
     1721            break;
    15821722
    15831723    if (!pSym)
    15841724    {
    15851725        /*
    1586          * new symol - this is easy!
     1726         * new symbol - this is easy!
    15871727         */
    15881728        pSym = xmalloc(sizeof(*pSym));
    15891729        memset(pSym, 0, sizeof(*pSym));
    1590         pSym->fFlags = fFlags;
     1730        pSym->fFlags  = fFlags;
    15911731        pSym->pszName = pszName;
     1732        pSym->uHash   = uHash;
    15921733        if (cchNameWeak)
    15931734        {
     
    15961737            WLDINFO(pWld, ("Weak symbol '%s'.", pSym->pszWeakName));
    15971738        }
    1598         pSym->pHashNext = pWld->Global.ap[uHash];
    1599         pWld->Global.ap[uHash] = pSym;
     1739        pSym->pHashNext = pWld->Global.ap[uHash % WLDSYM_HASH_SIZE];
     1740        pWld->Global.ap[uHash % WLDSYM_HASH_SIZE] = pSym;
    16001741        if (peAction) *peAction = WLDSA_NEW;
    16011742        WLDDBG2(("symAdd: New symbol '%s'", pSym->pszName));
     
    17281869
    17291870    /*
    1730      * Maintain the module pointer and referers.
     1871     * Maintain the module pointer, referers and truncation aliases.
    17311872     */
    17321873    if (pSym)
     
    17451886                    pSym->paReferers = xrealloc(pSym->paReferers, sizeof(pSym->paReferers[0]) * (pSym->cReferers + 64));
    17461887                pSym->paReferers[pSym->cReferers++] = pMod;
     1888            }
     1889        }
     1890       
     1891        /*
     1892         * Maintain list of truncated aliases.
     1893         */
     1894        if (    !SYM_IS_DEFINED(fFlags)
     1895            && ((fFlags & WLDSF_TRUNCATED) || (pSym->fFlags & WLDSF_TRUNCATED)))
     1896        {
     1897            PWLDSYMTRUNC    pTrunc = pSym->pTrunc;
     1898            const char     *pszSubName = pSym->pszWeakName;
     1899            if (!pszSubName)
     1900                pszSubName = strpool_addn(pWld->pStrMisc, pachName, cchNameTrunc);
     1901
     1902            while (pTrunc && pTrunc->pszName != pszSubName)
     1903                pTrunc = pTrunc->pNext;
     1904            if (!pTrunc)
     1905            {
     1906                pTrunc = xmalloc(sizeof(*pTrunc));
     1907                pTrunc->pszName = pszSubName;
     1908                pTrunc->pNext = pSym->pTrunc;
     1909                pSym->pTrunc = pTrunc;
    17471910            }
    17481911        }
     
    32573420static int      wldGenerateObjEnum(PWLD pWld, PWLDSYM pSym, void *pvUser)
    32583421{
     3422    const char     *pszSubName = pSym->pszWeakName;
     3423    PWLDGOEPARAM    pParam = (PWLDGOEPARAM)pvUser;
     3424    int             cch;
     3425    WLDSYMTRUNC     Trunc;
     3426    PWLDSYMTRUNC    pTrunc;
     3427
     3428    /*
     3429     * If weak, we'll make fake trunc record.
     3430     */
    32593431    if (pSym->pszWeakName)
    32603432    {
    3261         PWLDGOEPARAM    pParam = (PWLDGOEPARAM)pvUser;
    3262         #pragma pack(1)
    3263         struct omfstuff
    3264         {
    3265             OMFREC  hdr;
    3266             union
     3433        Trunc.pNext   = pSym->pTrunc;
     3434        Trunc.pszName = pSym->pszName;
     3435        pTrunc = &Trunc;
     3436    }
     3437    else
     3438    {
     3439        pTrunc = pSym->pTrunc;
     3440        pszSubName = pSym->pszName;
     3441    }
     3442    cch = strlen(pszSubName);
     3443
     3444    /*
     3445     * Walk trunc record list.
     3446     */
     3447    while (pTrunc)
     3448    {
     3449        if (pTrunc->pszName != pszSubName)
     3450        {
     3451            #pragma pack(1)
     3452            struct omfstuff
    32673453            {
    3268                 char        ach[640];
    3269                 OMFLIBHDRX  libhdr;
    3270             };
    3271         } omf;
    3272         #pragma pack()
    3273         int             cch = strlen(pSym->pszWeakName);
    3274         int             cchAlias = strlen(pSym->pszName);
    3275 
    3276         WLDINFO(pWld, ("using weak %s for %s", pSym->pszWeakName, pSym->pszName));
    3277 
    3278         /* paranoia */
    3279         if (cchAlias > 255)
    3280         {
    3281             wldErr(pWld, "Symbol '%s' are too long (%d).", pSym->pszName, cchAlias);
    3282             return -1;
    3283         }
    3284         if (cch > 255)
    3285         {
    3286             wldErr(pWld, "Symbol '%s' are too long (%d).", pSym->pszWeakName, cch);
    3287             return -1;
    3288         }
    3289 
    3290         /* end the current object? */
    3291         if ((pWld->fFlags & WLDC_LINKER_LINK386) && pParam->cAliases >= 32)
    3292         {
    3293             int rc = wldObjEnd(pWld, pParam->phFile, 32);
    3294             if (rc)
    3295                 return rc;
    3296             pParam->cAliases = 0;
    3297         }
    3298 
    3299         /* make new object ? */
    3300         if (!pParam->cAliases)
    3301         {
    3302             sprintf(omf.ach, "wk%d.obj", pParam->iLibFile++);
    3303             int rc = wldObjStart(pWld, pParam->phFile, omf.ach);
    3304             if (rc)
    3305                 return rc;
    3306         }
    3307 
    3308         /* Alias record */
    3309         omf.hdr.chType = ALIAS;
    3310         omf.hdr.cb = cchAlias + cch + 3;
    3311         omf.ach[0] = cchAlias;
    3312         memcpy(&omf.ach[1], pSym->pszName, cchAlias);           /* alias */
    3313         omf.ach[cchAlias + 1] = cch;
    3314         memcpy(&omf.ach[cchAlias + 2], pSym->pszWeakName, cch); /* subtitute */
    3315         omf.ach[cchAlias + cch + 2] = 0; /* crc */
    3316         if (fwrite(&omf, omf.hdr.cb + sizeof(OMFREC), 1, pParam->phFile) != 1)
    3317         {
    3318             wldErr(pWld, "Error occured while writing weak aliases. (2)");
    3319             return -1;
    3320         }
    3321         pParam->cAliases++;
    3322     }
     3454                OMFREC  hdr;
     3455                union
     3456                {
     3457                    char        ach[640];
     3458                    OMFLIBHDRX  libhdr;
     3459                };
     3460            } omf;
     3461            #pragma pack()
     3462            int             cchAlias = strlen(pTrunc->pszName);
     3463
     3464            WLDINFO(pWld, ("using weak/trunc %s for %s", pszSubName, pTrunc->pszName));
     3465
     3466            /* paranoia */
     3467            if (cchAlias > 255)
     3468            {
     3469                wldErr(pWld, "Symbol '%s' are too long (%d).", pTrunc->pszName, cchAlias);
     3470                return -1;
     3471            }
     3472            if (cch > 255)
     3473            {
     3474                wldErr(pWld, "Symbol '%s' are too long (%d).", pszSubName, cch);
     3475                return -1;
     3476            }
     3477
     3478            /* end the current object? */
     3479            if ((pWld->fFlags & WLDC_LINKER_LINK386) && pParam->cAliases >= 32)
     3480            {
     3481                int rc = wldObjEnd(pWld, pParam->phFile, 32);
     3482                if (rc)
     3483                    return rc;
     3484                pParam->cAliases = 0;
     3485            }
     3486
     3487            /* make new object ? */
     3488            if (!pParam->cAliases)
     3489            {
     3490                sprintf(omf.ach, "wk%d.obj", pParam->iLibFile++);
     3491                int rc = wldObjStart(pWld, pParam->phFile, omf.ach);
     3492                if (rc)
     3493                    return rc;
     3494            }
     3495
     3496            /* Alias record */
     3497            omf.hdr.chType = ALIAS;
     3498            omf.hdr.cb = cchAlias + cch + 3;
     3499            omf.ach[0] = cchAlias;
     3500            memcpy(&omf.ach[1], pTrunc->pszName, cchAlias);           /* alias */
     3501            omf.ach[cchAlias + 1] = cch;
     3502            memcpy(&omf.ach[cchAlias + 2], pszSubName, cch); /* subtitute */
     3503            omf.ach[cchAlias + cch + 2] = 0; /* crc */
     3504            if (fwrite(&omf, omf.hdr.cb + sizeof(OMFREC), 1, pParam->phFile) != 1)
     3505            {
     3506                wldErr(pWld, "Error occured while writing weak/trunc aliases. (2)");
     3507                return -1;
     3508            }
     3509            pParam->cAliases++;
     3510        }
     3511
     3512        /* next */
     3513        pTrunc = pTrunc->pNext;
     3514    }
     3515
    33233516    return 0;
    33243517}
     
    36513844                         * See defect #483 for details. Short summary: an array calculation in ilink is
    36523845                         * assuming that library objects have less EXTDEFs than the object ones. So, for
    3653                          * pass2 an EXTDEF array may become too short.
     3846                         * pass2 an EXTDEF array may become too small.
    36543847                         */
    36553848                        WLDINFO(pWld, ("cWeakAliases=%d cMaxObjExts=%d cMaxLibExts=%d",
Note: See TracChangeset for help on using the changeset viewer.