/* */
/* */
/* */
-/* (C) 1998-2001 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
+/* (C) 1998-2003 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
typedef struct Fragment Fragment;
struct Fragment {
- Fragment* List; /* List of all fragments */
- Fragment* Next; /* Fragment list in one segment */
+ Fragment* Next; /* Pointer to next fragment in segment */
Fragment* LineList; /* List of fragments for one src line */
FilePos Pos; /* File position for this fragment */
struct LineInfo* LI; /* Extra line info */
-/* List of all fragments */
-extern Fragment* FragList;
-extern Fragment* FragLast;
-
-
-
/* End of fragment.h */
#endif
/* */
/* */
/* */
-/* (C) 2000 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* (C) 2000-2003 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
+/* ca65 */
#include "fragment.h"
#define LINE_HEADER_LEN 24
/* One listing line as it is stored in memory */
-typedef struct ListLine_ ListLine;
-struct ListLine_ {
+typedef struct ListLine ListLine;
+struct ListLine {
ListLine* Next; /* Pointer to next line */
Fragment* FragList; /* List of fragments for this line */
Fragment* FragLast; /* Last entry in fragment list */
/* */
/* */
/* */
-/* (C) 1998-2002 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
+/* (C) 1998-2003 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
Segment* List; /* List of all segments */
Fragment* Root; /* Root of fragment list */
Fragment* Last; /* Pointer to last fragment */
+ unsigned long FragCount; /* Number of fragments */
unsigned Num; /* Segment number */
unsigned Align; /* Segment alignment */
unsigned long PC;
#define SEG(segdef, num, prev) \
- { prev, 0, 0, num, 0, 0, segdef }
+ { prev, 0, 0, 0, num, 0, 0, segdef }
/* Definitions for predefined segments */
SegDef NullSegDef = STATIC_SEGDEF_INITIALIZER (SEGNAME_NULL, SEGTYPE_ABS);
S = xmalloc (sizeof (*S));
/* Initialize it */
- S->List = 0;
- S->Root = 0;
- S->Last = 0;
- S->Num = SegmentCount++;
- S->Align = 0;
- S->PC = 0;
- S->Def = NewSegDef (Name, SegType);
+ S->List = 0;
+ S->Root = 0;
+ S->Last = 0;
+ S->FragCount = 0;
+ S->Num = SegmentCount++;
+ S->Align = 0;
+ S->PC = 0;
+ S->Def = NewSegDef (Name, SegType);
/* Insert it into the segment list */
SegmentLast->List = S;
PError (&F->Pos, ERR_RANGE);
}
} else {
- /* PC relative value */
+ /* PC relative value */
if (Val < -128 || Val > 127) {
PError (&F->Pos, ERR_RANGE);
}
{
Fragment* Frag;
unsigned LineInfoIndex;
+ unsigned long DataSize;
+ unsigned long EndPos;
- /* Write the segment name followed by the byte count in this segment */
- ObjWriteStr (Seg->Def->Name);
- ObjWrite32 (Seg->PC);
- ObjWrite8 (Seg->Align);
- ObjWrite8 (Seg->Def->Type);
+ /* Remember the file position, then write a dummy for the size of the
+ * following data
+ */
+ unsigned long SizePos = ObjGetFilePos ();
+ ObjWrite32 (0);
+
+ /* Write the segment data */
+ ObjWriteStr (Seg->Def->Name); /* Name of the segment */
+ ObjWrite32 (Seg->PC); /* Size */
+ ObjWrite8 (Seg->Align); /* Segment alignment */
+ ObjWrite8 (Seg->Def->Type); /* Type of the segment */
+ ObjWriteVar (Seg->FragCount); /* Number of fragments that follow */
/* Now walk through the fragment list for this segment and write the
* fragments.
switch (Frag->Type) {
case FRAG_LITERAL:
- ObjWrite8 (FRAG_LITERAL);
- ObjWriteVar (Frag->Len);
- ObjWriteData (Frag->V.Data, Frag->Len);
- break;
+ ObjWrite8 (FRAG_LITERAL);
+ ObjWriteVar (Frag->Len);
+ ObjWriteData (Frag->V.Data, Frag->Len);
+ break;
case FRAG_EXPR:
- switch (Frag->Len) {
- case 1: ObjWrite8 (FRAG_EXPR8); break;
- case 2: ObjWrite8 (FRAG_EXPR16); break;
- case 3: ObjWrite8 (FRAG_EXPR24); break;
- case 4: ObjWrite8 (FRAG_EXPR32); break;
- default: Internal ("Invalid fragment size: %u", Frag->Len);
- }
- WriteExpr (Frag->V.Expr);
- break;
+ switch (Frag->Len) {
+ case 1: ObjWrite8 (FRAG_EXPR8); break;
+ case 2: ObjWrite8 (FRAG_EXPR16); break;
+ case 3: ObjWrite8 (FRAG_EXPR24); break;
+ case 4: ObjWrite8 (FRAG_EXPR32); break;
+ default: Internal ("Invalid fragment size: %u", Frag->Len);
+ }
+ WriteExpr (Frag->V.Expr);
+ break;
case FRAG_SEXPR:
- switch (Frag->Len) {
- case 1: ObjWrite8 (FRAG_SEXPR8); break;
- case 2: ObjWrite8 (FRAG_SEXPR16); break;
- case 3: ObjWrite8 (FRAG_SEXPR24); break;
- case 4: ObjWrite8 (FRAG_SEXPR32); break;
- default: Internal ("Invalid fragment size: %u", Frag->Len);
- }
- WriteExpr (Frag->V.Expr);
- break;
+ switch (Frag->Len) {
+ case 1: ObjWrite8 (FRAG_SEXPR8); break;
+ case 2: ObjWrite8 (FRAG_SEXPR16); break;
+ case 3: ObjWrite8 (FRAG_SEXPR24); break;
+ case 4: ObjWrite8 (FRAG_SEXPR32); break;
+ default: Internal ("Invalid fragment size: %u", Frag->Len);
+ }
+ WriteExpr (Frag->V.Expr);
+ break;
case FRAG_FILL:
- ObjWrite8 (FRAG_FILL);
+ ObjWrite8 (FRAG_FILL);
ObjWriteVar (Frag->Len);
- break;
+ break;
default:
- Internal ("Invalid fragment type: %u", Frag->Type);
+ Internal ("Invalid fragment type: %u", Frag->Type);
}
/* Next fragment */
Frag = Frag->Next;
}
+
+ /* Calculate the size of the data, seek back and write it */
+ EndPos = ObjGetFilePos (); /* Remember where we are */
+ DataSize = EndPos - SizePos - 4; /* Don't count size itself */
+ ObjSetFilePos (SizePos); /* Seek back to the size */
+ ObjWrite32 (DataSize); /* Write the size */
+ ObjSetFilePos (EndPos); /* Seek back to the end */
}
F = xmalloc (sizeof (*F));
/* Initialize it */
- F->List = 0;
F->Next = 0;
F->LineList = 0;
F->Pos = CurPos;
F->Len = Len;
F->Type = Type;
- /* Insert it into the list of all segments */
- if (FragList == 0) {
- FragList = F;
- } else {
- FragLast->List = F;
- }
- FragLast = F;
-
- /* Insert it into the current segment */
+ /* Insert the fragment into the current segment */
if (ActiveSeg->Root) {
ActiveSeg->Last->Next = F;
ActiveSeg->Last = F;
} else {
ActiveSeg->Root = ActiveSeg->Last = F;
}
+ ++ActiveSeg->FragCount;
/* Add this fragment to the current listing line */
if (LineCur) {
+unsigned long ObjGetFilePos (void)
+/* Get the current file position */
+{
+ long Pos = ftell (F);
+ if (Pos < 0) {
+ ObjWriteError ();
+ }
+ return Pos;
+}
+
+
+
+void ObjSetFilePos (unsigned long Pos)
+/* Set the file position */
+{
+ if (fseek (F, Pos, SEEK_SET) != 0) {
+ ObjWriteError ();
+ }
+}
+
+
+
void ObjWrite8 (unsigned V)
/* Write an 8 bit value to the file */
{
void ObjClose (void);
/* Write an update header and close the object file. */
+unsigned long ObjGetFilePos (void);
+/* Get the current file position */
+
+void ObjSetFilePos (unsigned long Pos);
+/* Set the file position */
+
void ObjWrite8 (unsigned V);
/* Write an 8 bit value to the file */
/* End of objfile.h */
-
+
#endif
/* common */
#include "abend.h"
#include "chartype.h"
+#include "fname.h"
#include "xmalloc.h"
#include "cmdline.h"
/* Struct to pass the command line */
typedef struct {
- char** Vec; /* The argument vector */
- unsigned Count; /* Actual number of arguments */
- unsigned Size; /* Number of argument allocated */
+ char** Vec; /* The argument vector */
+ unsigned Count; /* Actual number of arguments */
+ unsigned Size; /* Number of argument allocated */
} CmdLine;
-static void AddArg (CmdLine* L, const char* Arg)
+static void AddArg (CmdLine* L, char* Arg)
/* Add one argument to the list */
{
if (L->Size <= L->Count) {
}
/* We have space left, add a copy of the argument */
- L->Vec [L->Count++] = xstrdup (Arg);
+ L->Vec[L->Count++] = Arg;
}
}
/* Add anything not empty to the command line */
- AddArg (L, B);
+ AddArg (L, xstrdup (B));
}
ProgName = aProgName;
} else {
/* Strip a path */
- const char* FirstArg = (*aArgVec)[0];
- ProgName = strchr (FirstArg, '\0');
- while (ProgName > FirstArg) {
- --ProgName;
- if (*ProgName == '/' || *ProgName == '\\') {
- ++ProgName;
- break;
- }
- }
+ ProgName = FindName ((*aArgVec)[0]);
if (ProgName[0] == '\0') {
/* Use the default */
ProgName = aProgName;
-
+
/* Fragment types in the object file */
#define FRAG_TYPEMASK 0x38 /* Mask the type of the fragment */
#define FRAG_BYTEMASK 0x07 /* Mask for byte count */
-#define FRAG_CHECKMASK 0xC0 /* Mask for check type */
+#define FRAG_CHECKMASK 0x40 /* Mask for check expressions */
/* Fragment types */
#define FRAG_LITERAL 0x00 /* Literal data */
#define FRAG_FILL 0x20 /* Fill bytes */
/* Fragment checks */
-#define FRAG_CHECK_NONE 0x00 /* No checks applied */
-#define FRAG_CHECK_WARN 0x40 /* Check and warn */
-#define FRAG_CHECK_ERROR 0x80 /* Check and abort */
+#define FRAG_CHECK 0x40 /* Check expressions exist */
/* common */
+#include "segdefs.h"
#include "xmalloc.h"
/* ld65 */
-Fragment* NewFragment (unsigned char Type, unsigned long Size, Section* S)
+Fragment* NewFragment (unsigned char Type, unsigned Size, Section* S)
/* Create a new fragment and insert it into the section S */
{
+ Fragment* F;
+
+ /* Calculate the size of the memory block. LitBuf is only needed if the
+ * fragment contains literal data.
+ */
+ unsigned FragSize = sizeof (Fragment) - 1;
+ if (Type == FRAG_LITERAL) {
+ FragSize += Size;
+ }
+
/* Allocate memory */
- Fragment* F = xmalloc (sizeof (Fragment) - 1 + Size);
+ F = xmalloc (FragSize);
/* Initialize the data */
F->Next = 0;
F->Expr = 0;
InitFilePos (&F->Pos);
F->LI = 0;
- F->WarnExpr = 0;
- F->ErrorExpr = 0;
+ F->Check = 0;
F->Type = Type;
/* Insert the code fragment into the section */
+/* Fragment check expression */
+typedef struct CheckExpr CheckExpr;
+struct CheckExpr {
+ struct CheckExpr* Next; /* Next check expression */
+ struct ExprNode* Expr; /* The expression itself */
+ unsigned Action; /* Action to take if the check fails */
+ unsigned Message; /* Message number */
+};
+
/* Fragment structure */
typedef struct Fragment Fragment;
struct Fragment {
Fragment* Next; /* Next fragment in list */
struct ObjData* Obj; /* Source of fragment */
- unsigned long Size; /* Size of data/expression */
+ unsigned Size; /* Size of data/expression */
struct ExprNode* Expr; /* Expression if FRAG_EXPR */
FilePos Pos; /* File position in source */
struct LineInfo* LI; /* Additional line info */
- struct ExprNode* WarnExpr; /* Print warning if expr true */
- struct ExprNode* ErrorExpr; /* Print error if expr true */
+ CheckExpr* Check; /* Single linked list of expressions */
unsigned char Type; /* Type of fragment */
unsigned char LitBuf [1]; /* Dynamically alloc'ed literal buffer */
};
-Fragment* NewFragment (unsigned char Type, unsigned long Size, struct Section* S);
+Fragment* NewFragment (unsigned char Type, unsigned Size, struct Section* S);
/* Create a new fragment and insert it into the section S */
objfile.o \
scanner.o \
segments.o \
+ spool.o \
tgtcfg.o
# -----------------------------------------------------------------------------
objfile.obj \
scanner.obj \
segments.obj \
+ spool.obj \
tgtcfg.obj
LIBS = ..\common\common.lib
O65RelocTab* R = xmalloc (sizeof (O65RelocTab));
/* Initialize the data */
- R->Size = RELOC_BLOCKSIZE;
+ R->Size = 0;
R->Fill = 0;
- R->Buf = xmalloc (RELOC_BLOCKSIZE);
+ R->Buf = 0;
/* Return the created struct */
return R;
Section* ReadSection (FILE* F, ObjData* O)
/* Read a section from a file */
{
- char* Name;
- unsigned long Size;
+ char* Name;
+ unsigned Size;
unsigned char Align;
unsigned char Type;
- Segment* S;
- Section* Sec;
-
- /* Read the name */
- Name = ReadStr (F);
-
- /* Read the size */
- Size = Read32 (F);
+ unsigned FragCount;
+ Segment* S;
+ Section* Sec;
- /* Read the alignment */
- Align = Read8 (F);
+ /* Read the segment data */
+ (void) Read32 (F); /* File size of data */
+ Name = ReadStr (F); /* Segment name */
+ Size = Read32 (F); /* Size of data */
+ Align = Read8 (F); /* Alignment */
+ Type = Read8 (F); /* Segment type */
+ FragCount = ReadVar (F); /* Number of fragments */
- /* Read the segment type */
- Type = Read8 (F);
/* Print some data */
- Print (stdout, 2, "Module `%s': Found segment `%s', size = %lu, align = %u, type = %u\n",
+ Print (stdout, 2, "Module `%s': Found segment `%s', size = %u, align = %u, type = %u\n",
GetObjFileName (O), Name, Size, Align, Type);
/* Get the segment for this section */
}
/* Start reading fragments from the file and insert them into the section . */
- while (Size) {
+ while (FragCount--) {
Fragment* Frag;
unsigned LineInfoIndex;
/* Extract the check mask from the type */
unsigned char Check = Type & FRAG_CHECKMASK;
- Type &= ~FRAG_CHECKMASK;
+ unsigned char Bytes = Type & FRAG_BYTEMASK;
+ Type &= FRAG_TYPEMASK;
/* Handle the different fragment types */
switch (Type) {
case FRAG_LITERAL:
Frag = NewFragment (Type, ReadVar (F), Sec);
+ ReadData (F, Frag->LitBuf, Frag->Size);
break;
- case FRAG_EXPR8:
- case FRAG_EXPR16:
- case FRAG_EXPR24:
- case FRAG_EXPR32:
- case FRAG_SEXPR8:
- case FRAG_SEXPR16:
- case FRAG_SEXPR24:
- case FRAG_SEXPR32:
- Frag = NewFragment (Type & FRAG_TYPEMASK, Type & FRAG_BYTEMASK, Sec);
+ case FRAG_EXPR:
+ case FRAG_SEXPR:
+ Frag = NewFragment (Type, Bytes, Sec);
+ Frag->Expr = ReadExpr (F, O);
break;
case FRAG_FILL:
return 0;
}
- /* Now read the fragment data */
- switch (Frag->Type) {
+ /* A list of check expressions may follow */
+ if (Check) {
- case FRAG_LITERAL:
- /* Literal data */
- ReadData (F, Frag->LitBuf, Frag->Size);
- break;
+ /* Read the number of expressions that follow */
+ unsigned Count = ReadVar (F);
- case FRAG_EXPR:
- case FRAG_SEXPR:
- /* An expression */
- Frag->Expr = ReadExpr (F, O);
- break;
-
- }
-
- /* A check expression may follow */
- if (Check & FRAG_CHECK_WARN) {
- Frag->WarnExpr = ReadExpr (F, O);
- }
- if (Check & FRAG_CHECK_ERROR) {
- Frag->ErrorExpr = ReadExpr (F, O);
+ /* Read the expressions */
+ CheckExpr* Last = 0;
+ while (Count--) {
+ /* ### */
+ }
}
/* Read the file position of the fragment */
/* Remember the module we had this fragment from */
Frag->Obj = O;
-
- /* Next one */
- CHECK (Size >= Frag->Size);
- Size -= Frag->Size;
}
/* Return the section */
switch (F->Type) {
case FRAG_LITERAL:
- printf (" Literal (%lu bytes):", F->Size);
+ printf (" Literal (%u bytes):", F->Size);
Count = F->Size;
Data = F->LitBuf;
I = 100;
break;
case FRAG_EXPR:
- printf (" Expression (%lu bytes):\n", F->Size);
+ printf (" Expression (%u bytes):\n", F->Size);
printf (" ");
DumpExpr (F->Expr);
break;
case FRAG_SEXPR:
- printf (" Signed expression (%lu bytes):\n", F->Size);
+ printf (" Signed expression (%u bytes):\n", F->Size);
printf (" ");
DumpExpr (F->Expr);
break;
case FRAG_FILL:
- printf (" Empty space (%lu bytes)\n", F->Size);
+ printf (" Empty space (%u bytes)\n", F->Size);
break;
-
+
default:
Internal ("Invalid fragment type: %02X", F->Type);
}
/* Loop over all fragments in this section */
Frag = Sec->FragRoot;
while (Frag) {
-
+
/* Do fragment alignment checks */
--- /dev/null
+/*****************************************************************************/
+/* */
+/* spool.c */
+/* */
+/* Id and message pool for the ld65 linker */
+/* */
+/* */
+/* */
+/* (C) 2003 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
+/* */
+/* */
+/* This software is provided 'as-is', without any expressed or implied */
+/* warranty. In no event will the authors be held liable for any damages */
+/* arising from the use of this software. */
+/* */
+/* Permission is granted to anyone to use this software for any purpose, */
+/* including commercial applications, and to alter it and redistribute it */
+/* freely, subject to the following restrictions: */
+/* */
+/* 1. The origin of this software must not be misrepresented; you must not */
+/* claim that you wrote the original software. If you use this software */
+/* in a product, an acknowledgment in the product documentation would be */
+/* appreciated but is not required. */
+/* 2. Altered source versions must be plainly marked as such, and must not */
+/* be misrepresented as being the original software. */
+/* 3. This notice may not be removed or altered from any source */
+/* distribution. */
+/* */
+/*****************************************************************************/
+
+
+
+/* ld65 */
+#include "spool.h"
+
+
+
+/*****************************************************************************/
+/* Data */
+/*****************************************************************************/
+
+
+
+StringPool StrPool = STATIC_STRINGPOOL_INITIALIZER;
+
+
+
+/*****************************************************************************/
+/* Code */
+/*****************************************************************************/
+
+
+
--- /dev/null
+/*****************************************************************************/
+/* */
+/* spool.h */
+/* */
+/* Id and message pool for the ld65 linker */
+/* */
+/* */
+/* */
+/* (C) 2003 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
+/* */
+/* */
+/* This software is provided 'as-is', without any expressed or implied */
+/* warranty. In no event will the authors be held liable for any damages */
+/* arising from the use of this software. */
+/* */
+/* Permission is granted to anyone to use this software for any purpose, */
+/* including commercial applications, and to alter it and redistribute it */
+/* freely, subject to the following restrictions: */
+/* */
+/* 1. The origin of this software must not be misrepresented; you must not */
+/* claim that you wrote the original software. If you use this software */
+/* in a product, an acknowledgment in the product documentation would be */
+/* appreciated but is not required. */
+/* 2. Altered source versions must be plainly marked as such, and must not */
+/* be misrepresented as being the original software. */
+/* 3. This notice may not be removed or altered from any source */
+/* distribution. */
+/* */
+/*****************************************************************************/
+
+
+
+#ifndef SPOOL_H
+#define SPOOL_H
+
+
+
+/* common */
+#include "strpool.h"
+
+
+
+/*****************************************************************************/
+/* Data */
+/*****************************************************************************/
+
+
+
+extern StringPool StrPool;
+
+
+
+/*****************************************************************************/
+/* Code */
+/*****************************************************************************/
+
+
+
+#if defined(HAVE_INLINE)
+INLINE unsigned GetStringId (const char* S)
+/* Return the id of the given string */
+{
+ return SP_Add (&StrPool, S);
+}
+#else
+# define GetStringId(S) SP_Add (&StrPool, (S))
+#endif
+
+
+
+/* End of spool.h */
+
+#endif
+
+
+
+
/* Not a leaf node */
SkipExpr (F);
SkipExpr (F);
-
}
}
-static unsigned SkipFragment (FILE* F)
-/* Skip a fragment from the given file and return the size */
-{
- FilePos Pos;
- unsigned long Size;
-
- /* Read the fragment type */
- unsigned char Type = Read8 (F);
-
- /* Extract the check mask */
- unsigned char Check = Type & FRAG_CHECKMASK;
- Type &= ~FRAG_CHECKMASK;
-
- /* Handle the different fragment types */
- switch (Type) {
-
- case FRAG_LITERAL:
- Size = ReadVar (F);
- break;
-
- case FRAG_EXPR8:
- case FRAG_EXPR16:
- case FRAG_EXPR24:
- case FRAG_EXPR32:
- case FRAG_SEXPR8:
- case FRAG_SEXPR16:
- case FRAG_SEXPR24:
- case FRAG_SEXPR32:
- Size = Type & FRAG_BYTEMASK;
- break;
-
- case FRAG_FILL:
- Size = ReadVar (F);
- break;
-
- default:
- Error ("Unknown fragment type: 0x%02X", Type);
- /* NOTREACHED */
- return 0;
- }
-
-
-
- /* Now read the fragment data */
- switch (Type & FRAG_TYPEMASK) {
-
- case FRAG_LITERAL:
- /* Literal data */
- FileSeek (F, ftell (F) + Size);
- break;
-
- case FRAG_EXPR:
- case FRAG_SEXPR:
- /* An expression */
- SkipExpr (F);
- break;
-
- }
-
- /* Skip the check expression if we have one */
- if (Check & FRAG_CHECK_WARN) {
- SkipExpr (F);
- }
- if (Check & FRAG_CHECK_ERROR) {
- SkipExpr (F);
- }
-
- /* Skip the file position of the fragment */
- ReadFilePos (F, &Pos);
-
- /* Skip the additional line info */
- (void) ReadVar (F);
-
- /* Return the size */
- return Size;
-}
-
-
-
static const char* GetExportFlags (unsigned Flags, const unsigned char* ConDes)
/* Get the export flags as a (static) string */
{
ObjHeader H;
/* Seek to the header position */
- FileSeek (F, Offset);
+ FileSetPos (F, Offset);
/* Read the header */
ReadObjHeader (F, &H);
unsigned I;
/* Seek to the header position and read the header */
- FileSeek (F, Offset);
+ FileSetPos (F, Offset);
ReadObjHeader (F, &H);
/* Seek to the start of the string pool and read it */
- FileSeek (F, Offset + H.StrPoolOffs);
+ FileSetPos (F, Offset + H.StrPoolOffs);
ReadStrPool (F, &StrPool);
/* Seek to the start of the options */
- FileSeek (F, Offset + H.OptionOffs);
+ FileSetPos (F, Offset + H.OptionOffs);
/* Output a header */
printf (" Options:\n");
/* Read and print all options */
for (I = 0; I < Count; ++I) {
- const char* ArgStr;
+ const char* ArgStr;
unsigned ArgLen;
/* Read the type of the option and the value */
unsigned I;
/* Seek to the header position and read the header */
- FileSeek (F, Offset);
+ FileSetPos (F, Offset);
ReadObjHeader (F, &H);
/* Seek to the start of the string pool and read it */
- FileSeek (F, Offset + H.StrPoolOffs);
+ FileSetPos (F, Offset + H.StrPoolOffs);
ReadStrPool (F, &StrPool);
/* Seek to the start of the source files */
- FileSeek (F, Offset + H.FileOffs);
+ FileSetPos (F, Offset + H.FileOffs);
/* Output a header */
printf (" Files:\n");
Collection StrPool = AUTO_COLLECTION_INITIALIZER;
unsigned Count;
unsigned I;
- unsigned FragCount;
/* Seek to the header position and read the header */
- FileSeek (F, Offset);
+ FileSetPos (F, Offset);
ReadObjHeader (F, &H);
/* Seek to the start of the string pool and read it */
- FileSeek (F, Offset + H.StrPoolOffs);
+ FileSetPos (F, Offset + H.StrPoolOffs);
ReadStrPool (F, &StrPool);
/* Seek to the start of the segments */
- FileSeek (F, Offset + H.SegOffs);
+ FileSetPos (F, Offset + H.SegOffs);
/* Output a header */
printf (" Segments:\n");
for (I = 0; I < Count; ++I) {
/* Read the data for one segments */
- char* Name = ReadStr (F);
- unsigned Len = strlen (Name);
- unsigned long Size = Read32 (F);
- unsigned Align = (1U << Read8 (F));
- unsigned char Type = Read8 (F);
+ unsigned long DataSize = Read32 (F);
+ unsigned long NextSeg = ftell (F) + DataSize;
+ char* Name = ReadStr (F);
+ unsigned Len = strlen (Name);
+ unsigned long Size = Read32 (F);
+ unsigned Align = (1U << Read8 (F));
+ unsigned char Type = Read8 (F);
+ unsigned long FragCount = ReadVar (F);
/* Get the description for the type */
const char* TypeDesc;
case SEGTYPE_ABS: TypeDesc = "SEGTYPE_ABS"; break;
case SEGTYPE_ZP: TypeDesc = "SEGTYPE_ZP"; break;
case SEGTYPE_FAR: TypeDesc = "SEGTYPE_FAR"; break;
- default: TypeDesc = "SEGTYPE_UNKNOWN"; break;
+ default: TypeDesc = "SEGTYPE_UNKNOWN"; break;
}
/* Print the header */
printf (" Size:%26lu\n", Size);
printf (" Alignment:%21u\n", Align);
printf (" Type:%22s0x%02X (%s)\n", "", Type, TypeDesc);
+ printf (" Fragment count:%16lu\n", FragCount);
/* Free the Name */
xfree (Name);
- /* Skip the fragments for this segment, counting them */
- FragCount = 0;
- while (Size > 0) {
- unsigned FragSize = SkipFragment (F);
- if (FragSize > Size) {
- /* OOPS - file data invalid */
- Error ("Invalid fragment data - file corrupt!");
- }
- Size -= FragSize;
- ++FragCount;
- }
-
- /* Print the fragment count */
- printf (" Fragment count:%16u\n", FragCount);
+ /* Seek to the end of the segment data (start of next) */
+ FileSetPos (F, NextSeg);
}
/* Destroy the string pool */
FilePos Pos;
/* Seek to the header position and read the header */
- FileSeek (F, Offset);
+ FileSetPos (F, Offset);
ReadObjHeader (F, &H);
/* Seek to the start of the string pool and read it */
- FileSeek (F, Offset + H.StrPoolOffs);
+ FileSetPos (F, Offset + H.StrPoolOffs);
ReadStrPool (F, &StrPool);
/* Seek to the start of the imports */
- FileSeek (F, Offset + H.ImportOffs);
+ FileSetPos (F, Offset + H.ImportOffs);
/* Output a header */
printf (" Imports:\n");
FilePos Pos;
/* Seek to the header position and read the header */
- FileSeek (F, Offset);
+ FileSetPos (F, Offset);
ReadObjHeader (F, &H);
/* Seek to the start of the string pool and read it */
- FileSeek (F, Offset + H.StrPoolOffs);
+ FileSetPos (F, Offset + H.StrPoolOffs);
ReadStrPool (F, &StrPool);
/* Seek to the start of the exports */
- FileSeek (F, Offset + H.ExportOffs);
+ FileSetPos (F, Offset + H.ExportOffs);
/* Output a header */
printf (" Exports:\n");
FilePos Pos;
/* Seek to the header position and read the header */
- FileSeek (F, Offset);
+ FileSetPos (F, Offset);
ReadObjHeader (F, &H);
/* Seek to the start of the string pool and read it */
- FileSeek (F, Offset + H.StrPoolOffs);
+ FileSetPos (F, Offset + H.StrPoolOffs);
ReadStrPool (F, &StrPool);
/* Seek to the start of the debug syms */
- FileSeek (F, Offset + H.DbgSymOffs);
+ FileSetPos (F, Offset + H.DbgSymOffs);
/* Output a header */
printf (" Debug symbols:\n");
unsigned I;
/* Seek to the header position and read the header */
- FileSeek (F, Offset);
+ FileSetPos (F, Offset);
ReadObjHeader (F, &H);
/* Seek to the start of the string pool and read it */
- FileSeek (F, Offset + H.StrPoolOffs);
+ FileSetPos (F, Offset + H.StrPoolOffs);
ReadStrPool (F, &StrPool);
/* Seek to the start of line infos */
- FileSeek (F, Offset + H.LineInfoOffs);
+ FileSetPos (F, Offset + H.LineInfoOffs);
/* Output a header */
printf (" Line info:\n");
unsigned Count;
/* Seek to the header position and read the header */
- FileSeek (F, Offset);
+ FileSetPos (F, Offset);
ReadObjHeader (F, &H);
/* Seek to the start of the string pool and read it */
- FileSeek (F, Offset + H.StrPoolOffs);
+ FileSetPos (F, Offset + H.StrPoolOffs);
ReadStrPool (F, &StrPool);
/* Seek to the start of the segments */
- FileSeek (F, Offset + H.SegOffs);
+ FileSetPos (F, Offset + H.SegOffs);
/* Output a header */
printf (" Segment sizes:\n");
while (Count--) {
/* Read the data for one segments */
- char* Name = ReadStr (F);
- unsigned Len = strlen (Name);
- unsigned long Size = Read32 (F);
+ unsigned long DataSize = Read32 (F);
+ unsigned long NextSeg = ftell (F) + DataSize;
+ char* Name = ReadStr (F);
+ unsigned Len = strlen (Name);
+ unsigned long Size = Read32 (F);
- /* Skip alignment and type */
+ /* Skip alignment, type and fragment count */
(void) Read8 (F);
(void) Read8 (F);
+ (void) ReadVar (F);
/* Print the size for this segment */
printf (" %s:%*s%6lu\n", Name, 24-Len, "", Size);
/* Free the Name */
xfree (Name);
- /* Skip the fragments for this segment, counting them */
- while (Size > 0) {
- unsigned FragSize = SkipFragment (F);
- if (FragSize > Size) {
- /* OOPS - file data invalid */
- Error ("Invalid fragment data - file corrupt!");
- }
- Size -= FragSize;
- }
- }
+ /* Seek to the end of the segment data (start of next) */
+ FileSetPos (F, NextSeg);
+ }
/* Destroy the string pool */
DestroyStrPool (&StrPool);
-void FileSeek (FILE* F, unsigned long Pos)
+void FileSetPos (FILE* F, unsigned long Pos)
/* Seek to the given absolute position, fail on errors */
{
if (fseek (F, Pos, SEEK_SET) != 0) {
+unsigned long FileGetPos (FILE* F)
+/* Return the current file position, fail on errors */
+{
+ long Pos = ftell (F);
+ if (Pos < 0) {
+ Error ("Error in ftell: %s", strerror (errno));
+ }
+ return Pos;
+}
+
+
+
unsigned Read8 (FILE* F)
/* Read an 8 bit value from the file */
{
-void FileSeek (FILE* F, unsigned long Pos);
+void FileSetPos (FILE* F, unsigned long Pos);
/* Seek to the given absolute position, fail on errors */
+unsigned long FileGetPos (FILE* F);
+/* Return the current file position, fail on errors */
+
unsigned Read8 (FILE* F);
/* Read an 8 bit value from the file */