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

Last change on this file since 3231 was 3222, checked in by bird, 26 years ago

Temporary checkin.

File size: 9.9 KB
Line 
1/* $Id: dbgLXDumper.c,v 1.1 2000-03-24 18:13:44 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
18#define WORD USHORT
19
20/*******************************************************************************
21* Header Files *
22*******************************************************************************/
23#include <os2.h>
24#include <newexe.h>
25#include <exe386.h>
26#include <string.h>
27#include <stdio.h>
28#include <malloc.h>
29#include <ctype.h>
30
31#include "hll.h"
32
33
34
35/*******************************************************************************
36* Internal Functions *
37*******************************************************************************/
38static int dbgLXDump(void *pvFile);
39static int dumpHLL(FILE *phOut, PBYTE pb, int cb);
40static void dumpHex(FILE *phOut, PBYTE pb, int cb);
41static void * readfile(const char *pszFilename);
42static signed long fsize(FILE *phFile);
43
44
45
46
47
48int main(int argc, char **argv)
49{
50 void * pvFile;
51
52 if (argc != 2)
53 {
54 fprintf(stderr, "error parameters!\n");
55 return -1;
56 }
57
58 pvFile = readfile(argv[1]);
59 if (pvFile == NULL)
60 {
61 fprintf(stderr, "error reading file %s\n", argv[1]);
62 return -2;
63 }
64
65 return dbgLXDump(pvFile);
66}
67
68
69
70/**
71 * Dumps the internals of LX dubug info.
72 * @returns error code. (0 is ok)
73 * @param pvFile Pointer to filemapping.
74 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
75 */
76static int dbgLXDump(void *pvFile)
77{
78 struct exe_hdr * pehdr = (struct exe_hdr *) pvFile;
79 struct e32_exe * pe32;
80 unsigned offe32;
81 PBYTE pbFile = (PBYTE)pvFile;
82
83 /*
84 * Find LX header.
85 */
86 if (pehdr->e_magic == EMAGIC)
87 offe32 = pehdr->e_lfanew;
88 else
89 offe32 = 0;
90 pe32 = (struct e32_exe *)((unsigned)pvFile + offe32);
91 if (pe32->e32_magic[0] != E32MAGIC1 || pe32->e32_magic[1] != E32MAGIC2)
92 {
93 fprintf(stderr, "not LX executable\n");
94 return ERROR_INVALID_EXE_SIGNATURE;
95 }
96
97 /*
98 * Check if there is any debuginfo in this executable.
99 */
100 printf("e32_debuginfo 0x%08x (%d)\n"
101 "e32_debuglen 0x%08x (%d)\n",
102 pe32->e32_debuginfo, pe32->e32_debuglen);
103
104 if (pe32->e32_debuginfo != 0 && pe32->e32_debuglen > 0)
105 {
106 PBYTE pbDbg = pbFile + pe32->e32_debuginfo;
107 /*
108 * Check signature. 'NB0'
109 */
110 printf("Debug signature: %c%c%c%c\n",
111 pbDbg[0], pbDbg[1], pbDbg[2], pbDbg[3]);
112 if (pbDbg[0] == 'N' && pbDbg[1] == 'B' && pbDbg[2] == '0')
113 {
114 int i;
115
116 /*
117 * Switch on debug datatype.
118 */
119 switch (pbDbg[3])
120 {
121 case '0':
122 printf("Found 32-bit Codeview format\n");
123 break;
124
125 case '1':
126 printf("Found AIX Debugger format - unsupported\n");
127 break;
128
129 case '2':
130 printf("Found 16-bit Codeview format\n");
131 break;
132
133 case '4':
134 printf("Found 32-bit OS/2 PM Debugger format (HLL)\n");
135 return dumpHLL(stdout, pbDbg + 4, pe32->e32_debuglen - 4);
136
137 default:
138 printf("Invalid debug type, %c (%d)\n", pbDbg[3], pbDbg[3]);
139 return ERROR_INVALID_DATA;
140 }
141
142 /*
143 * Dump debug data
144 */
145 printf("\ndumps debug data\n");
146 dumpHex(stdout, pbDbg + 4, pe32->e32_debuglen - 4);
147 }
148 else
149 {
150 printf("Invalid debug signature\n");
151 return ERROR_INVALID_DATA;
152 }
153 }
154 else
155 printf(" - no debug info -\n");
156
157 return NO_ERROR;
158}
159
160
161/**
162 * Dumps binary data to file handle.
163 * @param phOut Output file handle.
164 * @param pb Pointer to debug data.
165 * @param cb Size of debug data.
166 *
167 * HLL:
168 * Starts with a 4 byte word with the offset (from start of HLL data) to
169 * the number of entries. (what entries is yet to come)
170 *
171 *
172 */
173static int dumpHLL(FILE *phOut, PBYTE pb, int cb)
174{
175 PHLLDIR pDir;
176 ULONG offDir;
177 int i;
178
179 /*
180 * Get number of entries.
181 */
182 offDir = *(PULONG)pb;
183 if (offDir + 4 >= cb)
184 {
185 fprintf(phOut, "error: offcEntries is incorrect!\n");
186 return ERROR_INVALID_DATA;
187 }
188 pDir = (PHLLDIR)(pb + offDir);
189 fprintf(phOut, "Directory offset=0x%08x cEntries=%d(0x%x)\n",
190 offDir, pDir->cEntries, pDir->cEntries);
191
192
193 /*
194 * Directory sanity check.
195 */
196 if ((PBYTE)&pDir->aEntries[pDir->cEntries] - pb >= cb)
197 {
198 fprintf(phOut, "Error: Directory is to big!\n");
199 return ERROR_INVALID_DATA;
200 }
201
202
203
204 /*
205 * Loop thru the directory.
206 */
207 for (i = 0; i < pDir->cEntries; i++)
208 {
209 fprintf(phOut, "Directory Entry %d (0x%x):\n", i, i);
210 fprintf(phOut, " usType 0x%08x (%d)\n"
211 " iMod 0x%08x (%d)\n"
212 " off 0x%08x (%d)\n"
213 " cb 0x%08x (%d)\n",
214 pDir->aEntries[i].usType,
215 pDir->aEntries[i].usType,
216 pDir->aEntries[i].iMod,
217 pDir->aEntries[i].iMod,
218 pDir->aEntries[i].off,
219 pDir->aEntries[i].off,
220 pDir->aEntries[i].cb,
221 pDir->aEntries[i].cb
222 );
223
224 switch (pDir->aEntries[i].usType)
225 {
226 case HLL_DE_MODULES: /* Filename */
227 printf(" Modulename: %*.s\n",
228 pDir->aEntries[i].cb,
229 pDir->aEntries[i].off + pb);
230 dumpHex(phOut, pDir->aEntries[i].off + pb, pDir->aEntries[i].cb);
231 break;
232
233 case HLL_DE_PUBLICS: /* Public symbols */
234 break;
235
236 case HLL_DE_TYPES: /* Types */
237 break;
238
239 case HLL_DE_SYMBOLS: /* Symbols */
240 break;
241
242 case HLL_DE_LIBRARIES: /* Libraries */
243 break;
244
245 case HLL_DE_SRCLINES: /* Line numbers - (IBM C/2 1.1) */
246 break;
247
248 case HLL_DE_SRCLNSEG: /* Line numbers - (MSC 6.00) */
249 break;
250
251 case HLL_DE_IBMSRC: /* Line numbers - (IBM HLL) */
252 break;
253
254 default:
255 fprintf(phOut, " Error - unknown entry type. (%x)\n", pDir->aEntries[i].usType);
256 }
257
258 }
259
260
261 /* - temporary - */
262 printf("\ndumps debug data\n");
263 dumpHex(stdout, pb, cb);
264
265 return NO_ERROR;
266}
267
268
269
270/**
271 * Dumps binary data to file handle.
272 * @param phOut Output file handle.
273 * @param pb Pointer to data.
274 * @param cb Count of bytes to dump.
275 */
276static void dumpHex(FILE *phOut, PBYTE pb, int cb)
277{
278 int i;
279
280 for (i = 0; i < cb; i += 16)
281 {
282 int j;
283 /* write offset */
284 fprintf(phOut, "%08x ", i);
285
286 /* write data (hex value) */
287 for (j = 0; j < 16; j++)
288 {
289 int f = i + j < cb;
290 unsigned char uch = f ? pb[i + j] : 0;
291 if (j == 3 || j == 11)
292 fprintf(phOut, f ? "%02x-" : " -", uch);
293 else if (j == 7)
294 fprintf(phOut, f ? "%02x - " : " - ", uch);
295 else
296 fprintf(phOut, f ? "%02x " : " ", uch);
297 }
298 fprintf(phOut, " ");
299
300 /* write ASCII */
301 for (j = 0; j < 16; j++)
302 {
303 if (i + j < cb)
304 {
305 if (isprint(pb[i + j]))
306 fprintf(phOut, "%c", pb[i + j]);
307 else
308 fprintf(phOut, ".");
309 }
310 else
311 fprintf(phOut, " ");
312 }
313 fprintf(phOut, "\n");
314 }
315}
316
317
318
319/**
320 * Creates a memory buffer for a binary file.
321 * @returns Pointer to file memoryblock. NULL on error.
322 * @param pszFilename Pointer to filename string.
323 * @remark This function is the one using most of the execution
324 * time (DosRead + DosOpen) - about 70% of the execution time!
325 */
326static void *readfile(const char *pszFilename)
327{
328 void *pvFile = NULL;
329 FILE *phFile;
330
331 phFile = fopen(pszFilename, "rb");
332 if (phFile != NULL)
333 {
334 signed long cbFile = fsize(phFile);
335 if (cbFile > 0)
336 {
337 pvFile = malloc(cbFile + 1);
338 if (pvFile != NULL)
339 {
340 memset(pvFile, 0, cbFile + 1);
341 if (fread(pvFile, 1, cbFile, phFile) == 0)
342 { /* failed! */
343 free(pvFile);
344 pvFile = NULL;
345 }
346 }
347 else
348 fprintf(stderr, "warning/error: failed to open file %s\n", pszFilename);
349 }
350 fclose(phFile);
351 }
352 return pvFile;
353}
354
355
356
357/**
358 * Find the size of a file.
359 * @returns Size of file. -1 on error.
360 * @param phFile File handle.
361 */
362static signed long fsize(FILE *phFile)
363{
364 int ipos;
365 signed long cb;
366
367 if ((ipos = ftell(phFile)) < 0
368 ||
369 fseek(phFile, 0, SEEK_END) != 0
370 ||
371 (cb = ftell(phFile)) < 0
372 ||
373 fseek(phFile, ipos, SEEK_SET) != 0
374 )
375 cb = -1;
376 return cb;
377}
378
Note: See TracBrowser for help on using the repository browser.