Ticket #7: emxomf.txt

File emxomf.txt, 6.1 KB (added by Yuri Dario, 18 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;