X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fod65%2Fdump.c;h=208c4bfbced706729d9211dc92495e43f471a528;hb=2fa9b6e5acbfea981887dd2824bc2e96e9ef6cfd;hp=b9bf7f1224b3b647b662255b5b4be0ca9e6abfad;hpb=097a01094eedd3b030c2c7a26ddc2ac5067ead28;p=cc65 diff --git a/src/od65/dump.c b/src/od65/dump.c index b9bf7f122..208c4bfbc 100644 --- a/src/od65/dump.c +++ b/src/od65/dump.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2000 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ +/* (C) 2002-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 */ @@ -33,9 +33,13 @@ +#include #include /* common */ +#include "addrsize.h" +#include "cddefs.h" +#include "coll.h" #include "exprdefs.h" #include "filepos.h" #include "objdefs.h" @@ -52,11 +56,39 @@ /*****************************************************************************/ -/* Code */ +/* Code */ /*****************************************************************************/ +static void DestroyStrPool (Collection* C) +/* Free all strings in the given pool plus the item pointers. Note: The + * collection may not be reused later. + */ +{ + unsigned I; + for (I = 0; I < CollCount (C); ++I) { + xfree (CollAtUnchecked (C, I)); + } + DoneCollection (C); +} + + + +static const char* GetString (const Collection* C, unsigned Index) +/* Get a string from a collection. In fact, this function calls CollConstAt, + * but will print a somewhat more readable error message if the index is out + * of bounds. + */ +{ + if (Index >= CollCount (C)) { + Error ("Invalid string index (%u) - file corrupt!", Index); + } + return CollConstAt (C, Index); +} + + + static void DumpObjHeaderSection (const char* Name, unsigned long Offset, unsigned long Size) @@ -107,10 +139,10 @@ static void SkipExpr (FILE* F) case EXPR_SYMBOL: /* Read the import number */ - (void) Read16 (F); + (void) ReadVar (F); break; - case EXPR_SEGMENT: + case EXPR_SECTION: /* Read the segment number */ (void) Read8 (F); break; @@ -125,72 +157,45 @@ static void SkipExpr (FILE* F) /* Not a leaf node */ SkipExpr (F); SkipExpr (F); - } } -static unsigned SkipFragment (FILE* F) -/* Skip a fragment from the given file and return the size */ +static const char* GetExportFlags (unsigned Flags, const unsigned char* ConDes) +/* Get the export flags as a (static) string */ { - FilePos Pos; - unsigned long Size; - - /* Read the fragment type */ - unsigned char Type = Read8 (F); - - /* 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; - } + /* Static buffer */ + static char TypeDesc[256]; + static char* T; + unsigned Count; + unsigned I; - - /* 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; - + /* Type of expression */ + TypeDesc[0] = '\0'; + switch (Flags & EXP_MASK_VAL) { + case EXP_CONST: strcat (TypeDesc, "EXP_CONST"); break; + case EXP_EXPR: strcat (TypeDesc, "EXP_EXPR"); break; } - /* Skip the file position of the fragment */ - ReadFilePos (F, &Pos); + /* Constructor/destructor declarations */ + T = TypeDesc + strlen (TypeDesc); + Count = GET_EXP_CONDES_COUNT (Flags); + if (Count > 0 && ConDes) { + T += sprintf (T, ",EXP_CONDES="); + for (I = 0; I < Count; ++I) { + unsigned Type = CD_GET_TYPE (ConDes[I]); + unsigned Prio = CD_GET_PRIO (ConDes[I]); + if (I > 0) { + *T++ = ','; + } + T += sprintf (T, "[%u,%u]", Type, Prio); + } + } - /* Return the size */ - return Size; + /* Return the result */ + return TypeDesc; } @@ -201,7 +206,7 @@ void DumpObjHeader (FILE* F, unsigned long Offset) ObjHeader H; /* Seek to the header position */ - FileSeek (F, Offset); + FileSetPos (F, Offset); /* Read the header */ ReadObjHeader (F, &H); @@ -241,6 +246,12 @@ void DumpObjHeader (FILE* F, unsigned long Offset) /* Debug symbols */ DumpObjHeaderSection ("Debug symbols", H.DbgSymOffs, H.DbgSymSize); + + /* Line infos */ + DumpObjHeaderSection ("Line infos", H.LineInfoOffs, H.LineInfoSize); + + /* String pool */ + DumpObjHeaderSection ("String pool", H.StrPoolOffs, H.StrPoolSize); } @@ -248,18 +259,21 @@ void DumpObjHeader (FILE* F, unsigned long Offset) void DumpObjOptions (FILE* F, unsigned long Offset) /* Dump the file options */ { - ObjHeader H; - unsigned Count; - unsigned I; + ObjHeader H; + Collection StrPool = AUTO_COLLECTION_INITIALIZER; + unsigned Count; + unsigned I; - /* Seek to the header position */ - FileSeek (F, Offset); - - /* Read the header */ + /* Seek to the header position and read the header */ + FileSetPos (F, Offset); ReadObjHeader (F, &H); + /* Seek to the start of the string pool and read it */ + 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"); @@ -271,49 +285,47 @@ void DumpObjOptions (FILE* F, unsigned long Offset) /* Read and print all options */ for (I = 0; I < Count; ++I) { - unsigned long ArgNum; - char* ArgStr; - unsigned ArgLen; + const char* ArgStr; + unsigned ArgLen; - /* Read the type of the option */ - unsigned char Type = Read8 (F); + /* Read the type of the option and the value */ + unsigned char Type = Read8 (F); + unsigned long Val = ReadVar (F); /* Get the type of the argument */ - unsigned char ArgType = Type & OPT_ARGMASK; + unsigned char ArgType = Type & OPT_ARGMASK; - /* Determine which option follows */ - const char* TypeDesc; - switch (Type) { + /* Determine which option follows */ + const char* TypeDesc; + switch (Type) { case OPT_COMMENT: TypeDesc = "OPT_COMMENT"; break; - case OPT_AUTHOR: TypeDesc = "OPT_AUTHOR"; break; - case OPT_TRANSLATOR:TypeDesc = "OPT_TRANSLATOR"; break; - case OPT_COMPILER: TypeDesc = "OPT_COMPILER"; break; - case OPT_OS: TypeDesc = "OPT_OS"; break; - case OPT_DATETIME: TypeDesc = "OPT_DATETIME"; break; - default: TypeDesc = "OPT_UNKNOWN"; break; - } - - /* Print the header */ - printf (" Index:%27u\n", I); - - /* Print the data */ - printf (" Type:%22s0x%02X (%s)\n", "", Type, TypeDesc); - switch (ArgType) { - - case OPT_ARGSTR: - ArgStr = ReadStr (F); - ArgLen = strlen (ArgStr); - printf (" Data:%*s\"%s\"\n", 24-ArgLen, "", ArgStr); - xfree (ArgStr); - break; - - case OPT_ARGNUM: - ArgNum = Read32 (F); - printf (" Data:%26lu", ArgNum); - if (Type == OPT_DATETIME) { - /* Print the time as a string */ - printf (" (%s)", TimeToStr (ArgNum)); - } + case OPT_AUTHOR: TypeDesc = "OPT_AUTHOR"; break; + case OPT_TRANSLATOR:TypeDesc = "OPT_TRANSLATOR"; break; + case OPT_COMPILER: TypeDesc = "OPT_COMPILER"; break; + case OPT_OS: TypeDesc = "OPT_OS"; break; + case OPT_DATETIME: TypeDesc = "OPT_DATETIME"; break; + default: TypeDesc = "OPT_UNKNOWN"; break; + } + + /* Print the header */ + printf (" Index:%27u\n", I); + + /* Print the data */ + printf (" Type:%22s0x%02X (%s)\n", "", Type, TypeDesc); + switch (ArgType) { + + case OPT_ARGSTR: + ArgStr = GetString (&StrPool, Val); + ArgLen = strlen (ArgStr); + printf (" Data:%*s\"%s\"\n", 24-ArgLen, "", ArgStr); + break; + + case OPT_ARGNUM: + printf (" Data:%26lu", Val); + if (Type == OPT_DATETIME) { + /* Print the time as a string */ + printf (" (%s)", TimeToStr (Val)); + } printf ("\n"); break; @@ -325,6 +337,9 @@ void DumpObjOptions (FILE* F, unsigned long Offset) break; } } + + /* Destroy the string pool */ + DestroyStrPool (&StrPool); } @@ -332,18 +347,21 @@ void DumpObjOptions (FILE* F, unsigned long Offset) void DumpObjFiles (FILE* F, unsigned long Offset) /* Dump the source files */ { - ObjHeader H; - unsigned Count; - unsigned I; + ObjHeader H; + Collection StrPool = AUTO_COLLECTION_INITIALIZER; + unsigned Count; + unsigned I; - /* Seek to the header position */ - FileSeek (F, Offset); - - /* Read the header */ + /* Seek to the header position and read the header */ + FileSetPos (F, Offset); ReadObjHeader (F, &H); - /* Seek to the start of the options */ - FileSeek (F, Offset + H.FileOffs); + /* Seek to the start of the string pool and read it */ + FileSetPos (F, Offset + H.StrPoolOffs); + ReadStrPool (F, &StrPool); + + /* Seek to the start of the source files */ + FileSetPos (F, Offset + H.FileOffs); /* Output a header */ printf (" Files:\n"); @@ -356,9 +374,9 @@ void DumpObjFiles (FILE* F, unsigned long Offset) for (I = 0; I < Count; ++I) { /* Read the data for one file */ + const char* Name = GetString (&StrPool, ReadVar (F)); unsigned long MTime = Read32 (F); unsigned long Size = Read32 (F); - char* Name = ReadStr (F); unsigned Len = strlen (Name); /* Print the header */ @@ -368,10 +386,10 @@ void DumpObjFiles (FILE* F, unsigned long Offset) printf (" Name:%*s\"%s\"\n", 24-Len, "", Name); printf (" Size:%26lu\n", Size); printf (" Modification time:%13lu (%s)\n", MTime, TimeToStr (MTime)); - - /* Free the Name */ - xfree (Name); } + + /* Destroy the string pool */ + DestroyStrPool (&StrPool); } @@ -379,19 +397,21 @@ void DumpObjFiles (FILE* F, unsigned long Offset) void DumpObjSegments (FILE* F, unsigned long Offset) /* Dump the segments in the object file */ { - ObjHeader H; - unsigned Count; - unsigned I; - unsigned FragCount; - - /* Seek to the header position */ - FileSeek (F, Offset); + ObjHeader H; + Collection StrPool = AUTO_COLLECTION_INITIALIZER; + unsigned Count; + unsigned I; - /* Read the header */ + /* Seek to the header position and read the header */ + FileSetPos (F, Offset); ReadObjHeader (F, &H); - /* Seek to the start of the options */ - FileSeek (F, Offset + H.SegOffs); + /* Seek to the start of the string pool and read it */ + FileSetPos (F, Offset + H.StrPoolOffs); + ReadStrPool (F, &StrPool); + + /* Seek to the start of the segments */ + FileSetPos (F, Offset + H.SegOffs); /* Output a header */ printf (" Segments:\n"); @@ -404,21 +424,14 @@ void DumpObjSegments (FILE* F, unsigned long Offset) 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); - - /* Get the description for the type */ - const char* TypeDesc; - switch (Type) { - case SEGTYPE_DEFAULT: TypeDesc = "SEGTYPE_DEFAULT"; break; - 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; - } + unsigned long DataSize = Read32 (F); + unsigned long NextSeg = ftell (F) + DataSize; + const char* Name = GetString (&StrPool, ReadVar (F)); + unsigned Len = strlen (Name); + unsigned long Size = Read32 (F); + unsigned Align = (1U << Read8 (F)); + unsigned char AddrSize = Read8 (F); + unsigned long FragCount = ReadVar (F); /* Print the header */ printf (" Index:%27u\n", I); @@ -427,26 +440,16 @@ void DumpObjSegments (FILE* F, unsigned long Offset) printf (" Name:%*s\"%s\"\n", 24-Len, "", Name); printf (" Size:%26lu\n", Size); printf (" Alignment:%21u\n", Align); - printf (" Type:%22s0x%02X (%s)\n", "", Type, TypeDesc); - - /* 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; - } + printf (" Address size:%14s0x%02X (%s)\n", "", AddrSize, + AddrSizeToStr (AddrSize)); + printf (" Fragment count:%16lu\n", 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 */ + DestroyStrPool (&StrPool); } @@ -454,19 +457,22 @@ void DumpObjSegments (FILE* F, unsigned long Offset) void DumpObjImports (FILE* F, unsigned long Offset) /* Dump the imports in the object file */ { - ObjHeader H; - unsigned Count; - unsigned I; - FilePos Pos; - - /* Seek to the header position */ - FileSeek (F, Offset); - - /* Read the header */ + ObjHeader H; + Collection StrPool = AUTO_COLLECTION_INITIALIZER; + unsigned Count; + unsigned I; + FilePos Pos; + + /* Seek to the header position and read the header */ + FileSetPos (F, Offset); ReadObjHeader (F, &H); - /* Seek to the start of the options */ - FileSeek (F, Offset + H.ImportOffs); + /* Seek to the start of the string pool and read it */ + FileSetPos (F, Offset + H.StrPoolOffs); + ReadStrPool (F, &StrPool); + + /* Seek to the start of the imports */ + FileSetPos (F, Offset + H.ImportOffs); /* Output a header */ printf (" Imports:\n"); @@ -478,31 +484,23 @@ void DumpObjImports (FILE* F, unsigned long Offset) /* Read and print all imports */ for (I = 0; I < Count; ++I) { - const char* TypeDesc; - /* Read the data for one import */ - unsigned char Type = Read8 (F); - char* Name = ReadStr (F); - unsigned Len = strlen (Name); + unsigned char AddrSize = Read8 (F); + const char* Name = GetString (&StrPool, ReadVar (F)); + unsigned Len = strlen (Name); ReadFilePos (F, &Pos); - /* Get a description for the type */ - switch (Type) { - case IMP_ZP: TypeDesc = "IMP_ZP"; break; - case IMP_ABS: TypeDesc = "IMP_ABS"; break; - default: TypeDesc = "IMP_UNKNOWN"; break; - } - /* Print the header */ printf (" Index:%27u\n", I); /* Print the data */ - printf (" Type:%22s0x%02X (%s)\n", "", Type, TypeDesc); + printf (" Address size:%14s0x%02X (%s)\n", "", AddrSize, + AddrSizeToStr (AddrSize)); printf (" Name:%*s\"%s\"\n", 24-Len, "", Name); - - /* Free the Name */ - xfree (Name); } + + /* Destroy the string pool */ + DestroyStrPool (&StrPool); } @@ -510,19 +508,22 @@ void DumpObjImports (FILE* F, unsigned long Offset) void DumpObjExports (FILE* F, unsigned long Offset) /* Dump the exports in the object file */ { - ObjHeader H; - unsigned Count; - unsigned I; - FilePos Pos; - - /* Seek to the header position */ - FileSeek (F, Offset); - - /* Read the header */ + ObjHeader H; + Collection StrPool = AUTO_COLLECTION_INITIALIZER; + unsigned Count; + unsigned I; + FilePos Pos; + + /* Seek to the header position and read the header */ + FileSetPos (F, Offset); ReadObjHeader (F, &H); - /* Seek to the start of the options */ - FileSeek (F, Offset + H.ExportOffs); + /* Seek to the start of the string pool and read it */ + FileSetPos (F, Offset + H.StrPoolOffs); + ReadStrPool (F, &StrPool); + + /* Seek to the start of the exports */ + FileSetPos (F, Offset + H.ExportOffs); /* Output a header */ printf (" Exports:\n"); @@ -535,14 +536,19 @@ void DumpObjExports (FILE* F, unsigned long Offset) for (I = 0; I < Count; ++I) { unsigned long Value = 0; - int HaveValue; - const char* TypeDesc; + int HaveValue; + unsigned char ConDes [CD_TYPE_COUNT]; + const char* Name; + unsigned Len; + /* Read the data for one export */ - unsigned char Type = Read8 (F); - char* Name = ReadStr (F); - unsigned Len = strlen (Name); - if (Type & EXP_EXPR) { + unsigned char Type = Read8 (F); + unsigned char AddrSize = Read8 (F); + ReadData (F, ConDes, GET_EXP_CONDES_COUNT (Type)); + Name = GetString (&StrPool, ReadVar (F)); + Len = strlen (Name); + if (IS_EXP_EXPR (Type)) { SkipExpr (F); HaveValue = 0; } else { @@ -551,28 +557,21 @@ void DumpObjExports (FILE* F, unsigned long Offset) } ReadFilePos (F, &Pos); - /* Get a description for the type */ - switch (Type) { - case EXP_ABS|EXP_CONST: TypeDesc = "EXP_ABS,EXP_CONST"; break; - case EXP_ZP|EXP_CONST: TypeDesc = "EXP_ZP,EXP_CONST"; break; - case EXP_ABS|EXP_EXPR: TypeDesc = "EXP_ABS,EXP_EXPR"; break; - case EXP_ZP|EXP_EXPR: TypeDesc = "EXP_ZP,EXP_EXPR"; break; - default: TypeDesc = "EXP_UNKNOWN"; break; - } - /* Print the header */ printf (" Index:%27u\n", I); /* Print the data */ - printf (" Type:%22s0x%02X (%s)\n", "", Type, TypeDesc); + printf (" Type:%22s0x%02X (%s)\n", "", Type, GetExportFlags (Type, ConDes)); + printf (" Address size:%14s0x%02X (%s)\n", "", AddrSize, + AddrSizeToStr (AddrSize)); printf (" Name:%*s\"%s\"\n", 24-Len, "", Name); if (HaveValue) { printf (" Value:%15s0x%08lX (%lu)\n", "", Value, Value); } - - /* Free the Name */ - xfree (Name); } + + /* Destroy the string pool */ + DestroyStrPool (&StrPool); } @@ -580,19 +579,22 @@ void DumpObjExports (FILE* F, unsigned long Offset) void DumpObjDbgSyms (FILE* F, unsigned long Offset) /* Dump the debug symbols from an object file */ { - ObjHeader H; - unsigned Count; - unsigned I; - FilePos Pos; - - /* Seek to the header position */ - FileSeek (F, Offset); - - /* Read the header */ + ObjHeader H; + Collection StrPool = AUTO_COLLECTION_INITIALIZER; + unsigned Count; + unsigned I; + FilePos Pos; + + /* Seek to the header position and read the header */ + FileSetPos (F, Offset); ReadObjHeader (F, &H); - /* Seek to the start of the options */ - FileSeek (F, Offset + H.DbgSymOffs); + /* Seek to the start of the string pool and read it */ + FileSetPos (F, Offset + H.StrPoolOffs); + ReadStrPool (F, &StrPool); + + /* Seek to the start of the debug syms */ + FileSetPos (F, Offset + H.DbgSymOffs); /* Output a header */ printf (" Debug symbols:\n"); @@ -612,14 +614,14 @@ void DumpObjDbgSyms (FILE* F, unsigned long Offset) for (I = 0; I < Count; ++I) { unsigned long Value = 0; - int HaveValue; - const char* TypeDesc; + int HaveValue; /* Read the data for one symbol */ - unsigned char Type = Read8 (F); - char* Name = ReadStr (F); - unsigned Len = strlen (Name); - if (Type & EXP_EXPR) { + unsigned char Type = Read8 (F); + unsigned char AddrSize = Read8 (F); + const char* Name = GetString (&StrPool, ReadVar (F)); + unsigned Len = strlen (Name); + if (IS_EXP_EXPR (Type)) { SkipExpr (F); HaveValue = 0; } else { @@ -628,30 +630,130 @@ void DumpObjDbgSyms (FILE* F, unsigned long Offset) } ReadFilePos (F, &Pos); - /* Get a description for the type */ - switch (Type) { - case EXP_ABS|EXP_CONST: TypeDesc = "EXP_ABS,EXP_CONST"; break; - case EXP_ZP|EXP_CONST: TypeDesc = "EXP_ZP,EXP_CONST"; break; - case EXP_ABS|EXP_EXPR: TypeDesc = "EXP_ABS,EXP_EXPR"; break; - case EXP_ZP|EXP_EXPR: TypeDesc = "EXP_ZP,EXP_EXPR"; break; - default: TypeDesc = "EXP_UNKNOWN"; break; - } - /* Print the header */ printf (" Index:%27u\n", I); /* Print the data */ - printf (" Type:%22s0x%02X (%s)\n", "", Type, TypeDesc); + printf (" Type:%22s0x%02X (%s)\n", "", Type, GetExportFlags (Type, 0)); + printf (" Address size:%14s0x%02X (%s)\n", "", AddrSize, + AddrSizeToStr (AddrSize)); printf (" Name:%*s\"%s\"\n", 24-Len, "", Name); if (HaveValue) { printf (" Value:%15s0x%08lX (%lu)\n", "", Value, Value); } + } + + /* Destroy the string pool */ + DestroyStrPool (&StrPool); +} + + + +void DumpObjLineInfo (FILE* F, unsigned long Offset) +/* Dump the line info from an object file */ +{ + ObjHeader H; + Collection StrPool = AUTO_COLLECTION_INITIALIZER; + unsigned Count; + unsigned I; + + /* Seek to the header position and read the header */ + FileSetPos (F, Offset); + ReadObjHeader (F, &H); + + /* Seek to the start of the string pool and read it */ + FileSetPos (F, Offset + H.StrPoolOffs); + ReadStrPool (F, &StrPool); + + /* Seek to the start of line infos */ + FileSetPos (F, Offset + H.LineInfoOffs); + + /* Output a header */ + printf (" Line info:\n"); - /* Free the Name */ - xfree (Name); + /* Check if the object file was compiled with debug info */ + if ((H.Flags & OBJ_FLAGS_DBGINFO) == 0) { + /* Print that there no line infos and bail out */ + printf (" Count:%27u\n", 0); + return; } + + /* Read the number of line infos and print it */ + Count = ReadVar (F); + printf (" Count:%27u\n", Count); + + /* Read and print all line infos */ + for (I = 0; I < Count; ++I) { + + FilePos Pos; + + /* Read one line info */ + ReadFilePos (F, &Pos); + + /* Print the header */ + printf (" Index:%27u\n", I); + + /* Print the data */ + printf (" Line:%26lu\n", Pos.Line); + printf (" Col:%27u\n", Pos.Col); + printf (" Name:%26u\n", Pos.Name); + } + + /* Destroy the string pool */ + DestroyStrPool (&StrPool); } +void DumpObjSegSize (FILE* F, unsigned long Offset) +/* Dump the sizes of the segment in the object file */ +{ + ObjHeader H; + Collection StrPool = AUTO_COLLECTION_INITIALIZER; + unsigned Count; + + /* Seek to the header position and read the header */ + FileSetPos (F, Offset); + ReadObjHeader (F, &H); + + /* Seek to the start of the string pool and read it */ + FileSetPos (F, Offset + H.StrPoolOffs); + ReadStrPool (F, &StrPool); + + /* Seek to the start of the segments */ + FileSetPos (F, Offset + H.SegOffs); + + /* Output a header */ + printf (" Segment sizes:\n"); + + /* Read the number of segments */ + Count = ReadVar (F); + + /* Read and print the sizes of all segments */ + while (Count--) { + + /* Read the data for one segments */ + unsigned long DataSize = Read32 (F); + unsigned long NextSeg = ftell (F) + DataSize; + const char* Name = GetString (&StrPool, ReadVar (F)); + unsigned Len = strlen (Name); + unsigned long Size = Read32 (F); + + /* 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); + + /* Seek to the end of the segment data (start of next) */ + FileSetPos (F, NextSeg); + } + + /* Destroy the string pool */ + DestroyStrPool (&StrPool); +} + +