source: trunk/tools/dbginfo/dbgLXDumper.c@ 3237

Last change on this file since 3237 was 3236, checked in by bird, 26 years ago

Backup checkin.

File size: 14.5 KB
Line 
1/* $Id: dbgLXDumper.c,v 1.2 2000-03-25 21:09:58 bird Exp $
2 *
3 * dbgLXDumper - reads and interprets the debuginfo found in an LX executable.
4 *
5 * Copyright (c) 2000 knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
6 *
7 * Project Odin Software License can be found in LICENSE.TXT
8 *
9 */
10
11/*******************************************************************************
12* Defined Constants And Macros *
13*******************************************************************************/
14#define INCL_TYPES
15#define INCL_DOSERRORS
16#define FOR_EXEHDR 1 /* exe386.h flag */
17#define DWORD ULONG /* Used by exe386.h / newexe.h */
18#define WORD USHORT /* Used by exe386.h / newexe.h */
19
20/*******************************************************************************
21* Header Files *
22*******************************************************************************/
23#include <os2.h>
24#include <newexe.h>
25#include <exe386.h>
26
27#include <malloc.h>
28#include <string.h>
29#include <stdio.h>
30#include <stddef.h>
31#include <ctype.h>
32
33#include "hll.h"
34
35
36
37/*******************************************************************************
38* Internal Functions *
39*******************************************************************************/
40int dbgLXDump(void *pvFile);
41int dumpHLL(FILE *phOut, PBYTE pb, int cb);
42void dumpHex(FILE *phOut, PBYTE pb, int cb);
43void * readfile(const char *pszFilename);
44signed long fsize(FILE *phFile);
45
46
47
48/*******************************************************************************
49* Global Variables *
50*******************************************************************************/
51static char achBufferDummy64[0x10000] = {0};
52char achBufferDummy128[0x20000] = {0};
53
54int main(int argc, char **argv)
55{
56 void * pvFile;
57
58 if (argc != 2)
59 {
60 fprintf(stderr, "error parameters!\n");
61 return -1;
62 }
63
64 pvFile = readfile(argv[1]);
65 if (pvFile == NULL)
66 {
67 fprintf(stderr, "error reading file %s\n", argv[1]);
68 return -2;
69 }
70
71 return dbgLXDump(pvFile);
72}
73
74
75
76/**
77 * Dumps the internals of LX dubug info.
78 * @returns error code. (0 is ok)
79 * @param pvFile Pointer to filemapping.
80 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
81 */
82int dbgLXDump(void *pvFile)
83{
84 struct exe_hdr * pehdr = (struct exe_hdr *) pvFile;
85 struct e32_exe * pe32;
86 unsigned offe32;
87 PBYTE pbFile = (PBYTE)pvFile;
88
89 /*
90 * Find LX header.
91 */
92 if (pehdr->e_magic == EMAGIC)
93 offe32 = pehdr->e_lfanew;
94 else
95 offe32 = 0;
96 pe32 = (struct e32_exe *)((unsigned)pvFile + offe32);
97 if (pe32->e32_magic[0] != E32MAGIC1 || pe32->e32_magic[1] != E32MAGIC2)
98 {
99 fprintf(stderr, "not LX executable\n");
100 return ERROR_INVALID_EXE_SIGNATURE;
101 }
102
103 /*
104 * Check if there is any debuginfo in this executable.
105 */
106 printf("e32_debuginfo 0x%08x (%d)\n"
107 "e32_debuglen 0x%08x (%d)\n",
108 pe32->e32_debuginfo, pe32->e32_debuglen);
109
110 if (pe32->e32_debuginfo != 0 && pe32->e32_debuglen > 0)
111 {
112 PBYTE pbDbg = pbFile + pe32->e32_debuginfo;
113 /*
114 * Check signature. 'NB0'
115 */
116 printf("Debug signature: %c%c%c%c\n",
117 pbDbg[0], pbDbg[1], pbDbg[2], pbDbg[3]);
118 if (pbDbg[0] == 'N' && pbDbg[1] == 'B' && pbDbg[2] == '0')
119 {
120 int i;
121
122 /*
123 * Switch on debug datatype.
124 */
125 switch (pbDbg[3])
126 {
127 case '0':
128 printf("Found 32-bit Codeview format\n");
129 break;
130
131 case '1':
132 printf("Found AIX Debugger format - unsupported\n");
133 break;
134
135 case '2':
136 printf("Found 16-bit Codeview format\n");
137 break;
138
139 case '4':
140 printf("Found 32-bit OS/2 PM Debugger format (HLL)\n");
141 return dumpHLL(stdout, pbDbg, pe32->e32_debuglen);
142
143 default:
144 printf("Invalid debug type, %c (%d)\n", pbDbg[3], pbDbg[3]);
145 return ERROR_INVALID_DATA;
146 }
147
148 /*
149 * Dump debug data
150 */
151 printf("\ndumps debug data\n");
152 dumpHex(stdout, pbDbg + 4, pe32->e32_debuglen - 4);
153 }
154 else
155 {
156 printf("Invalid debug signature\n");
157 return ERROR_INVALID_DATA;
158 }
159 }
160 else
161 printf(" - no debug info -\n");
162
163 return NO_ERROR;
164}
165
166
167/**
168 * Dumps binary data to file handle.
169 * @param phOut Output file handle.
170 * @param pb Pointer to debug data. (Starts with signature ('NB04').)
171 * @param cb Size of debug data.
172 *
173 * HLL:
174 * Starts with a 4 byte word with the offset (from start of HLL data) to
175 * the number of entries. (what entries is yet to come)
176 *
177 *
178 */
179int dumpHLL(FILE *phOut, PBYTE pb, int cb)
180{
181 PHLLDIR pDir;
182 int i;
183 PHLLHDR pHdr = (PHLLHDR)pb;
184
185 /*
186 * Dump header.
187 */
188 fprintf(phOut,
189 "- HLL header -\n"
190 " Signature %.4s\n"
191 " Directory offset 0x%08x (%d)\n"
192 " reserved 0x%08x (%d)\n"
193 "\n",
194 pHdr->achSignature,
195 pHdr->offDirectory,
196 pHdr->offDirectory,
197 pHdr->ulReserved,
198 pHdr->ulReserved);
199
200
201 /*
202 * Get and Dump directory
203 */
204 if (pHdr->offDirectory + sizeof(HLLDIR) >= cb)
205 {
206 fprintf(phOut, "error: offcEntries is incorrect!\n");
207 return ERROR_INVALID_DATA;
208 }
209 pDir = (PHLLDIR)(pb + pHdr->offDirectory);
210 fprintf(phOut,
211 "- HLL Directory -\n"
212 " Reserved 0x%08x (%d)\n"
213 " Number of entries 0x%08x (%d)\n",
214 pDir->ulReserved,
215 pDir->ulReserved,
216 pDir->cEntries,
217 pDir->cEntries);
218
219
220 /*
221 * Directory sanity check - check that it's not too big
222 */
223 if ((PBYTE)&pDir->aEntries[pDir->cEntries] - pb >= cb)
224 {
225 fprintf(phOut, "Error: Directory is to big!\n");
226 return ERROR_INVALID_DATA;
227 }
228
229
230
231 /*
232 * Loop thru the directory.
233 */
234 for (i = 0; i < pDir->cEntries; i++)
235 {
236 /*
237 * Directory entry type descriptions.
238 */
239 static const char * apsz[] =
240 {
241 "HLL_DE_MODULES",
242 "HLL_DE_PUBLICS",
243 "HLL_DE_TYPES",
244 "HLL_DE_SYMBOLS",
245 "HLL_DE_SRCLINES",
246 "HLL_DE_LIBRARIES",
247 "unknown",
248 "unknown",
249 "HLL_DE_SRCLNSEG",
250 "unknown",
251 "HLL_DE_IBMSRC"
252 };
253 const char *pszType = pDir->aEntries[i].usType >= HLL_DE_MODULES
254 && pDir->aEntries[i].usType <= HLL_DE_IBMSRC
255 ? apsz[pDir->aEntries[i].usType - HLL_DE_MODULES]
256 : "unknown";
257
258 /*
259 * Dump directroy info.
260 */
261 fprintf(phOut, "\n"
262 "- HLL Directory Entry %d (0x%x): -\n", i, i);
263 fprintf(phOut, " usType 0x%08x (%d) %s\n"
264 " iMod 0x%08x (%d)\n"
265 " off 0x%08x (%d)\n"
266 " cb 0x%08x (%d)\n",
267 pDir->aEntries[i].usType,
268 pDir->aEntries[i].usType,
269 pszType,
270 pDir->aEntries[i].iMod,
271 pDir->aEntries[i].iMod,
272 pDir->aEntries[i].off,
273 pDir->aEntries[i].off,
274 pDir->aEntries[i].cb,
275 pDir->aEntries[i].cb
276 );
277
278
279
280 /*
281 * Switch between the different entry types to do individual
282 * processing.
283 */
284 switch (pDir->aEntries[i].usType)
285 {
286 /*
287 * Module - debuginfo on an object/source module.
288 */
289 case HLL_DE_MODULES:
290 {
291 PHLLMODULE pModule = (PHLLMODULE)(pDir->aEntries[i].off + pb);
292 PHLLOBJECT paObjects;
293 int j, c;
294
295 /*
296 * Dump module entry data.
297 */
298 fprintf(phOut,
299 " Modulename: %.*s\n"
300 " overlay %d\n"
301 " ilib %d\n"
302 " pad %d\n"
303 " usDebugStyle %#04x %c%c\n"
304 " HLL Version %d.%d\n"
305 " cchName %d\n"
306 ,
307 pModule->cchName,
308 &pModule->achName[0],
309 pModule->overlay,
310 pModule->iLib,
311 pModule->pad,
312 pModule->usDebugStyle,
313 pModule->usDebugStyle & 0xFF,
314 pModule->usDebugStyle >> 8,
315 pModule->chVerMajor,
316 pModule->chVerMinor,
317 pModule->cchName
318 );
319
320
321 /*
322 * Dump object data
323 */
324 fprintf(phOut,
325 " Object %d\n"
326 " iObj %#x\n"
327 " off %#x\n"
328 " cb %#x\n",
329 0,
330 pModule->Object.iObj,
331 pModule->Object.off,
332 pModule->Object.cb);
333
334 c = pModule->cObjects > 0 ? pModule->cObjects : 0;
335 paObjects = (PHLLOBJECT)((void*)&pModule->achName[pModule->cchName]);
336 for (j = 0; j < c; j++)
337 {
338 fprintf(phOut,
339 " Object %d\n"
340 " iObj %#x\n"
341 " off %#x\n"
342 " cb %#x\n",
343 j + 1,
344 paObjects[j].iObj,
345 paObjects[j].off,
346 paObjects[j].cb);
347 }
348 break;
349 }
350
351
352 case HLL_DE_PUBLICS: /* Public symbols */
353 {
354 PHLLPUBLICSYM pPubSym = (PHLLPUBLICSYM)(pDir->aEntries[i].off + pb);
355
356 while ((char *)pPubSym - pb - pDir->aEntries[i].off < pDir->aEntries[i].cb)
357 {
358 fprintf(phOut,
359 " %#03x:%#08x iType=%#2x name=%.*s\n",
360 pPubSym->iObj,
361 pPubSym->off,
362 pPubSym->iType,
363 pPubSym->cchName,
364 pPubSym->achName);
365
366 /* next */
367 pPubSym = (PHLLPUBLICSYM)&pPubSym->achName[pPubSym->cchName];
368 }
369 break;
370 }
371
372
373 case HLL_DE_TYPES: /* Types */
374 break;
375
376 case HLL_DE_SYMBOLS: /* Symbols */
377 break;
378
379 case HLL_DE_LIBRARIES: /* Libraries */
380 break;
381
382 case HLL_DE_SRCLINES: /* Line numbers - (IBM C/2 1.1) */
383 break;
384
385 case HLL_DE_SRCLNSEG: /* Line numbers - (MSC 6.00) */
386 break;
387
388 case HLL_DE_IBMSRC: /* Line numbers - (IBM HLL) */
389 break;
390
391 default:
392 fprintf(phOut, " Error - unknown entry type. (%x)\n", pDir->aEntries[i].usType);
393 }
394
395 }
396
397
398 /* - temporary - */
399 printf("\ndumps debug data\n");
400 dumpHex(stdout, pb, cb);
401
402 return NO_ERROR;
403}
404
405
406
407/**
408 * Dumps binary data to file handle.
409 * @param phOut Output file handle.
410 * @param pb Pointer to data.
411 * @param cb Count of bytes to dump.
412 */
413void dumpHex(FILE *phOut, PBYTE pb, int cb)
414{
415 int i;
416
417 for (i = 0; i < cb; i += 16)
418 {
419 int j;
420 /* write offset */
421 fprintf(phOut, "%08x ", i);
422
423 /* write data (hex value) */
424 for (j = 0; j < 16; j++)
425 {
426 int f = i + j < cb;
427 unsigned char uch = f ? pb[i + j] : 0;
428 if (j == 3 || j == 11)
429 fprintf(phOut, f ? "%02x-" : " -", uch);
430 else if (j == 7)
431 fprintf(phOut, f ? "%02x - " : " - ", uch);
432 else
433 fprintf(phOut, f ? "%02x " : " ", uch);
434 }
435 fprintf(phOut, " ");
436
437 /* write ASCII */
438 for (j = 0; j < 16; j++)
439 {
440 if (i + j < cb)
441 {
442 if (isprint(pb[i + j]))
443 fprintf(phOut, "%c", pb[i + j]);
444 else
445 fprintf(phOut, ".");
446 }
447 else
448 fprintf(phOut, " ");
449 }
450 fprintf(phOut, "\n");
451 }
452}
453
454
455
456/**
457 * Creates a memory buffer for a binary file.
458 * @returns Pointer to file memoryblock. NULL on error.
459 * @param pszFilename Pointer to filename string.
460 * @remark This function is the one using most of the execution
461 * time (DosRead + DosOpen) - about 70% of the execution time!
462 */
463void *readfile(const char *pszFilename)
464{
465 void *pvFile = NULL;
466 FILE *phFile;
467
468 phFile = fopen(pszFilename, "rb");
469 if (phFile != NULL)
470 {
471 signed long cbFile = fsize(phFile);
472 if (cbFile > 0)
473 {
474 pvFile = malloc(cbFile + 1);
475 if (pvFile != NULL)
476 {
477 memset(pvFile, 0, cbFile + 1);
478 if (fread(pvFile, 1, cbFile, phFile) == 0)
479 { /* failed! */
480 free(pvFile);
481 pvFile = NULL;
482 }
483 }
484 else
485 fprintf(stderr, "warning/error: failed to open file %s\n", pszFilename);
486 }
487 fclose(phFile);
488 }
489 return pvFile;
490}
491
492
493
494/**
495 * Find the size of a file.
496 * @returns Size of file. -1 on error.
497 * @param phFile File handle.
498 */
499signed long fsize(FILE *phFile)
500{
501 int ipos;
502 signed long cb;
503
504 if ((ipos = ftell(phFile)) < 0
505 ||
506 fseek(phFile, 0, SEEK_END) != 0
507 ||
508 (cb = ftell(phFile)) < 0
509 ||
510 fseek(phFile, ipos, SEEK_SET) != 0
511 )
512 cb = -1;
513 return cb;
514}
515
Note: See TracBrowser for help on using the repository browser.