Index: emxomf.c =================================================================== RCS file: /netlabs.cvs/libc/src/emx/src/emxomf/emxomf.c,v retrieving revision 1.1.1.6 diff -u -r1.1.1.6 emxomf.c --- emxomf.c 2005/06/28 14:22:36 1.1.1.6 +++ emxomf.c 2005/11/05 17:10:36 @@ -50,6 +50,10 @@ #define SF_FAR16 0x01 /* 16:16 pointer */ +/* Max symbol len (OMF size - hash - weak = 255 - 10 - 20 = 225) */ + +#define MAX_SYMBOL_LEN 225 + /* This structure holds additional data for symbols. */ struct symbol @@ -761,6 +765,19 @@ error ("Record too long"); } +/* This function will return a 32bit hash for the string pszName +*/ +unsigned int hash_string( const char* pszName) +{ + int cch = strlen( pszName), cch2; + const char *psz; + unsigned uHash = 5381; + + for (psz = pszName; cch > 0; psz++, cch--) /* hash alg: original djb2. */ + uHash += (uHash << 5) + *psz; + + return uHash; +} /* Put the string pszName into the current OMF record. In the OMF record, the string is preceded by a length byte. The @@ -771,7 +788,9 @@ static void put_nstr(const char *pszName, size_t cch) { - if (cch > 255) + /* weak symbols are already under 255 */ + /* but greater than MAX_SYMBOL_LEN -> skip hashing */ + if (cch > MAX_SYMBOL_LEN && strstr( pszName+MAX_SYMBOL_LEN, "$w$")==NULL) { /* Hash the symbol to help making it unique. * NOTE that the hash algorithm is not fixed, so is the !_%X marker too. @@ -779,20 +798,20 @@ */ char szHash[16]; int cch2; - const char *psz; - unsigned uHash; - for (psz = pszName, uHash = 5381, cch2 = cch; cch > 0; psz++, cch--) /* hash alg: original djb2. */ - uHash += (uHash << 5) + *psz; - cch2 = sprintf(szHash, "!_%X", 0x7fffffff & uHash); - if (!fits(1+255)) - doesn_fit(); - out_data[out_idx++] = 255; - memcpy(out_data + out_idx, pszName, 255); - memcpy(out_data + out_idx + 255 - cch2, szHash, cch2); - out_idx += 255; + cch2 = sprintf(szHash, "!_%08X", hash_string( pszName)); - warning ("Symbol length truncated to 255 characters (from %d) for `%s'", cch, pszName); + if (!fits(1+MAX_SYMBOL_LEN)) + doesn_fit(); + out_data[out_idx++] = MAX_SYMBOL_LEN + cch2; + memcpy(out_data + out_idx, pszName, MAX_SYMBOL_LEN); + memcpy(out_data + out_idx + MAX_SYMBOL_LEN, szHash, cch2); + *(out_data + out_idx + MAX_SYMBOL_LEN + cch2) = '\0'; + + warning ("put_nstr(): Symbol length truncated"); + warning ("put_nstr(): from %d `%s'", cch, pszName); + warning ("put_nstr(): to %d `%s'", strlen(out_data+out_idx), out_data+out_idx); + out_idx += (MAX_SYMBOL_LEN+cch2); } else { @@ -1106,7 +1125,8 @@ struct timeval tv = {0, 0}; const char *p1; char *p2, *p3; - + unsigned hash; + /* simple */ memcpy(weak_marker_simple, "$w$", 4); for (p1 = "\\/:", p2 = mod_name; *p1; p1++) @@ -1119,7 +1139,9 @@ else if (*p2 == '.') *p3++ = '_'; *p3 = '\0'; + weak_marker_simple_size = p3 - &weak_marker_simple[0]; + //sprintf( weak_marker_simple, "$w$%X", hash_string(weak_marker_simple)); /* timestamped: $w$[1-7][1-4]#[-1-7]#[1-123] */ gettimeofday(&tv, NULL); @@ -1145,33 +1167,31 @@ weak_marker_ts[cch2++] = '#'; } tv_prev = tv; - memcpy(&weak_marker_ts[cch2], &weak_marker_simple[3], weak_marker_simple_size - 3 + 1); - weak_marker_ts_size = cch2 + weak_marker_simple_size - 3; + + sprintf( weak_marker_simple, "$w$%08X_%08X", + hash_string(weak_marker_simple), + hash_string(weak_marker_ts)); + weak_marker_simple_size = strlen(weak_marker_simple); } /* generate the weak symbol name. */ - if (!opt_weakts && cch + weak_marker_simple_size < 255) /* total is one byte short of full length. */ + if (cch < MAX_SYMBOL_LEN) /* total is one byte short of full length. */ snprintf(pachName, cchName, "%s%s", pszOrgName, weak_marker_simple); - else if (cch + weak_marker_ts_size < 255) - snprintf(pachName, cchName, "%s%s", pszOrgName, weak_marker_ts); - else if (cch + 24 < 255) - snprintf(pachName, cchName, "%s%.16s", pszOrgName, weak_marker_ts); else { /* too long. */ - int cch3 = weak_marker_ts_size > 24 ? 24 : weak_marker_ts_size; + int cch3 = weak_marker_ts_size;// > 24 ? 24 : weak_marker_ts_size; + int cchl; char szHash[16]; const char *psz; unsigned uHash; - for (psz = pszOrgName, uHash = 5381; *psz; psz++) /* hash alg: original djb2. */ - uHash += (uHash << 5) + *psz; - - cch2 = sprintf(szHash, "!_%X", 0x7fffffff & uHash); - memcpy(pachName, pszOrgName, cch > 255 ? 255 : cch); - memcpy(&pachName[255 - cch3 - cch2], szHash, cch2); - memcpy(&pachName[255 - cch3], weak_marker_ts, cch3); - pachName[255] = '\0'; - warning ("Symbol length truncated to 255 characters (from %d) for `%s'", cch, pszOrgName); + + memcpy(pachName, pszOrgName, MAX_SYMBOL_LEN); + sprintf( pachName+MAX_SYMBOL_LEN, "!_%08X", hash_string( pszOrgName)); + strcat( pachName, weak_marker_simple); + warning ("Symbol length truncated to 255 characters"); + warning ("from %d `%s'", cch, pszOrgName); + warning (" to %d `%s'", strlen(pachName), pachName); } return pachName;