/* */
/* */
/* */
-/* (C) 2000-2002 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
+/* (C) 2002-2003 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* common */
#include "cddefs.h"
+#include "coll.h"
#include "exprdefs.h"
#include "filepos.h"
#include "objdefs.h"
/*****************************************************************************/
-/* 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)
case EXPR_SYMBOL:
/* Read the import number */
- (void) Read16 (F);
+ (void) ReadVar (F);
break;
case EXPR_SECTION:
/* 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) {
}
+ /* 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);
/* 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);
}
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 */
+ /* Seek to the header position and read the header */
FileSeek (F, Offset);
-
- /* Read the header */
ReadObjHeader (F, &H);
+ /* Seek to the start of the string pool and read it */
+ FileSeek (F, Offset + H.StrPoolOffs);
+ ReadStrPool (F, &StrPool);
+
/* Seek to the start of the options */
FileSeek (F, Offset + H.OptionOffs);
break;
}
}
+
+ /* Destroy the string pool */
+ DestroyStrPool (&StrPool);
}
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 */
+ /* Seek to the header position and read the header */
FileSeek (F, Offset);
-
- /* Read the header */
ReadObjHeader (F, &H);
+ /* Seek to the start of the string pool and read it */
+ FileSeek (F, Offset + H.StrPoolOffs);
+ ReadStrPool (F, &StrPool);
+
/* Seek to the start of the source files */
FileSeek (F, Offset + H.FileOffs);
/* Free the Name */
xfree (Name);
}
+
+ /* Destroy the string pool */
+ DestroyStrPool (&StrPool);
}
void DumpObjSegments (FILE* F, unsigned long Offset)
/* Dump the segments in the object file */
{
- ObjHeader H;
- unsigned Count;
- unsigned I;
- unsigned FragCount;
+ ObjHeader H;
+ Collection StrPool = AUTO_COLLECTION_INITIALIZER;
+ unsigned Count;
+ unsigned I;
+ unsigned FragCount;
- /* Seek to the header position */
+ /* Seek to the header position and read the header */
FileSeek (F, Offset);
-
- /* Read the header */
ReadObjHeader (F, &H);
+ /* Seek to the start of the string pool and read it */
+ FileSeek (F, Offset + H.StrPoolOffs);
+ ReadStrPool (F, &StrPool);
+
/* Seek to the start of the segments */
FileSeek (F, Offset + H.SegOffs);
/* Read and print all segments */
for (I = 0; I < Count; ++I) {
-
+
/* Read the data for one segments */
char* Name = ReadStr (F);
unsigned Len = strlen (Name);
while (Size > 0) {
unsigned FragSize = SkipFragment (F);
if (FragSize > Size) {
- /* OOPS - file data invalid */
- Error ("Invalid fragment data - file corrupt!");
+ /* OOPS - file data invalid */
+ Error ("Invalid fragment data - file corrupt!");
}
Size -= FragSize;
++FragCount;
/* Print the fragment count */
printf (" Fragment count:%16u\n", FragCount);
}
+
+ /* Destroy the string pool */
+ DestroyStrPool (&StrPool);
}
void DumpObjImports (FILE* F, unsigned long Offset)
/* Dump the imports in the object file */
{
- ObjHeader H;
- unsigned Count;
- unsigned I;
- FilePos Pos;
+ ObjHeader H;
+ Collection StrPool = AUTO_COLLECTION_INITIALIZER;
+ unsigned Count;
+ unsigned I;
+ FilePos Pos;
- /* Seek to the header position */
+ /* Seek to the header position and read the header */
FileSeek (F, Offset);
-
- /* Read the header */
ReadObjHeader (F, &H);
+ /* Seek to the start of the string pool and read it */
+ FileSeek (F, Offset + H.StrPoolOffs);
+ ReadStrPool (F, &StrPool);
+
/* Seek to the start of the imports */
FileSeek (F, Offset + H.ImportOffs);
/* Read the data for one import */
unsigned char Type = Read8 (F);
- char* Name = ReadStr (F);
+ const char* Name = GetString (&StrPool, ReadVar (F));
unsigned Len = strlen (Name);
ReadFilePos (F, &Pos);
/* Print the data */
printf (" Type:%22s0x%02X (%s)\n", "", Type, TypeDesc);
printf (" Name:%*s\"%s\"\n", 24-Len, "", Name);
-
- /* Free the Name */
- xfree (Name);
}
+
+ /* Destroy the string pool */
+ DestroyStrPool (&StrPool);
}
void DumpObjExports (FILE* F, unsigned long Offset)
/* Dump the exports in the object file */
{
- ObjHeader H;
- unsigned Count;
- unsigned I;
- FilePos Pos;
+ ObjHeader H;
+ Collection StrPool = AUTO_COLLECTION_INITIALIZER;
+ unsigned Count;
+ unsigned I;
+ FilePos Pos;
- /* Seek to the header position */
+ /* Seek to the header position and read the header */
FileSeek (F, Offset);
-
- /* Read the header */
ReadObjHeader (F, &H);
+ /* Seek to the start of the string pool and read it */
+ FileSeek (F, Offset + H.StrPoolOffs);
+ ReadStrPool (F, &StrPool);
+
/* Seek to the start of the exports */
FileSeek (F, Offset + H.ExportOffs);
for (I = 0; I < Count; ++I) {
unsigned long Value = 0;
- int HaveValue;
+ int HaveValue;
unsigned char Type;
unsigned char ConDes [CD_TYPE_COUNT];
- char* Name;
+ const char* Name;
unsigned Len;
/* Read the data for one export */
Type = Read8 (F);
ReadData (F, ConDes, GET_EXP_CONDES_COUNT (Type));
- Name = ReadStr (F);
+ Name = GetString (&StrPool, ReadVar (F));
Len = strlen (Name);
if (IS_EXP_EXPR (Type)) {
SkipExpr (F);
if (HaveValue) {
printf (" Value:%15s0x%08lX (%lu)\n", "", Value, Value);
}
-
- /* Free the Name */
- xfree (Name);
}
+
+ /* Destroy the string pool */
+ DestroyStrPool (&StrPool);
}
void DumpObjDbgSyms (FILE* F, unsigned long Offset)
/* Dump the debug symbols from an object file */
{
- ObjHeader H;
- unsigned Count;
- unsigned I;
- FilePos Pos;
+ ObjHeader H;
+ Collection StrPool = AUTO_COLLECTION_INITIALIZER;
+ unsigned Count;
+ unsigned I;
+ FilePos Pos;
- /* Seek to the header position */
+ /* Seek to the header position and read the header */
FileSeek (F, Offset);
-
- /* Read the header */
ReadObjHeader (F, &H);
+ /* Seek to the start of the string pool and read it */
+ FileSeek (F, Offset + H.StrPoolOffs);
+ ReadStrPool (F, &StrPool);
+
/* Seek to the start of the debug syms */
FileSeek (F, Offset + H.DbgSymOffs);
int HaveValue;
unsigned char Type;
unsigned char ConDes [CD_TYPE_COUNT];
- char* Name;
+ const char* Name;
unsigned Len;
/* Read the data for one symbol */
Type = Read8 (F);
ReadData (F, ConDes, GET_EXP_CONDES_COUNT (Type));
- Name = ReadStr (F);
+ Name = GetString (&StrPool, ReadVar (F));
Len = strlen (Name);
if (IS_EXP_EXPR (Type)) {
SkipExpr (F);
if (HaveValue) {
printf (" Value:%15s0x%08lX (%lu)\n", "", Value, Value);
}
-
- /* Free the Name */
- xfree (Name);
}
+
+ /* Destroy the string pool */
+ DestroyStrPool (&StrPool);
}
void DumpObjLineInfo (FILE* F, unsigned long Offset)
/* Dump the line info from an object file */
{
- ObjHeader H;
- unsigned Count;
- unsigned I;
+ ObjHeader H;
+ Collection StrPool = AUTO_COLLECTION_INITIALIZER;
+ unsigned Count;
+ unsigned I;
- /* Seek to the header position */
+ /* Seek to the header position and read the header */
FileSeek (F, Offset);
-
- /* Read the header */
ReadObjHeader (F, &H);
+ /* Seek to the start of the string pool and read it */
+ FileSeek (F, Offset + H.StrPoolOffs);
+ ReadStrPool (F, &StrPool);
+
/* Seek to the start of line infos */
FileSeek (F, Offset + H.LineInfoOffs);
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;
- unsigned Count;
+ ObjHeader H;
+ Collection StrPool = AUTO_COLLECTION_INITIALIZER;
+ unsigned Count;
- /* Seek to the header position */
+ /* Seek to the header position and read the header */
FileSeek (F, Offset);
-
- /* Read the header */
ReadObjHeader (F, &H);
+ /* Seek to the start of the string pool and read it */
+ FileSeek (F, Offset + H.StrPoolOffs);
+ ReadStrPool (F, &StrPool);
+
/* Seek to the start of the segments */
FileSeek (F, Offset + H.SegOffs);
Size -= FragSize;
}
}
+
+ /* Destroy the string pool */
+ DestroyStrPool (&StrPool);
}