source: trunk/tools/dbginfo/kHll.cpp@ 3614

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

Every object should be able to dump humanreadable state info to file.
LX Constructor, partially coded.

File size: 47.6 KB
Line 
1/* $Id: kHll.cpp,v 1.13 2000-05-27 02:15:41 bird Exp $
2 *
3 * kHll - Implementation of the class kHll.
4 * That class is used to create HLL debuginfo.
5 *
6 * Copyright (c) 2000 knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
7 *
8 * Project Odin Software License can be found in LICENSE.TXT
9 *
10 */
11
12
13/*******************************************************************************
14* Defined Constants And Macros *
15*******************************************************************************/
16#define INCL_TYPES
17#define INCL_DOSERRORS
18#define FOR_EXEHDR 1 /* exe386.h flag */
19#define DWORD ULONG /* Used by exe386.h / newexe.h */
20#define WORD USHORT /* Used by exe386.h / newexe.h */
21
22
23/*******************************************************************************
24* Internal Functions *
25*******************************************************************************/
26#include <os2.h>
27#include <newexe.h>
28#include <exe386.h>
29
30#include <malloc.h>
31#define free(a) memset(a, '7', _msize(a)) //overload free for debugging purposes.
32#define malloc(a) memset(malloc(a), '3', a) //overload free for debugging purposes.
33#include <stdio.h>
34#include <string.h>
35#include <stddef.h>
36#include <stdlib.h>
37#include <assert.h>
38
39#include <kList.h>
40#include <kFile.h>
41
42#include "hll.h"
43#include "kHll.h"
44
45
46/*******************************************************************************
47* Internal Functions *
48*******************************************************************************/
49signed long fsize(FILE *phFile);
50
51
52
53
54/*******************************************************************************
55* *
56* kHllBaseEntry *
57* *
58* kHllBaseEntry *
59* *
60*******************************************************************************/
61
62
63/**
64 * Writes a list to disk.
65 * @returns Number of bytes written.
66 * @returns Count of bytes written on success. (includes 0)
67 * -3 Invalid offsets.
68 * -2 Seek error.
69 * -1 Write error.
70 * @param phFile Output filehandle.
71 * @param pEntry Pointer to the start of the list which is to be written.
72 */
73int kHllBaseEntry::writeList(FILE *phFile, kHllBaseEntry *pEntry)
74{
75 int cch;
76 int cchWritten = 0;
77
78 /*
79 * Loop thru the list and write all the entries to disk.
80 */
81 while (pEntry != NULL)
82 {
83 cchWritten += cch = pEntry->write(phFile);
84 if (cch < 0)
85 return cch;
86 if (cch == 0)
87 return -1;
88 pEntry = (kHllBaseEntry*)pEntry->getNext();
89 }
90
91 return cchWritten;
92}
93
94
95
96/**
97 * Loops thru the given list and call the dump function for each
98 * node with the passed in parameters.
99 * @param ph Dump file handle.
100 * @param cchIndent Indent.
101 * @param pEntry Indent.
102 */
103void kHllBaseEntry::dumpList(FILE *ph, int cchIndent, kHllBaseEntry *pEntry)
104{
105 /*
106 * Loop thru the list staring at pEntry and call dump for each entry.
107 */
108 while (pEntry != NULL)
109 {
110 pEntry->dump(ph, cchIndent);
111 pEntry = (kHllBaseEntry*)pEntry->getNext();
112 }
113}
114
115
116
117
118
119
120/*******************************************************************************
121* *
122* kHllPubSymEntry *
123* *
124* kHllPubSymEntry *
125* *
126*******************************************************************************/
127
128
129
130
131
132/**
133 * Creates an HLL public symbol entry.
134 * @param pachName Symbol name.
135 * @param cchName Length of symbol name.
136 * @param off Offset into the object.
137 * @param iObject LX Object index.
138 * @param iType Type index. (index into type table)
139 */
140kHllPubSymEntry::kHllPubSymEntry(
141 const char * pachName,
142 int cchName,
143 unsigned long off,
144 unsigned short iObject,
145 unsigned short iType
146 )
147{
148 pPubSym = (PHLLPUBLICSYM)malloc(cchName + sizeof(HLLPUBLICSYM));
149 assert(pPubSym != NULL);
150
151 pPubSym->cchName = (unsigned char)cchName;
152 pPubSym->achName[0] = '\0';
153 strncat((char*)&pPubSym->achName[0], pachName, cchName);
154 pPubSym->off = off;
155 pPubSym->iObject = iObject;
156 pPubSym->iType = iType;
157}
158
159
160
161/**
162 * Destructor.
163 */
164kHllPubSymEntry::~kHllPubSymEntry()
165{
166 if (pPubSym != NULL)
167 free(pPubSym);
168 pPubSym = NULL;
169}
170
171
172
173/**
174 * Write this entry to file.
175 * @returns Count of bytes written (on success).
176 * -3 Invalid offsets.
177 * -2 Seek error.
178 * -1 Write error.
179 * 0 No data written. Concidered as an error!
180 * @param phFile Filehandle.
181 */
182int kHllPubSymEntry::write(FILE *phFile)
183{
184 assert(pPubSym != NULL);
185 return fwrite(pPubSym,
186 1,
187 offsetof(HLLPUBLICSYM, achName) + pPubSym->cchName,
188 phFile);
189}
190
191
192/**
193 * Dumps the HLL entry to ph in a human readable fashion.
194 * @param ph Output file handle the dump is to be written to.
195 * @param cchIndent Number of char to indents the output dump.
196 */
197void kHllPubSymEntry::dump(FILE *ph, int cchIndent)
198{
199 /*
200 * Dump public symbol entry
201 */
202 fprintf(ph, "%*.s0x%04x:0x%08x type:%04d(0x%04) name: %.*s\n",
203 cchIndent, "",
204 pPubSym->iObject,
205 pPubSym->off,
206 pPubSym->iType,
207 pPubSym->iType,
208 pPubSym->cchName, pPubSym->achName
209 );
210}
211
212
213
214
215
216
217
218/*******************************************************************************
219* *
220* kHllLineNumberChunk *
221* *
222* kHllLineNumberChunk *
223* *
224*******************************************************************************/
225
226
227
228
229 int cLines;
230 PHLLLINENUMBERENTRY paLines;
231 HLLFIRSTENTRY FirstEntry;
232
233/**
234 * Constructor.
235 * @param iSeg Segment number for these linenumbers.
236 * @param offBase Base offset for all line number offsets. (defaults to 0)
237 */
238kHllLineNumberChunk::kHllLineNumberChunk(
239 unsigned short int iSeg,
240 unsigned long int offBase /*= 0*/
241 )
242{
243 memset(&FirstEntry, 0, sizeof(FirstEntry));
244 FirstEntry.hll04.iSeg = iSeg;
245 FirstEntry.hll04.u1.offBase = offBase;
246 FirstEntry.hll04.uchType = 0;
247}
248
249
250
251/**
252 * Destructor.
253 */
254kHllLineNumberChunk::~kHllLineNumberChunk()
255{
256 if (paLines != NULL)
257 free(paLines);
258 paLines = 0;
259 FirstEntry.hll04.cEntries = 0;
260}
261
262
263
264/**
265 * Adds a line information.
266 * @returns Success indicator.
267 * @param iusFile File index.
268 * @param usLine Line number
269 * @param off Offset into object.
270 */
271BOOL kHllLineNumberChunk::addLineInfo(
272 unsigned short int iusFile,
273 unsigned short int usLine,
274 unsigned long int off
275 )
276{
277 /*
278 * Allocate more memory?
279 */
280 if (FirstEntry.hll04.cEntries % 20 == 0)
281 {
282 void *pv = realloc(paLines, (FirstEntry.hll04.cEntries + 20) * sizeof(paLines[0].hll04));
283 assert(pv != NULL);
284 if (pv == NULL)
285 return FALSE;
286 paLines = (PHLLLINENUMBERENTRY)pv;
287 }
288
289 /*
290 * Add line info entry.
291 */
292 paLines[FirstEntry.hll04.cEntries].hll04.iusSourceFile = iusFile;
293 paLines[FirstEntry.hll04.cEntries].hll04.off = off;
294 paLines[FirstEntry.hll04.cEntries].hll04.usLine = usLine;
295 FirstEntry.hll04.cEntries++;
296
297 return FALSE;
298}
299
300
301/**
302 * Write this entry to file.
303 * @returns Count of bytes written (on success).
304 * -3 Invalid offsets.
305 * -2 Seek error.
306 * -1 Write error.
307 * 0 No data written. Concidered as an error!
308 * @param phFile Filehandle.
309 */
310int kHllLineNumberChunk::write(FILE *phFile)
311{
312 int cb;
313 int cbWritten;
314
315 /*
316 * First entry
317 */
318 cb = sizeof(paLines[0])*FirstEntry.hll04.cEntries;
319 cbWritten = fwrite(&FirstEntry, 1, cb, phFile);
320 if (cbWritten != cb)
321 return -1;
322
323 /*
324 * Line array.
325 */
326 cb = sizeof(paLines[0])*FirstEntry.hll04.cEntries;
327 cbWritten = fwrite(paLines, 1, cb, phFile);
328 if (cbWritten != cb)
329 return -1;
330
331 return cbWritten + sizeof(FirstEntry.hll04);
332}
333
334
335
336/**
337 * Dumps the HLL entry to ph in a human readable fashion.
338 * @param ph Output file handle the dump is to be written to.
339 * @param cchIndent Number of char to indents the output dump.
340 */
341void kHllLineNumberChunk::dump(FILE *ph, int cchIndent)
342{
343 int i;
344
345 /*
346 * Write header.
347 * Dump first entry.
348 * Dump linenumbers.
349 * Write footer.
350 */
351 fprintf(ph, "%*.s------- start kHllLineNumberChunk object 0x%08x -------\n",
352 cchIndent, "", this);
353
354 /* ASSUMES - TODO - FIXME: HLL version 3 or 4. */
355 fprintf(ph, "%*.sBaseLine: %04d Type: 0x%02x Entries: 0x%04(%d) iSeg: 0x04x(%d) ",
356 cchIndent, "",
357 FirstEntry.hll04.usLine,
358 FirstEntry.hll04.uchType,
359 FirstEntry.hll04.cEntries,
360 FirstEntry.hll04.cEntries,
361 FirstEntry.hll04.iSeg,
362 FirstEntry.hll04.iSeg
363 );
364 if (FirstEntry.hll04.uchType == 0)
365 fprintf(ph, "offBase: 0x%08x\n", FirstEntry.hll04.u1.offBase);
366 else
367 fprintf(ph, "u1: 0x%08x\n", FirstEntry.hll04.u1.offBase);
368
369
370 /* ASSUMES - TODO - FIXME: HLL version 3 or 4. */
371 for (i = 0; i < FirstEntry.hll04.cEntries; i++)
372 fprintf(ph, "%*.sFile: %04d Line: %04d Offset: 0x%08x\n",
373 cchIndent, "",
374 paLines[i].hll04.iusSourceFile,
375 paLines[i].hll04.usLine,
376 paLines[i].hll04.off
377 );
378
379
380 fprintf(ph, "%*.s------- end kHllLineNumberChunk object 0x%08x -------\n",
381 cchIndent, "", this);
382}
383
384
385
386
387
388
389
390/*******************************************************************************
391* *
392* kHllSrcEntry *
393* *
394* kHllSrcEntry *
395* *
396*******************************************************************************/
397
398
399
400
401
402/**
403 * Constructor.
404 */
405kHllSrcEntry::kHllSrcEntry()
406 :
407 cFilenames(0),
408 pachFilenames(NULL),
409 cbFilenames(0),
410 cbFilenamesAllocated(0)
411{
412}
413
414
415/**
416 * Destructor.
417 */
418kHllSrcEntry::~kHllSrcEntry()
419{
420 if (pachFilenames != NULL)
421 free(pachFilenames);
422 pachFilenames = NULL;
423 cFilenames = cbFilenames = cbFilenamesAllocated = 0;
424}
425
426
427
428/**
429 * Add/queries a Linenumber chunk.
430 * A linenumber chunk is a collection of linenumber information for a
431 * module segement.
432 * @returns Pointer to linenumber chunk which you may add linenumber info to.
433 * NULL on failiure.
434 * @param iSeg Segment number for these linenumbers.
435 * @param offBase Base offset for all line number offsets. (defaults to 0)
436 */
437kHllLineNumberChunk *
438 kHllSrcEntry::addLineNumberChunk(
439 unsigned short int iSeg,
440 unsigned long int offBase/* = 0*/
441 )
442{
443 kHllLineNumberChunk *pChunk;
444
445 /*
446 * Try find existing chunk.
447 */
448 pChunk = Lines.getFirst();
449 while (pChunk != NULL && pChunk->getSeg() != iSeg)
450 pChunk = (kHllLineNumberChunk*)pChunk->getNext();
451
452 /*
453 * If not found, then create a new one and add it to the list.
454 */
455 if (pChunk != NULL)
456 {
457 pChunk = new kHllLineNumberChunk(iSeg, offBase);
458 assert(pChunk != NULL);
459 if (pChunk != NULL)
460 Lines.insert(pChunk);
461 }
462
463 return pChunk;
464}
465
466
467
468/**
469 * Adds a file for this module.
470 * @returns Filename index used when adding linenumbers.
471 * @param pszFilename Pointer to filaname string.
472 */
473unsigned short kHllSrcEntry::addFile(
474 const char * pszFilename
475 )
476{
477 return addFile(pszFilename, strlen(pszFilename));
478}
479
480
481
482/**
483 * Adds a file for this module.
484 * @returns Filename index used when adding linenumbers.
485 * 0 on error.
486 * @param pachFilename Pointer to filaname string (not zero terminated).
487 * @param cchFilename Length of filename.
488 */
489unsigned short kHllSrcEntry::addFile(
490 const char * pachFilename,
491 int cchFilename
492 )
493{
494 assert(pachFilename != NULL);
495 assert(cchFilename < 256);
496 if (cchFilename >= 256)
497 cchFilename = 255;
498
499 /*
500 * Allocate more memory?
501 */
502 if ((cbFilenames + cchFilename + 1) >= cbFilenamesAllocated)
503 {
504 void *pv = realloc(pachFilenames, (size_t)cbFilenamesAllocated + 256);
505 assert(pv != NULL);
506 if (pv == NULL)
507 return 0;
508 pachFilenames = (char*)pv;
509 cbFilenamesAllocated += 256;
510 }
511
512
513 /*
514 * Add filename
515 */
516 pachFilenames[cbFilenames++] = (char)cchFilename;
517 memcpy(&pachFilenames[cbFilenames], pachFilename, cchFilename);
518 cbFilenames += cchFilename;
519
520 return (unsigned short)++cFilenames;
521}
522
523
524
525/**
526 * Write this entry to file.
527 * @returns Count of bytes written (on success).
528 * -3 Invalid offsets.
529 * -2 Seek error.
530 * -1 Write error.
531 * 0 No data written. Concidered as an error!
532 * @param phFile Filehandle.
533 */
534int kHllSrcEntry::write(FILE *phFile)
535{
536 HLLFIRSTENTRY FirstEntry;
537 HLLFILENAMEENTRY FilenameEntry;
538 int cb;
539 int cbWrote;
540 int cbWritten;
541
542 /*
543 * Filenames - if no filename present we'll add a dummy filename!
544 * First entry for the filenames.
545 * Filename entry header.
546 * Write filename entries.
547 */
548 FirstEntry.hll04.usLine = 0;
549 FirstEntry.hll04.uchType = 3; /* filename */
550 FirstEntry.hll04.uchReserved = 0;
551 FirstEntry.hll04.cEntries = (unsigned short)max(cFilenames, 1);
552 FirstEntry.hll04.iSeg = 0;
553 FirstEntry.hll04.u1.cbFileNameTable = cbFilenames != 0 ? cbFilenames : 8;
554 cb = sizeof(FirstEntry.hll04);
555 cbWritten = cbWrote = fwrite(&FirstEntry, 1, cb, phFile);
556 if (cb != cbWrote)
557 return -1;
558
559 FilenameEntry.cSourceFiles = max(cFilenames, 1);
560 FilenameEntry.offSource = 0;
561 FilenameEntry.cSourceRecords = 0;
562 cb = offsetof(HLLFILENAMEENTRY, cchName);
563 cbWritten += cbWrote = fwrite(&FilenameEntry, 1, cb, phFile);
564 if (cbWrote != cb)
565 return -1;
566
567 if (cbFilenames != 0)
568 {
569 cbWritten += cbWrote = fwrite(pachFilenames, 1, cbFilenames, phFile);
570 if (cbWrote != cbFilenames)
571 return -1;
572 }
573 else
574 { /* no filename - write dummy empty */
575 cbWritten += cbWrote = fwrite("\07dummy.c", 1, 8, phFile);
576 if (cbWrote != 8)
577 return -1;
578 }
579
580
581 /*
582 * Write linenumbers.
583 */
584 if (Lines.getFirst() != NULL)
585 {
586 cbWritten += cbWrote = kHllBaseEntry::writeList(phFile, Lines.getFirst());
587 if (cbWrote < 0)
588 return cbWrote;
589 }
590
591 return cbWritten;
592}
593
594
595
596/**
597 * Dumps the HLL entry to ph in a human readable fashion.
598 * @param ph Output file handle the dump is to be written to.
599 * @param cchIndent Number of char to indents the output dump.
600 */
601void kHllSrcEntry::dump(FILE *ph, int cchIndent)
602{
603 int i;
604 char * pach;
605
606 /*
607 * Write header with filename count.
608 * Write filenames.
609 * Dump linenumber list.
610 * Write footer with filename count.
611 */
612 fprintf(ph, "%*.s------- start kHllSrcEntry object 0x%08x --- %d -------\n",
613 cchIndent, "", this, cFilenames);
614
615 for (i = 0, pach = pachFilenames; i < cFilenames; i++, pach += 1 + *pach)
616 fprintf(ph, "%*.s%.2d - %.*s\n",
617 cchIndent, "",
618 i, *pach, pach + 1);
619
620 kHllBaseEntry::dumpList(ph, cchIndent + 4, Lines.getFirst());
621
622 fprintf(ph, "%*.s------- end kHllSrcEntry object 0x%08x --- %d -------\n",
623 cchIndent, "", this, cFilenames);
624}
625
626
627
628
629
630
631/*******************************************************************************
632* *
633* kHllModuleEntry *
634* *
635* kHllModuleEntry *
636* *
637*******************************************************************************/
638
639
640
641
642
643
644
645/**
646 * Creates an HLL module entry.
647 * @param pszName Module name. (NULL is not allowed!)
648 * @param iLib Library index.
649 * @param cSegInfo Number of objects in the array.
650 * @param paSegInfo Pointer to an array of objects.
651 */
652kHllModuleEntry::kHllModuleEntry(
653 const char * pszName,
654 unsigned short iLib,
655 unsigned char cSegInfo/*= 0 */,
656 PHLLSEGINFO paSegInfo/*= NULL */
657 )
658: fValidOffsetsAndSizes(FALSE)
659{
660 int i;
661 int cchName;
662 PHLLSEGINFO pSegInfo;
663
664 /*
665 * Debug parameter validations.
666 */
667 assert(pszName != NULL);
668 assert(cSegInfo == 0 || paSegInfo != NULL);
669
670 /*
671 * Allocate data storage and fill HLL structure.
672 */
673 cchName = strlen(pszName);
674 cchName = min(cchName, 255);
675 pModule = (PHLLMODULE)malloc(sizeof(HLLMODULE) + cchName +
676 (sizeof(HLLSEGINFO) * max((cSegInfo - 1), 3)));
677 assert(pModule != NULL);
678 memset(pModule, 0, sizeof(*pModule));
679 pModule->cchName = (unsigned char)cchName;
680 memcpy(&pModule->achName[0], pszName, cchName);
681 pModule->chVerMajor = 4;
682 pModule->chVerMinor = 0;
683 pModule->cSegInfo = cSegInfo;
684 pModule->iLib = iLib;
685 pModule->usDebugStyle = HLL_MOD_STYLE;
686 pModule->overlay = 0;
687 pModule->pad = 0;
688
689 /* objects */
690 if (cSegInfo != 0)
691 {
692 pModule->SegInfo0.iObject = paSegInfo->iObject;
693 pModule->SegInfo0.cb = paSegInfo->cb;
694 pModule->SegInfo0.off = paSegInfo->off;
695
696 for (i = 1, pSegInfo = (PHLLSEGINFO)&pModule->achName[cchName]; i < cSegInfo; i++, pSegInfo++)
697 {
698 pSegInfo->iObject = paSegInfo[i].iObject;
699 pSegInfo->cb = paSegInfo[i].cb;
700 pSegInfo->off = paSegInfo[i].off;
701 }
702 }
703}
704
705
706/**
707 * Destructor - free storage.
708 */
709kHllModuleEntry::~kHllModuleEntry()
710{
711 if (pModule != NULL)
712 free(pModule);
713 pModule = NULL;
714}
715
716
717
718/**
719 * Adds an object to the module.
720 * @returns Success indicator.
721 * @param iObject LX Object index.
722 * @param off Offset into the object to the module data.
723 * @param cb Size of module data (in the object).
724 */
725BOOL kHllModuleEntry::addSegInfo(
726 unsigned short int iObject,
727 unsigned long off,
728 unsigned long cb
729 )
730{
731 assert(pModule != NULL);
732
733 /*
734 * Reallocate? (Note that we'll initially allocated space for 3 objects.)
735 */
736 if (pModule->cSegInfo >= 3)
737 {
738 void *pv = realloc(pModule, sizeof(HLLMODULE) + pModule->cchName
739 + (pModule->cSegInfo + 1) * sizeof(HLLSEGINFO));
740 assert(pv != NULL);
741 if (pv == NULL)
742 return FALSE;
743 pModule = (PHLLMODULE)pv;
744 }
745
746
747 /*
748 * Add module.
749 */
750 if (pModule->cSegInfo == 0)
751 {
752 pModule->SegInfo0.cb = cb;
753 pModule->SegInfo0.off = off;
754 pModule->SegInfo0.iObject = iObject;
755 }
756 else
757 {
758 PHLLSEGINFO pSegInfo = (PHLLSEGINFO)((pModule->cSegInfo - 1) * sizeof(HLLSEGINFO)
759 + &pModule->achName[pModule->cchName]);
760 pSegInfo->cb = cb;
761 pSegInfo->off = off;
762 pSegInfo->iObject = iObject;
763 }
764 pModule->cSegInfo++;
765
766 return TRUE;
767}
768
769
770
771/**
772 * Adds a public symbol.
773 * @returns Handle to the symbol. NULL on error.
774 * @param pszName Symbol name.
775 * @param off Offset into the LX Object of the symbol.
776 * @param iObject LX Object index.
777 * @param pvType Type handle. NULL if not type.
778 */
779const void * kHllModuleEntry::addPublicSymbol(
780 const char * pszName,
781 unsigned long int off,
782 unsigned short int iObject,
783 const void * pvType
784 )
785{
786 assert(pszName != NULL);
787 return addPublicSymbol(pszName, strlen(pszName), off, iObject, pvType);
788}
789
790
791
792/**
793 * Adds a public symbol.
794 * @returns Handle to the symbol. NULL on error.
795 * @param pachName Symbol name.
796 * @param cchName Name length.
797 * @param off Offset into the LX Object of the symbol.
798 * @param iObject LX Object index.
799 * @param pvType Type handle. NULL if not type.
800 */
801const void * kHllModuleEntry::addPublicSymbol(
802 const char * pachName,
803 int cchName,
804 unsigned long int off,
805 unsigned short int iObject,
806 const void * pvType
807 )
808{
809 kHllPubSymEntry * pEntry;
810
811 /* parameter assertion */
812 assert(pachName != NULL);
813
814 /*
815 * Create a public symbol entry
816 * Insert into it's list.
817 * Invalidate offsets.
818 */
819 pEntry = new kHllPubSymEntry(
820 pachName,
821 cchName,
822 off,
823 iObject,
824 (unsigned short)(pvType == NULL ? 0 : -1) //FIXME/TODO: Types->getIndex(pvType); check if 0 or -1.
825 );
826
827 PublicSymbols.insert(pEntry);
828
829 fValidOffsetsAndSizes = FALSE;
830
831 return pEntry;
832}
833
834
835
836
837/**
838 * Write this HLL entry to file.
839 * @returns Count of bytes written.
840 * -3 Invalid offsets.
841 * -2 Seek error.
842 * -1 Write error.
843 * @param phFile Filehandle.
844 * @param off Current offset into the HLL data.
845 * This is stored and used when making the directory
846 * entries for this module.
847 */
848int kHllModuleEntry::write(FILE *phFile, unsigned long off)
849{
850 int cch;
851 int cchToWrite;
852 int cchWritten = 0;
853
854 /* validate object state */
855 assert(pModule != NULL);
856
857 /*
858 * Write module HLL data.
859 */
860 offModule = off;
861 cchToWrite = offsetof(HLLMODULE, achName) + pModule->cchName + sizeof(HLLSEGINFO) * max(pModule->cSegInfo-1, 0);
862 cch = fwrite(pModule, 1, cchToWrite, phFile);
863 if (cch != cchToWrite)
864 return -1;
865 cchWritten += cch;
866 cbModule = cch;
867 off += cch;
868
869 /*
870 * Write the lists.
871 * Public Symbols
872 * Types
873 * Symbols
874 * Source
875 */
876 offPublicSymbols = off;
877 cbPublicSymbols = cch = kHllBaseEntry::writeList(phFile, PublicSymbols.getFirst());
878 if (cch < 0)
879 return cch;
880 cchWritten += cch;
881 off += cch;
882
883 /*
884 offTypes = off;
885 cbTypes = cch = kHllBaseEntry::writeList(phFile, Types.getFirst());
886 if (cch < 0)
887 return cch;
888 cchWritten += cch;
889 off += cch;
890
891
892 offSymbols = off;
893 cbSymbols = cch = kHllBaseEntry::writeList(phFile, Symbols.getFirst());
894 if (cch < 0)
895 return cch;
896 cchWritten += cch;
897 off += cch;
898 */
899
900 offSource = off;
901 cbSource = cch = Source.write(phFile);
902 if (cch < 0)
903 return cch;
904 cchWritten += cch;
905 off += cch;
906
907 /*
908 * Marks offsets and sizes valid and returns succesfully.
909 */
910 fValidOffsetsAndSizes = TRUE;
911 return cchWritten;
912}
913
914
915
916/**
917 * Writes the directory entries for this module to file.
918 * @returns Count of bytes written on success.
919 * -3 Invalid offsets.
920 * -2 Seek error.
921 * -1 Write error.
922 * 0 no data written (this is an error condition!)
923 * @param phFile Filehandle.
924 * @param iMod Index of this module.
925 */
926int kHllModuleEntry::writeDirEntries(FILE *phFile, unsigned short iMod)
927{
928 HLLDIRENTRY hllDirEntry;
929 int cch;
930 int cchWritten = 0;
931
932 /*
933 * Check that offsets are valid!
934 */
935 assert(fValidOffsetsAndSizes);
936 if (!fValidOffsetsAndSizes)
937 return -3;
938
939 /*
940 * Write Directory Entries.
941 * Module.
942 * Public Symbols. (if any)
943 * Types. (if any)
944 * Symbols. (if any)
945 * Source. (if any)
946 */
947 hllDirEntry.usType = HLL_DE_MODULES;
948 hllDirEntry.cb = cbModule;
949 hllDirEntry.off = offModule;
950 hllDirEntry.iMod = iMod;
951 cch = fwrite(&hllDirEntry, 1, sizeof(hllDirEntry), phFile);
952 if (cch != sizeof(hllDirEntry))
953 return -1;
954 cchWritten += cch;
955
956 if (cbPublicSymbols != 0)
957 {
958 hllDirEntry.usType = HLL_DE_PUBLICS;
959 hllDirEntry.cb = cbPublicSymbols;
960 hllDirEntry.off = offPublicSymbols;
961 hllDirEntry.iMod = iMod;
962 cch = fwrite(&hllDirEntry, 1, sizeof(hllDirEntry), phFile);
963 if (cch != sizeof(hllDirEntry))
964 return -1;
965 cchWritten += cch;
966 }
967
968 /*
969 if (cbTypes > 0)
970 {
971 hllDirEntry.usType = HLL_DE_TYPES;
972 hllDirEntry.cb = cbTypes;
973 hllDirEntry.off = offTypes;
974 hllDirEntry.iMod = iMod;
975 cch = fwrite(&hllDirEntry, 1, sizeof(hllDirEntry), phFile);
976 if (cch != sizeof(hllDirEntry))
977 return -1;
978 cchWritten += cch;
979 }
980
981 if (cbSymbols > 0)
982 {
983 hllDirEntry.usType = HLL_DE_SYMBOLS;
984 hllDirEntry.cb = cbSymbols;
985 hllDirEntry.off = offSymbols;
986 hllDirEntry.iMod = iMod;
987 cch = fwrite(&hllDirEntry, 1, sizeof(hllDirEntry), phFile);
988 if (cch != sizeof(hllDirEntry))
989 return -1;
990 cchWritten += cch;
991 }
992 */
993
994 if (cbSource != 0)
995 {
996 hllDirEntry.usType = HLL_DE_IBMSRC;
997 hllDirEntry.cb = cbSource;
998 hllDirEntry.off = offSource;
999 hllDirEntry.iMod = iMod;
1000 cch = fwrite(&hllDirEntry, 1, sizeof(hllDirEntry), phFile);
1001 if (cch != sizeof(hllDirEntry))
1002 return -1;
1003 cchWritten += cch;
1004 }
1005
1006
1007 return cchWritten;
1008}
1009
1010
1011/**
1012 * Dumps this module entry to the given file.
1013 * @param ph Filehandle to dump this module entry to.
1014 */
1015void kHllModuleEntry::dump(FILE *ph)
1016{
1017 PHLLSEGINFO pSegInfo;
1018 int i;
1019
1020 fprintf(ph, " ------- start dumping kHllModuleEntry object 0x%08x -------\n", this);
1021
1022 /*
1023 * Dump HLL module entry.
1024 */
1025 fprintf(ph, " Modulename: %.*s Style: %.2s HLL ver: %d.%d #SegInfos: %d\n",
1026 pModule->cchName, pModule->achName,
1027 &pModule->usDebugStyle,
1028 pModule->chVerMajor, pModule->chVerMinor,
1029 pModule->cSegInfo
1030 );
1031
1032 for (i = 0, pSegInfo = &pModule->SegInfo0; i < pModule->cSegInfo; i++)
1033 {
1034 fprintf(ph, " Obj.no.: 0x%04x Offset: 0x%08x Size: 0x%08x(%d)\n",
1035 pSegInfo->iObject, pSegInfo->off, pSegInfo->cb, pSegInfo->cb);
1036
1037 /* next */
1038 if (i == 0)
1039 pSegInfo = (PHLLSEGINFO)&pModule->achName[pModule->cchName];
1040 else
1041 pSegInfo++;
1042 }
1043
1044
1045 /*
1046 * Dump the sub-entries.
1047 */
1048 kHllBaseEntry::dumpList(ph, 8, PublicSymbols.getFirst());
1049 /*
1050 kHllBaseEntry::dumpList(ph, 8, Types.getFirst());
1051 kHllBaseEntry::dumpList(ph, 8, Symbols.getFirst());
1052 kHllBaseEntry::dumpList(ph, 8, Source.getFirst());
1053 */
1054 Source.dump(ph, 8);
1055
1056
1057 fprintf(ph, " ------- end dumping kHllModuleEntry object 0x%08x -------\n", this);
1058}
1059
1060
1061
1062
1063
1064
1065
1066
1067/*******************************************************************************
1068* *
1069* kHll *
1070* *
1071* kHll *
1072* *
1073*******************************************************************************/
1074
1075
1076
1077/**
1078 * Writes HLL debuginfo to the given file at the current position.
1079 * The file should be opened in write mode.
1080 * @returns Number of bytes written.
1081 * @param phFile Filehandle to output file. Starts writing at current pos.
1082 */
1083int kHll::write(FILE *phFile)
1084{
1085 HLLHDR hllHdr;
1086 HLLDIR hllDir;
1087 kHllModuleEntry * pModule;
1088 int cch; /* Number of bytes written to the file in an operation. */
1089 int cchWritten = 0; /* Number of bytes written to the file. */
1090 long int lPosStart; /* Starting position. */
1091 long int lPosDir; /* Directory position. */
1092 long int lPos; /* A file position. */
1093 int iMod; /* Module index (passed in to writeDirEntries) */
1094
1095 /* Get starting position. */
1096 lPosStart = ftell(phFile);
1097
1098 /* Make temporary header and write it */
1099 memcpy(hllHdr.achSignature, "NB04", 4);
1100 hllHdr.offDirectory = 0;
1101 cch = fwrite(&hllHdr, 1, sizeof(hllHdr), phFile);
1102 if (cch != sizeof(hllHdr))
1103 return -1;
1104 cchWritten += cch;
1105
1106
1107 /*
1108 * Start writing modules
1109 */
1110 pModule = (kHllModuleEntry*)Modules.getFirst();
1111 while (pModule != NULL)
1112 {
1113 cch = pModule->write(phFile, cchWritten);
1114 if (cch <= 0)
1115 return cch;
1116 cchWritten += cch;
1117 pModule = (kHllModuleEntry *)pModule->getNext();
1118 }
1119
1120
1121 /*
1122 * Write libraries.
1123 */
1124 //Not implemented yet - TODO/FIXME!
1125
1126
1127 /*
1128 * Write directory.
1129 * Make and write temporary directory header.
1130 * Write directory entries per module.
1131 * Write directory entry for libraries.
1132 * Remake and rewrite directory header. (correct cEntries)
1133 */
1134 lPosDir = ftell(phFile);
1135 hllDir.cEntries = 0;
1136 hllDir.cb = offsetof(HLLDIR, aEntries);
1137 hllDir.cbEntry = sizeof(HLLDIRENTRY);
1138 cch = fwrite(&hllDir, 1, offsetof(HLLDIR, aEntries), phFile);
1139 if (cch != offsetof(HLLDIR, aEntries))
1140 return -1;
1141 cchWritten += cch;
1142
1143 iMod = 1;
1144 pModule = (kHllModuleEntry*)Modules.getFirst();
1145 while (pModule != NULL)
1146 {
1147 cch = pModule->writeDirEntries(phFile, (unsigned short)iMod);
1148 if (cch == -1)
1149 return -1;
1150 cchWritten += cch;
1151 pModule = (kHllModuleEntry *)pModule->getNext();
1152 iMod++;
1153 }
1154
1155 //Library - TODO/FIXME
1156
1157 lPos = ftell(phFile);
1158 hllDir.cEntries = (lPos - lPosDir - offsetof(HLLDIR, aEntries)) / sizeof(HLLDIRENTRY);
1159 if (fseek(phFile, lPosDir, SEEK_SET) != 0)
1160 return -2;
1161 cch = fwrite(&hllDir, 1, offsetof(HLLDIR, aEntries), phFile);
1162 if (cch != offsetof(HLLDIR, aEntries))
1163 return -1;
1164
1165 /*
1166 * Rewrite HLL header (with correct directory offset).
1167 */
1168 hllHdr.offDirectory = lPosDir - lPosStart;
1169 if (fseek(phFile, lPosStart, SEEK_SET) != 0)
1170 return -2;
1171 cch = fwrite(&hllHdr, 1, sizeof(hllHdr), phFile);
1172 if (cch != sizeof(hllHdr))
1173 return -1;
1174
1175 /*
1176 * Hacking:
1177 * Writing an extra HLL header pointing to an non-existing directory
1178 * staring at the last byte of this header. This is present when linking
1179 * with ilink...
1180 */
1181 if (fseek(phFile, lPosStart + cchWritten, SEEK_SET) != 0)
1182 return -2;
1183 hllHdr.offDirectory = cchWritten + sizeof(hllHdr);
1184 cch = fwrite(&hllHdr, 1, sizeof(hllHdr), phFile);
1185 if (cch != sizeof(hllHdr))
1186 return -1;
1187 cchWritten += cch;
1188
1189 return cchWritten;
1190}
1191
1192
1193
1194/**
1195 * Constructor - Creates an empty HLL object.
1196 */
1197kHll::kHll()
1198{
1199}
1200
1201
1202/**
1203 * Creates a kHll object from debugdata found in a file (LX layout).
1204 * @param pFile Pointer to file object which the data is to be read from.
1205 * The file object is positioned at the start of the debuginfo.
1206 * start of the debuginfo.
1207 * Note. The file object is set to throw on errors.
1208 */
1209kHll::kHll(kFile *pFile) throw (int)
1210{
1211 long offHllHdr; /* Offset of debug data in file. */
1212 HLLHDR hllHdr; /* HLL data header. */
1213 HLLDIR hllDir; /* HLL directory (header only) */
1214 PHLLDIR pHllDir; /* HLL directory (all) */
1215 PHLLDIRENTRY pDirEntry; /* Current HLL directory entry. */
1216 int iDir;
1217
1218 /* auto throw */
1219 pFile->setThrowOnErrors();
1220
1221 /* Save file offset of debugdata. */
1222 offHllHdr = pFile->getPos();
1223
1224 /* Read HLL header */
1225 pFile->read(&hllHdr, sizeof(hllHdr));
1226 if (memcmp(hllHdr.achSignature, "NB04", 4) != 0)
1227 throw(ERROR_INVALID_EXE_SIGNATURE);
1228
1229 /*
1230 * Read the Directory head to get the directory size.
1231 * Allocate memory for the entire directory and read it.
1232 */
1233 pFile->readAt(&hllDir, sizeof(hllDir), offHllHdr + hllHdr.offDirectory);
1234 pHllDir = (PHLLDIR)malloc((size_t)(hllDir.cbEntry * hllDir.cEntries + hllDir.cb));
1235 if (pHllDir == NULL) throw(ERROR_NOT_ENOUGH_MEMORY);
1236 pFile->readAt(pHllDir, hllDir.cbEntry * hllDir.cEntries + hllDir.cb, offHllHdr + hllHdr.offDirectory);
1237
1238
1239 /*
1240 * Loop thru the directory entries and add them we have implemented.
1241 */
1242 unsigned long ulHLLVersion = 0; /* HLL version of the last module. */
1243 kHllModuleEntry *pCurMod = NULL; /* Current Module. */
1244 int iCurMod = 0; /* Current Module index (import). */
1245
1246 for (iDir = 0, pDirEntry = (PHLLDIRENTRY)((char*)pHllDir + hllDir.cb);
1247 iDir < pHllDir->cEntries;
1248 iDir++, pDirEntry = (PHLLDIRENTRY)((char*)pDirEntry + hllDir.cbEntry)
1249 )
1250 {
1251 CHAR szName[1024];
1252
1253 switch (pDirEntry->usType)
1254 {
1255 /*
1256 * Source filename(=Module) entry.
1257 */
1258 case HLL_DE_MODULES:
1259 {
1260 HLLMODULE hllMod;
1261 PHLLSEGINFO paSegInfo;
1262
1263 /*
1264 * Read hllmod, filename and seginfo table if any.
1265 */
1266 pFile->readAt(&hllMod, sizeof(hllMod), offHllHdr + pDirEntry->off);
1267 pFile->move(-1);
1268 pFile->read(szName, hllMod.cchName);
1269 szName[hllMod.cchName] = '\0';
1270 if (hllMod.cSegInfo != 0)
1271 {
1272 paSegInfo = (PHLLSEGINFO)malloc(sizeof(HLLSEGINFO) * hllMod.cSegInfo);
1273 if (pHllDir == NULL) throw(ERROR_NOT_ENOUGH_MEMORY);
1274 memcpy(paSegInfo, &hllMod.SegInfo0, sizeof(HLLSEGINFO));
1275 if (hllMod.cSegInfo > 1)
1276 pFile->read(&paSegInfo[1], sizeof(HLLSEGINFO) * (hllMod.cSegInfo - 1));
1277 }
1278 else
1279 paSegInfo = NULL;
1280
1281 /*
1282 * Add the module and save module data for later use.
1283 * Cleanup seginfo.
1284 */
1285 pCurMod = this->addModule(szName, hllMod.cchName, NULL, hllMod.cSegInfo, paSegInfo);
1286 iCurMod = pDirEntry->iMod;
1287 ulHLLVersion = HLLMAKEVER(hllMod.chVerMajor, hllMod.chVerMinor);
1288
1289 if (paSegInfo != NULL)
1290 free(paSegInfo);
1291 fprintf(stderr, "Module directory entry: %s\n", szName);
1292 break;
1293 }
1294
1295 case HLL_DE_PUBLICS: /* Public symbols */
1296 fprintf(stderr, "Publics directory entry\n");
1297 break;
1298
1299 case HLL_DE_TYPES: /* Types */
1300 fprintf(stderr, "Types directory entry\n");
1301 break;
1302
1303 case HLL_DE_SYMBOLS: /* Symbols */
1304 fprintf(stderr, "Symbols directory entry\n");
1305 break;
1306
1307 case HLL_DE_LIBRARIES: /* Libraries */
1308 fprintf(stderr, "Libraries directory entry\n");
1309 break;
1310
1311 case HLL_DE_SRCLINES: /* Line numbers - (IBM C/2 1.1) */
1312 fprintf(stderr, "SRCLINES directory entry\n");
1313 break;
1314
1315 case HLL_DE_SRCLNSEG: /* Line numbers - (MSC 6.00) */
1316 fprintf(stderr, "SRCLNSEG directory entry\n");
1317 break;
1318
1319 case HLL_DE_IBMSRC: /* Line numbers - (IBM HLL) */
1320 fprintf(stderr, "IBMSRC directory entry\n");
1321 break;
1322
1323 default:
1324 /* Unsupported directory entry - ignore */
1325 fprintf(stderr, "Unsupported directory entry %d\n", pDirEntry->usType);
1326 break;
1327 }
1328 }
1329
1330 /* cleanup */
1331 free(pHllDir);
1332}
1333
1334
1335/**
1336 * Destructor.
1337 */
1338kHll::~kHll()
1339{
1340}
1341
1342
1343
1344/**
1345 * Adds a module.
1346 * @returns Pointer to the module object added. NULL on error.
1347 * @param pszName Module name
1348 * @param pvLib Library module handle.
1349 * @param cSegInfo Number of objects in the array.
1350 * @param paSegInfo Pointer to an array of objects.
1351 */
1352kHllModuleEntry * kHll::addModule(
1353 const char * pszName,
1354 const void * pvLib,
1355 unsigned cSegInfo,
1356 PHLLSEGINFO paSegInfo)
1357{
1358 kHllModuleEntry * pEntry;
1359 assert(pszName != NULL);
1360
1361 pEntry = new kHllModuleEntry(
1362 pszName,
1363 (unsigned short)(pvLib == NULL ? 0 : -1), //FIXME/TODO: Libs->getIndex(pvLib); check if 0 or -1;
1364 (unsigned char) cSegInfo,
1365 paSegInfo);
1366
1367 Modules.insert(pEntry);
1368 return pEntry;
1369}
1370
1371
1372
1373/**
1374 * Adds a module.
1375 * @returns Pointer to the module object added. NULL on error.
1376 * @param pachName Module name
1377 * @param cchName Length of modulename
1378 * @param pvLib Library module handle.
1379 * @param cSegInfo Number of objects in the array.
1380 * @param paSegInfo Pointer to an array of objects.
1381 */
1382kHllModuleEntry * kHll::addModule(
1383 const char * pachName,
1384 unsigned cchName,
1385 const void * pvLib,
1386 unsigned cSegInfo,
1387 PHLLSEGINFO paSegInfo)
1388{
1389 char szModName[256];
1390 kHllModuleEntry * pEntry;
1391 assert(pachName != NULL && cchName != 0);
1392
1393 szModName[0] = '\0';
1394 strncat(szModName, pachName, min(cchName, 255));
1395 pEntry = new kHllModuleEntry(
1396 szModName,
1397 (unsigned short)(pvLib == NULL ? 0 : -1), //FIXME/TODO: Libs->getIndex(pvLib); check if 0 or -1;
1398 (unsigned char)cSegInfo,
1399 paSegInfo);
1400
1401 Modules.insert(pEntry);
1402 return pEntry;
1403}
1404
1405
1406/**
1407 * Dump the object in a human readable fashion to stdout.
1408 */
1409void kHll::dump()
1410{
1411 FILE *ph = stdout;
1412
1413 fprintf(ph,
1414 "------- start dumping kHll object 0x%08x --- %d modules -------\n",
1415 this, Modules.getCount());
1416
1417 kHllModuleEntry * pMod = Modules.getFirst();
1418 while (pMod != NULL)
1419 {
1420 /* Dump it */
1421 pMod->dump(ph);
1422
1423 /* Next module */
1424 pMod = (kHllModuleEntry*)pMod->getNext();
1425 }
1426
1427 fprintf(ph,
1428 "------- end dumping kHll object 0x%08x --- %d modules -------\n",
1429 this, Modules.getCount());
1430}
1431
1432
1433/**
1434 * Creates a kHll object of the HLL debug information found a LX file.
1435 * (An empty object is returned when no info is found.)
1436 * @return Pointer to kHll object on success.
1437 * NULL on error. Message is printed.
1438 */
1439kHll * kHll::readLX(
1440 const char *pszFilename
1441 )
1442{
1443 try
1444 {
1445 struct exe_hdr ehdr;
1446 struct e32_exe e32;
1447 long offLXHdr;
1448
1449 kFile file(pszFilename);
1450
1451 /*
1452 * Find and read the LX header.
1453 */
1454 file.read(&ehdr, sizeof(ehdr));
1455 if (ehdr.e_magic == EMAGIC)
1456 offLXHdr = ehdr.e_lfanew;
1457 else
1458 offLXHdr = 0;
1459 file.readAt(&e32, sizeof(e32), offLXHdr);
1460 if (*(PSHORT)&e32.e32_magic[0] != E32MAGIC)
1461 throw (ERROR_INVALID_EXE_SIGNATURE);
1462
1463 /*
1464 * Is there any debug info in this LX header?
1465 */
1466 if (e32.e32_debuginfo != 0UL && e32.e32_debuglen != 0UL
1467 && file.set(e32.e32_debuginfo))
1468 return new kHll(&file);
1469 else
1470 return new kHll();
1471 }
1472 catch (int iOS2Error)
1473 {
1474 fprintf(stderr, "failed to create kHll object for file %s. Failed with OS2 error %d.\n",
1475 pszFilename, iOS2Error);
1476 }
1477 return NULL;
1478}
1479
1480
1481/**
1482 * Writes the HLL info to a file. (Not LX?)
1483 * @returns Success indicator.
1484 * @param pszFilename Name of the output file.
1485 * @remark IMPORTANT! This is mostly for debugging!
1486 * It completely overwrites the file if it exists!
1487 */
1488BOOL kHll::write(
1489 const char *pszFilename
1490 )
1491{
1492 FILE * phFile;
1493
1494 phFile = fopen(pszFilename, "wb");
1495 if (phFile != NULL)
1496 {
1497 int cch = write(phFile);
1498 if (cch > 0)
1499 {
1500 fclose(phFile);
1501 return TRUE;
1502 }
1503 else
1504 fprintf(stderr, "write failed with cch=%d\n", cch);
1505 fclose(phFile);
1506 }
1507
1508 return FALSE;
1509}
1510
1511
1512
1513/**
1514 * Writes the HLL info to a file. (Not LX?)
1515 * Failes if there is debuginfo in the file.
1516 * No backup is made. (sorry)
1517 * @returns OS2 return code.
1518 * @param pszFilename Name of the output file.
1519 */
1520APIRET kHll::writeToLX(
1521 const char *pszFilename
1522 )
1523{
1524 APIRET rc;
1525 FILE * phFile;
1526
1527 phFile = fopen(pszFilename, "rb+");
1528 if (phFile != NULL)
1529 {
1530 struct exe_hdr ehdr;
1531 struct e32_exe e32;
1532 int cch;
1533 long lPosLXHdr;
1534 long cbLXFile;
1535
1536 /*
1537 * Read exe header
1538 */
1539 cch = fread(&ehdr, 1, sizeof(ehdr), phFile);
1540 if (cch == sizeof(ehdr))
1541 {
1542 cbLXFile = fsize(phFile);
1543 if (ehdr.e_magic == EMAGIC)
1544 lPosLXHdr = ehdr.e_lfanew;
1545 else
1546 lPosLXHdr = 0;
1547 if (fseek(phFile, lPosLXHdr, SEEK_SET) == 0)
1548 {
1549 cch = fread(&e32, 1, sizeof(e32), phFile);
1550 if (cch == sizeof(e32))
1551 {
1552 if (*(unsigned short*)&e32.e32_magic[0] == E32MAGIC)
1553 {
1554 /*
1555 * Found exeheader.
1556 * Check if there is any debug info.
1557 */
1558 if ((e32.e32_debuginfo == 0 && e32.e32_debuginfo == 0)
1559 || (cbLXFile == e32.e32_debuglen + e32.e32_debuginfo)
1560 )
1561 {
1562 long lPosDebug;
1563
1564 if (e32.e32_debuginfo != 0 && e32.e32_debuglen != 0)
1565 lPosDebug = e32.e32_debuginfo;
1566 else
1567 lPosDebug = (cbLXFile + 0x400) & ~0x1FF; //try do some alignment.
1568
1569 /*
1570 * Go to debug info position in the file and write debug info.
1571 */
1572 if (fseek(phFile, lPosDebug, SEEK_SET) == 0)
1573 {
1574 /*
1575 * Write the HLL data to disk.
1576 */
1577 cch = write(phFile);
1578 if (cch > 0)
1579 {
1580 /*
1581 * Update exeheader.
1582 */
1583 e32.e32_debuglen = cch;
1584 e32.e32_debuginfo = lPosDebug;
1585 if (fseek(phFile, lPosLXHdr, SEEK_SET) == 0)
1586 {
1587 /*
1588 * Write the updated header to disk.
1589 */
1590 cch = fwrite(&e32, 1, sizeof(e32), phFile);
1591 if (cch == sizeof(e32))
1592 rc = NO_ERROR;
1593 else
1594 rc = ERROR_WRITE_FAULT;
1595 }
1596 else
1597 rc = ERROR_SEEK;
1598 }
1599 else
1600 {
1601 fprintf(stderr, "error - write failed with cch=%d\n", cch);
1602 rc = ERROR_WRITE_FAULT;
1603 }
1604 }
1605 else
1606 rc = ERROR_SEEK;
1607 }
1608 else
1609 {
1610 fprintf(stderr, "error - debuginfo exists\n");
1611 rc = ERROR_BAD_EXE_FORMAT;
1612 }
1613
1614 }
1615 else
1616 rc = ERROR_INVALID_EXE_SIGNATURE;
1617 }
1618 else
1619 rc = ERROR_BAD_EXE_FORMAT;
1620 }
1621 else
1622 rc = ERROR_BAD_EXE_FORMAT;
1623 }
1624 else
1625 rc = ERROR_READ_FAULT;
1626
1627 fclose(phFile);
1628 }
1629 else
1630 rc = ERROR_ACCESS_DENIED; //?
1631
1632
1633 return rc;
1634}
1635
1636
1637/**
1638 * Find the size of a file.
1639 * @returns Size of file. -1 on error.
1640 * @param phFile File handle.
1641 */
1642signed long fsize(FILE *phFile)
1643{
1644 long ipos;
1645 signed long cb;
1646
1647 if ((ipos = ftell(phFile)) < 0
1648 ||
1649 fseek(phFile, 0, SEEK_END) != 0
1650 ||
1651 (cb = ftell(phFile)) < 0
1652 ||
1653 fseek(phFile, ipos, SEEK_SET) != 0
1654 )
1655 cb = -1;
1656 return cb;
1657}
1658
1659
1660
1661#if 1
1662/**
1663 * Debugging entry point for the readLX constructor.
1664 * It reads this executable and dumps it.
1665 * @param argc Argument count.
1666 * @param argv Argument vector - only the first entry is used.
1667 */
1668void main(int argc, char **argv)
1669{
1670 kHll *pHll;
1671
1672 /* read my self */
1673 pHll = kHll::readLX(argv[0]);
1674 if (pHll)
1675 {
1676 printf("Successfully read %s\n", argv[0]);
1677 pHll->dump();
1678 }
1679 argc = argc;
1680 delete (pHll);
1681}
1682
1683#ifdef __IBMCPP__
1684#include "klist.cpp"
1685#endif
1686
1687#endif
Note: See TracBrowser for help on using the repository browser.