Ticket #7: emxomf.txt2

File emxomf.txt2, 6.6 KB (added by Yuri Dario, 18 years ago)

Fix for EXTDEF recors, includes previous changes.

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/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;