Ticket #7: emxomf.txt

File emxomf.txt, 6.1 KB (added by Yuri Dario, 20 years ago)

(partial) rewrite of hashing and weak $w$ symbol processing.

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