+#include <time.h>
+
/* common */
#include "objdefs.h"
+#include "optdefs.h"
+#include "xmalloc.h"
/* od65 */
+#include "error.h"
#include "fileio.h"
#include "dump.h"
/*****************************************************************************/
-/* Code */
+/* Code */
/*****************************************************************************/
-static void DumpHeaderSection (const char* Name,
- unsigned long Offset,
- unsigned long Size)
+static void DumpObjHeaderSection (const char* Name,
+ unsigned long Offset,
+ unsigned long Size)
/* Dump a header section */
{
printf (" %s:\n", Name);
- printf (" Offset: %8lu\n", Offset);
- printf (" Size: %8lu\n", Size);
+ printf (" Offset: %8lu\n", Offset);
+ printf (" Size: %8lu\n", Size);
}
-void DumpHeader (FILE* F, unsigned long Offset)
+void DumpObjHeader (FILE* F, unsigned long Offset)
/* Dump the header of the given object file */
{
ObjHeader H;
- /* Output a header */
- printf (" Header:\n");
-
/* Seek to the header position */
- fseek (F, 0, SEEK_SET);
+ FileSeek (F, Offset);
/* Read the header */
ReadObjHeader (F, &H);
/* Now dump the information */
+ /* Output a header */
+ printf (" Header:\n");
+
/* Magic */
- printf (" Magic: 0x%08lX\n", H.Magic);
+ printf (" Magic: 0x%08lX\n", H.Magic);
/* Version */
- printf (" Version: %10u\n", H.Version);
+ printf (" Version: %10u\n", H.Version);
/* Flags */
- printf (" Flags: 0x%04X (", H.Flags);
+ printf (" Flags: 0x%04X (", H.Flags);
if (H.Flags & OBJ_FLAGS_DBGINFO) {
- printf ("OBJ_FLAGS_DBGINFO");
+ printf ("OBJ_FLAGS_DBGINFO");
}
printf (")\n");
/* Options */
- DumpHeaderSection ("Options", H.OptionOffs, H.OptionSize);
+ DumpObjHeaderSection ("Options", H.OptionOffs, H.OptionSize);
/* Files */
- DumpHeaderSection ("Files", H.FileOffs, H.FileSize);
+ DumpObjHeaderSection ("Files", H.FileOffs, H.FileSize);
/* Segments */
- DumpHeaderSection ("Segments", H.SegOffs, H.SegSize);
+ DumpObjHeaderSection ("Segments", H.SegOffs, H.SegSize);
/* Imports */
- DumpHeaderSection ("Imports", H.ImportOffs, H.ImportSize);
+ DumpObjHeaderSection ("Imports", H.ImportOffs, H.ImportSize);
/* Exports */
- DumpHeaderSection ("Exports", H.ExportOffs, H.ExportSize);
+ DumpObjHeaderSection ("Exports", H.ExportOffs, H.ExportSize);
/* Debug symbols */
- DumpHeaderSection ("Debug symbols", H.DbgSymOffs, H.DbgSymSize);
+ DumpObjHeaderSection ("Debug symbols", H.DbgSymOffs, H.DbgSymSize);
+}
+
+
+
+void DumpObjOptions (FILE* F, unsigned long Offset)
+/* Dump the file options */
+{
+ ObjHeader H;
+ long Size;
+ unsigned Count;
+ unsigned I;
+
+ /* Seek to the header position */
+ FileSeek (F, Offset);
+
+ /* Read the header */
+ ReadObjHeader (F, &H);
+
+ /* Seek to the start of the options */
+ FileSeek (F, Offset + H.OptionOffs);
+
+ /* Output a header */
+ printf (" Options:\n");
+
+ /* Read the number of options and print it */
+ Count = Read16 (F);
+ printf (" Count: %5u\n", Count);
+
+ /* Read and print all options */
+ for (I = 0; I < Count; ++I) {
+
+ unsigned long ArgNum;
+ char* ArgStr;
+ unsigned ArgLen;
+
+ /* Read the type of the option */
+ unsigned char Type = Read8 (F);
+
+ /* Get the type of the argument */
+ unsigned char ArgType = Type & OPT_ARGMASK;
+
+ /* 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 (" Option %u:\n", I);
+
+ /* Print the data */
+ printf (" Type: 0x%02X (%s)\n", Type, TypeDesc);
+ switch (ArgType) {
+
+ case OPT_ARGSTR:
+ ArgStr = ReadMallocedStr (F);
+ ArgLen = strlen (ArgStr);
+ printf (" Data:%*s\"%s\"\n", 24-ArgLen, "", ArgStr);
+ Size -= 1 + ArgLen + 1;
+ xfree (ArgStr);
+ break;
+
+ case OPT_ARGNUM:
+ ArgNum = Read32 (F);
+ printf (" Data:%26lu", ArgNum);
+ if (Type == OPT_DATETIME) {
+ /* Print the time as a string */
+ time_t T = (time_t) ArgNum;
+ printf (" (%.24s)", asctime (localtime (&T)));
+ }
+ printf ("\n");
+ Size -= 1 + 4;
+ break;
+
+ default:
+ /* Unknown argument type. This means that we cannot determine
+ * the option length, so we cannot proceed.
+ */
+ Error ("Unknown option type: 0x%02X", Type);
+ break;
+ }
+ }
}
" -V\t\t\tPrint the version number and exit\n"
"\n"
"Long options:\n"
- " --dump-header\t\tDump the object file header\n"
+ " --dump-header\t\tDump the object file header\n"
+ " --dump-options\t\tDump object file options\n"
" --help\t\tHelp (this text)\n"
" --version\t\tPrint the version number and exit\n",
ProgName);
+static void OptDumpOptions (const char* Opt, const char* Arg)
+/* Dump the object file options */
+{
+ What |= D_OPTIONS;
+}
+
+
+
static void OptHelp (const char* Opt, const char* Arg)
/* Print usage information and exit */
{
if (Magic != OBJ_MAGIC) {
/* Unknown format */
- printf ("%s: (no xo65 object file)\n", Name);
+ printf ("%s: (no x65 object file)\n", Name);
} else if (What == 0) {
/* Check what to dump */
if (What & D_HEADER) {
- DumpHeader (F, 0);
+ DumpObjHeader (F, 0);
}
-
+ if (What & D_OPTIONS) {
+ DumpObjOptions (F, 0);
+ }
}
/* Close the file */
/* Program long options */
static const LongOpt OptTab[] = {
{ "--dump-header", 0, OptDumpHeader },
+ { "--dump-options", 0, OptDumpOptions },
{ "--help", 0, OptHelp },
{ "--version", 0, OptVersion },
};