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