| 1 | Index: emxomf.c
|
|---|
| 2 | ===================================================================
|
|---|
| 3 | RCS file: /netlabs.cvs/libc/src/emx/src/emxomf/emxomf.c,v
|
|---|
| 4 | retrieving revision 1.1.1.6
|
|---|
| 5 | diff -u -r1.1.1.6 emxomf.c
|
|---|
| 6 | --- emxomf.c 2005/06/28 14:22:36 1.1.1.6
|
|---|
| 7 | +++ emxomf.c 2005/11/11 16:39:04
|
|---|
| 8 | @@ -50,6 +50,12 @@
|
|---|
| 9 |
|
|---|
| 10 | #define SF_FAR16 0x01 /* 16:16 pointer */
|
|---|
| 11 |
|
|---|
| 12 | +/* Max symbol len (OMF size - hash - weak = 255 - 10 - 20 = 225) */
|
|---|
| 13 | +
|
|---|
| 14 | +#define MAX_SYMBOL_LEN 225
|
|---|
| 15 | +#define MAX_SYMBOL_HASH 10
|
|---|
| 16 | +#define MAX_SYMBOL_WEAK 20
|
|---|
| 17 | +
|
|---|
| 18 | /* This structure holds additional data for symbols. */
|
|---|
| 19 |
|
|---|
| 20 | struct symbol
|
|---|
| 21 | @@ -761,6 +767,19 @@
|
|---|
| 22 | error ("Record too long");
|
|---|
| 23 | }
|
|---|
| 24 |
|
|---|
| 25 | +/* This function will return a 32bit hash for the string pszName
|
|---|
| 26 | +*/
|
|---|
| 27 | +unsigned int hash_string( const char* pszName)
|
|---|
| 28 | +{
|
|---|
| 29 | + int cch = strlen( pszName), cch2;
|
|---|
| 30 | + const char *psz;
|
|---|
| 31 | + unsigned uHash = 5381;
|
|---|
| 32 | +
|
|---|
| 33 | + for (psz = pszName; cch > 0; psz++, cch--) /* hash alg: original djb2. */
|
|---|
| 34 | + uHash += (uHash << 5) + *psz;
|
|---|
| 35 | +
|
|---|
| 36 | + return uHash;
|
|---|
| 37 | +}
|
|---|
| 38 |
|
|---|
| 39 | /* Put the string pszName into the current OMF record.
|
|---|
| 40 | In the OMF record, the string is preceded by a length byte. The
|
|---|
| 41 | @@ -771,7 +790,9 @@
|
|---|
| 42 |
|
|---|
| 43 | static void put_nstr(const char *pszName, size_t cch)
|
|---|
| 44 | {
|
|---|
| 45 | - if (cch > 255)
|
|---|
| 46 | + /* weak symbols are already under 255 */
|
|---|
| 47 | + /* but greater than MAX_SYMBOL_LEN -> skip hashing */
|
|---|
| 48 | + if (cch > MAX_SYMBOL_LEN && strstr( pszName, "$w$")==NULL)
|
|---|
| 49 | {
|
|---|
| 50 | /* Hash the symbol to help making it unique.
|
|---|
| 51 | * NOTE that the hash algorithm is not fixed, so is the !_%X marker too.
|
|---|
| 52 | @@ -779,20 +800,20 @@
|
|---|
| 53 | */
|
|---|
| 54 | char szHash[16];
|
|---|
| 55 | int cch2;
|
|---|
| 56 | - const char *psz;
|
|---|
| 57 | - unsigned uHash;
|
|---|
| 58 | - for (psz = pszName, uHash = 5381, cch2 = cch; cch > 0; psz++, cch--) /* hash alg: original djb2. */
|
|---|
| 59 | - uHash += (uHash << 5) + *psz;
|
|---|
| 60 | - cch2 = sprintf(szHash, "!_%X", 0x7fffffff & uHash);
|
|---|
| 61 |
|
|---|
| 62 | - if (!fits(1+255))
|
|---|
| 63 | - doesn_fit();
|
|---|
| 64 | - out_data[out_idx++] = 255;
|
|---|
| 65 | - memcpy(out_data + out_idx, pszName, 255);
|
|---|
| 66 | - memcpy(out_data + out_idx + 255 - cch2, szHash, cch2);
|
|---|
| 67 | - out_idx += 255;
|
|---|
| 68 | + cch2 = sprintf(szHash, "!_%08X", hash_string( pszName));
|
|---|
| 69 |
|
|---|
| 70 | - warning ("Symbol length truncated to 255 characters (from %d) for `%s'", cch, pszName);
|
|---|
| 71 | + if (!fits(1+MAX_SYMBOL_LEN))
|
|---|
| 72 | + doesn_fit();
|
|---|
| 73 | + out_data[out_idx++] = MAX_SYMBOL_LEN + cch2;
|
|---|
| 74 | + memcpy(out_data + out_idx, pszName, MAX_SYMBOL_LEN);
|
|---|
| 75 | + memcpy(out_data + out_idx + MAX_SYMBOL_LEN, szHash, cch2);
|
|---|
| 76 | + *(out_data + out_idx + MAX_SYMBOL_LEN + cch2) = '\0';
|
|---|
| 77 | +
|
|---|
| 78 | + warning ("put_nstr(): Symbol length truncated");
|
|---|
| 79 | + warning ("put_nstr(): from %d `%s'", cch, pszName);
|
|---|
| 80 | + warning ("put_nstr(): to %d `%s'", strlen(out_data+out_idx), out_data+out_idx);
|
|---|
| 81 | + out_idx += (MAX_SYMBOL_LEN+cch2);
|
|---|
| 82 | }
|
|---|
| 83 | else
|
|---|
| 84 | {
|
|---|
| 85 | @@ -962,7 +983,12 @@
|
|---|
| 86 |
|
|---|
| 87 | static void add_extdef (int *pstarted, const char *name, int type)
|
|---|
| 88 | {
|
|---|
| 89 | - if (*pstarted && !fits (strlen (name) + 3 + (type > 127)))
|
|---|
| 90 | + int len = strlen(name);
|
|---|
| 91 | + // YD if greater than MAX_SYMBOL_LEN, take account of hashing!
|
|---|
| 92 | + if (len > MAX_SYMBOL_LEN)
|
|---|
| 93 | + len += MAX_SYMBOL_HASH;
|
|---|
| 94 | +
|
|---|
| 95 | + if (*pstarted && !fits (len + 3 + (type > 127)))
|
|---|
| 96 | {
|
|---|
| 97 | write_rec ();
|
|---|
| 98 | *pstarted = FALSE;
|
|---|
| 99 | @@ -1106,7 +1134,8 @@
|
|---|
| 100 | struct timeval tv = {0, 0};
|
|---|
| 101 | const char *p1;
|
|---|
| 102 | char *p2, *p3;
|
|---|
| 103 | -
|
|---|
| 104 | + unsigned hash;
|
|---|
| 105 | +
|
|---|
| 106 | /* simple */
|
|---|
| 107 | memcpy(weak_marker_simple, "$w$", 4);
|
|---|
| 108 | for (p1 = "\\/:", p2 = mod_name; *p1; p1++)
|
|---|
| 109 | @@ -1119,7 +1148,9 @@
|
|---|
| 110 | else if (*p2 == '.')
|
|---|
| 111 | *p3++ = '_';
|
|---|
| 112 | *p3 = '\0';
|
|---|
| 113 | +
|
|---|
| 114 | weak_marker_simple_size = p3 - &weak_marker_simple[0];
|
|---|
| 115 | + //sprintf( weak_marker_simple, "$w$%X", hash_string(weak_marker_simple));
|
|---|
| 116 |
|
|---|
| 117 | /* timestamped: $w$[1-7][1-4]#[-1-7]#[1-123] */
|
|---|
| 118 | gettimeofday(&tv, NULL);
|
|---|
| 119 | @@ -1145,33 +1176,31 @@
|
|---|
| 120 | weak_marker_ts[cch2++] = '#';
|
|---|
| 121 | }
|
|---|
| 122 | tv_prev = tv;
|
|---|
| 123 | - memcpy(&weak_marker_ts[cch2], &weak_marker_simple[3], weak_marker_simple_size - 3 + 1);
|
|---|
| 124 | - weak_marker_ts_size = cch2 + weak_marker_simple_size - 3;
|
|---|
| 125 | +
|
|---|
| 126 | + sprintf( weak_marker_simple, "$w$%08X_%08X",
|
|---|
| 127 | + hash_string(weak_marker_simple),
|
|---|
| 128 | + hash_string(weak_marker_ts));
|
|---|
| 129 | + weak_marker_simple_size = strlen(weak_marker_simple);
|
|---|
| 130 | }
|
|---|
| 131 |
|
|---|
| 132 |
|
|---|
| 133 | /* generate the weak symbol name. */
|
|---|
| 134 | - if (!opt_weakts && cch + weak_marker_simple_size < 255) /* total is one byte short of full length. */
|
|---|
| 135 | + if (cch < MAX_SYMBOL_LEN) /* total is one byte short of full length. */
|
|---|
| 136 | snprintf(pachName, cchName, "%s%s", pszOrgName, weak_marker_simple);
|
|---|
| 137 | - else if (cch + weak_marker_ts_size < 255)
|
|---|
| 138 | - snprintf(pachName, cchName, "%s%s", pszOrgName, weak_marker_ts);
|
|---|
| 139 | - else if (cch + 24 < 255)
|
|---|
| 140 | - snprintf(pachName, cchName, "%s%.16s", pszOrgName, weak_marker_ts);
|
|---|
| 141 | else
|
|---|
| 142 | { /* too long. */
|
|---|
| 143 | - int cch3 = weak_marker_ts_size > 24 ? 24 : weak_marker_ts_size;
|
|---|
| 144 | + int cch3 = weak_marker_ts_size;// > 24 ? 24 : weak_marker_ts_size;
|
|---|
| 145 | + int cchl;
|
|---|
| 146 | char szHash[16];
|
|---|
| 147 | const char *psz;
|
|---|
| 148 | unsigned uHash;
|
|---|
| 149 | - for (psz = pszOrgName, uHash = 5381; *psz; psz++) /* hash alg: original djb2. */
|
|---|
| 150 | - uHash += (uHash << 5) + *psz;
|
|---|
| 151 | -
|
|---|
| 152 | - cch2 = sprintf(szHash, "!_%X", 0x7fffffff & uHash);
|
|---|
| 153 | - memcpy(pachName, pszOrgName, cch > 255 ? 255 : cch);
|
|---|
| 154 | - memcpy(&pachName[255 - cch3 - cch2], szHash, cch2);
|
|---|
| 155 | - memcpy(&pachName[255 - cch3], weak_marker_ts, cch3);
|
|---|
| 156 | - pachName[255] = '\0';
|
|---|
| 157 | - warning ("Symbol length truncated to 255 characters (from %d) for `%s'", cch, pszOrgName);
|
|---|
| 158 | +
|
|---|
| 159 | + memcpy(pachName, pszOrgName, MAX_SYMBOL_LEN);
|
|---|
| 160 | + sprintf( pachName+MAX_SYMBOL_LEN, "!_%08X", hash_string( pszOrgName));
|
|---|
| 161 | + strcat( pachName, weak_marker_simple);
|
|---|
| 162 | + warning ("Symbol length truncated to 255 characters");
|
|---|
| 163 | + warning ("from %d `%s'", cch, pszOrgName);
|
|---|
| 164 | + warning (" to %d `%s'", strlen(pachName), pachName);
|
|---|
| 165 | }
|
|---|
| 166 |
|
|---|
| 167 | return pachName;
|
|---|