source: trunk/src/win32k/libconv.c@ 5120

Last change on this file since 5120 was 4164, checked in by bird, 25 years ago

Merged in the Grace branch. New Win32k!

File size: 11.2 KB
Line 
1/* $Id: libconv.c,v 1.3 2000-09-02 21:07:53 bird Exp $
2 *
3 * Very simple OMF/LIB dumper.
4 *
5 * Copyright (c) 1999 knut st. osmundsen
6 *
7 * Project Odin Software License can be found in LICENSE.TXT
8 *
9 */
10
11
12/*@Header***********************************************************************
13* Header Files *
14*******************************************************************************/
15#include <stdio.h>
16#include <string.h>
17#include <malloc.h>
18
19
20#include "include\omf.h"
21
22int fCodeToCode16 = 0;
23int fRemoveExtra = 0;
24
25/*@IntFunc**********************************************************************
26* Internal Functions *
27*******************************************************************************/
28int processFile(const char *pszFilename, const char *pszFilenameOut);
29void *processRecord(void *pvRecord, void *pvBase, FILE *phNew, unsigned short *ausTrans);
30
31
32
33int main(int argc, char **argv)
34{
35 int rc = 0;
36 int argi = 1;
37
38 if (argc == 4)
39 {
40 argi = 2;
41 fRemoveExtra = 1;
42 }
43 if (argc != 3)
44 printf("syntax error - requires two filename, in.lib and out.lib\n");
45
46 rc = processFile(argv[argi], argv[argi+1]);
47
48 return rc;
49}
50
51
52
53
54int processFile(const char *pszFilename, const char *pszFilenameOut)
55{
56 FILE *phFile;
57 FILE *phNew;
58 char *psz;
59 int rc = 0;
60
61 psz = strrchr(pszFilename, '\\');
62 if (psz)
63 fCodeToCode16 = stricmp(psz, "\\dhcalls.lib") == 0;
64
65 phFile = fopen(pszFilename, "rb");
66 phNew = fopen(pszFilenameOut, "wb");
67 if (phFile != NULL && phNew != NULL)
68 {
69 int cbFile;
70
71 /* get size of file */
72 if (!fseek(phFile, 0, SEEK_END)
73 && (cbFile = ftell(phFile) ) != -1
74 && !fseek(phFile, 0, SEEK_SET)
75 )
76 {
77 void *pvFile;
78
79 /* allocater memory */
80 pvFile = malloc(cbFile);
81 if (pvFile != NULL)
82 {
83 /* read the whole file */
84 if (fread(pvFile, cbFile, 1, phFile) == 1)
85 {
86 unsigned short * ausTrans = calloc(sizeof(unsigned short), cbFile / 16 ); /* Assumes page size of 16 FIXME! */
87 void *pvNew = pvFile;
88
89
90 /* main loop */
91 while (pvNew < (void*)(cbFile + (int)pvFile))
92 pvNew = processRecord(pvNew, pvFile, phNew, ausTrans);
93 }
94 else
95 rc = 4;
96 }
97 else
98 rc = 3;
99 }
100 else
101 rc = 2;
102 fclose(phFile);
103 fclose(phNew);
104 }
105 else
106 rc = 1;
107
108 return rc;
109}
110
111
112
113void *processRecord(void *pvRecord, void *pvBase, FILE *phNew, unsigned short *ausTrans)
114{
115 static char *apszLNames[256];
116 static int cpszLNames = 0;
117 static int iCode16 = 0;
118 static int cbPage = 16; /* fixme todo TODO FIXME ASSUMES: pagesize = 16 */
119 void *pvRet = pvRecord;
120 int cbRecord;
121 int i;
122 int fChanged = 0;
123
124 switch (*(unsigned char*)pvRecord)
125 {
126 case LIBHDR:
127 if (*(unsigned short*)((int)pvRecord+1) < 6)
128 fprintf(stderr, "error: not supported LIBHDR\n");
129 cbRecord = *((unsigned short*)((int)pvRecord+1)) + 3;
130 break;
131
132 case THEADR:
133 /* Add entry to the translation table - used to translate block numbers in the dictionary */
134 ausTrans[((char*)pvRecord - (char*)pvBase) / cbPage] = (unsigned short)(ftell(phNew) / cbPage);
135 cbRecord = *((unsigned short*)((int)pvRecord+1)) + 3;
136 break;
137
138 case SEGDEF: /* 16-bit segdef */
139 cbRecord = *((unsigned short*)((int)pvRecord+1)) + 3;
140 *((char*)pvRecord + 9) = 0;
141 i = *(char*)((int)pvRecord + 6);
142 if (cbRecord == 10 && i <= cpszLNames && strcmp(apszLNames[i-1], "CODE") == 0)
143 {
144 *(char*)((int)pvRecord + 6) = iCode16+1;
145 }
146 i = *(char*)((int)pvRecord + 6);
147 if (cbRecord == 10 && (*((char *)pvRecord + 3) & 0xE0) == 0x20 && i <= cpszLNames && strcmp(apszLNames[i-1], "CODE16_IOSEG") == 0)
148 { /* change alignment of this segment... */
149 /* fprintf(stderr, "debug %s 0x%02x\n", apszLNames[*(char*)((int)pvRecord + 6) - 1], (*((char *)pvRecord + 3) & 0xFF)); */
150 *((char*)pvRecord + 3) = 0x40 | (*((char*)pvRecord + 3) & 0x1F);
151 }
152 break;
153
154 case MODEND:
155 case MODEND2:
156 {
157 unsigned long ul = (unsigned long)pvRecord - (unsigned long)pvBase;
158
159 cbRecord = *((unsigned short*)((int)pvRecord+1)) + 3;
160 /* it seems to be somthing funny here! - lets try aligning it to on a 16 bytes boundrary... */
161 /* PS. I know this I have a wrong approch to the lib files, not using the directory... */
162 /* Aug 13 2000 4:24am: The alignment of modules are found in the library header.
163 * It's the size of the library header.
164 * Not implemented yet. TODO FIXME BUGBUG ASSUMES
165 */
166 fChanged = 1;
167 fwrite(pvRecord, 1, cbRecord, phNew);
168 ul += cbRecord;
169 if (*((unsigned char*)((int)pvRecord+cbRecord)) == 0x00)
170 {
171 if ((ul % cbPage) > 0)
172 cbRecord += cbPage - (ul % cbPage);
173 }
174 /*if (*((unsigned char*)pvRecord + cbRecord) != LIBEND)*/
175 {
176 ul = ftell(phNew);
177 while (ul++ % cbPage != 0)
178 fputc(0, phNew);
179 }
180 while (cpszLNames-- > 0)
181 free(apszLNames[cpszLNames]);
182 } break;
183
184 case PUBDEF:
185 {
186 cbRecord = *((unsigned short*)((int)pvRecord+1)) + 3;
187 *((char*)pvRecord + cbRecord - 1) = 0;
188 break;
189 }
190
191 case LNAMES:
192 {
193 char *apszConv[] =
194 {
195 /* classes */
196 "CODE", "CODE",
197 "IOSEG_CODE", "CODE",
198 "DATA", "FAR_DATA",
199 "BSS", "DATA16BSS",
200 "CONST", "DATA16CONST",
201 /* segment names */
202 "_TEXT", "CODE16",
203 "_IOSEG", "CODE16_IOSEG",
204 "_CODE", "CODE16", /* dhcalls */
205 "_DATA", "DATA16",
206 "_BSS", "DATA16BSS",
207 "_CONST", "DATA16CONST",
208 /* groups */
209 "DGROUP", "DATA16_GROUP",
210 NULL, NULL
211 };
212
213 int cb;
214 int cbNew; /* record size */
215 char *psz;
216 iCode16 = -1;
217
218 cpszLNames = 0;
219 cbRecord = *((unsigned short*)((int)pvRecord+1)) + 3;
220 cb = 3;
221 cbNew = 1;
222 psz = (char*)pvRecord + 3;
223 while (cb < cbRecord-1)
224 {
225 int j = 0;
226 char szName[256];
227
228 strncpy(szName, psz+1, *psz);
229 szName[*psz] = '\0';
230
231 while (apszConv[j] != NULL && stricmp(szName, apszConv[j]) != 0)
232 j += 2;
233
234 if (apszConv[j] == NULL)
235 {
236 cbNew += *psz + 1;
237 if (*psz != 0)
238 printf("LNAMES: %.*s was not converted\n", *psz, psz+1);
239 apszLNames[cpszLNames++] = strdup(&szName[0]);
240 }
241 else
242 {
243 cbNew += strlen(apszConv[j+1]) + 1;
244 if (strcmp(apszConv[j+1], "CODE16") == 0)
245 iCode16 = cpszLNames;
246 apszLNames[cpszLNames++] = strdup(apszConv[j+1]);
247 }
248 cb += *psz + 1;
249 psz += 1 + *psz;
250 }
251
252 if (iCode16 == -1)
253 {
254 iCode16 = cpszLNames;
255 apszLNames[cpszLNames++] = strdup("CODE16");
256 cbNew += 1 + 6;
257 }
258
259 fChanged = 1;
260 fputc(LNAMES, phNew);
261 fwrite(&cbNew, 1, 2, phNew);
262
263 for (i = 0; i < cpszLNames; i++)
264 {
265 fputc(strlen(apszLNames[i]), phNew);
266 fwrite(apszLNames[i], 1, strlen(apszLNames[i]), phNew);
267 }
268
269 fputc(0, phNew);
270 break;
271 }
272
273 case LIBEND:
274 {
275 /* align dictionary at 512 byte (3 is min size of this record) */
276 int cBlocks;
277 unsigned short int cbSize = (((ftell(phNew) + 3 + 0x1ff) & ~0x1ff) - ftell(phNew)) - 3;
278 unsigned long int offDict = ftell(phNew) + cbSize + 3;
279 cbRecord = cbSize + 3;
280 fwrite(pvRecord, 1, 1, phNew);
281 fwrite(&cbSize, 1, sizeof(cbSize), phNew);
282 while (cbSize-- > 0)
283 fwrite("\0", 1, 1, phNew);
284
285 /* update header record. */
286 fseek(phNew, 3, SEEK_SET);
287 fwrite(&offDict, 1, sizeof(offDict), phNew);
288 fseek(phNew, offDict, SEEK_SET);
289
290 /* Translate the dictionary */
291 pvRecord = (void*)((char*)pvRecord + *(unsigned short*)((char*)pvRecord + 1) + 3);
292 cBlocks = *(unsigned short *)((char*)pvBase + 7);
293 for (i = 0; i < cBlocks; i++)
294 {
295 int j;
296 char *pchBlock = (char*)pvRecord + i * 512;
297 for (j = 0; j < 37; j++)
298 {
299 if (pchBlock[j] > 19 && pchBlock[j] < 0xff)
300 {
301 unsigned short *pusBlock = (unsigned short*)&pchBlock[pchBlock[j] * 2];
302 pusBlock = (unsigned short *) ((char*)pusBlock + *(char*)pusBlock + 1);
303 if (ausTrans[*pusBlock] == 0)
304 fprintf(stderr, "error: dictionary entry don't point to a THEADR page!\n");
305 else
306 *pusBlock = ausTrans[*pusBlock];
307 }
308 }
309
310 }
311
312 /* Write the dictionary */
313 fwrite(pvRecord, 512, cBlocks, phNew);
314 return (void*)0xffffffff; /* FINE */
315 }
316
317 case COMENT:
318 {
319 cbRecord = *((unsigned short*)((int)pvRecord+1)) + 3;
320 switch (*((unsigned char*)((int)pvRecord+4)))
321 {
322 /* remove "Link Pass Separator" */
323 case 0xA2:
324 /* remove "LIBMOD" - The VAC 3.6.5 Linker don't like these! */
325 case 0xA3:
326 fChanged = fRemoveExtra;
327 break;
328 }
329 break;
330 }
331
332 /*
333 * Remove checksum
334 */
335 /*
336 case GRPDEF:
337 case FIXUPP:
338 case FIXUPP2:
339 case LEDATA:
340 {
341 cbRecord = *((unsigned short*)((int)pvRecord+1)) + 3;
342 *((char*)pvRecord + cbRecord - 1) = 0;
343 break;
344 }
345 */
346
347 default:
348 cbRecord = *((unsigned short*)((int)pvRecord+1)) + 3;
349 break;
350 }
351
352 if (!fChanged)
353 fwrite(pvRet, 1, cbRecord, phNew);
354
355
356 return (void*)((int)pvRet + cbRecord);
357}
358
359
Note: See TracBrowser for help on using the repository browser.