mirror of
https://github.com/cc65/cc65.git
synced 2024-12-26 08:32:00 +00:00
Add dumping of options
git-svn-id: svn://svn.cc65.org/cc65/trunk@237 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
2e3b545bdb
commit
697f6e1cfa
135
src/od65/dump.c
135
src/od65/dump.c
@ -33,79 +33,172 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
#include "objdefs.h"
|
#include "objdefs.h"
|
||||||
|
#include "optdefs.h"
|
||||||
|
#include "xmalloc.h"
|
||||||
|
|
||||||
/* od65 */
|
/* od65 */
|
||||||
|
#include "error.h"
|
||||||
#include "fileio.h"
|
#include "fileio.h"
|
||||||
#include "dump.h"
|
#include "dump.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* Code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void DumpHeaderSection (const char* Name,
|
static void DumpObjHeaderSection (const char* Name,
|
||||||
unsigned long Offset,
|
unsigned long Offset,
|
||||||
unsigned long Size)
|
unsigned long Size)
|
||||||
/* Dump a header section */
|
/* Dump a header section */
|
||||||
{
|
{
|
||||||
printf (" %s:\n", Name);
|
printf (" %s:\n", Name);
|
||||||
printf (" Offset: %8lu\n", Offset);
|
printf (" Offset: %8lu\n", Offset);
|
||||||
printf (" Size: %8lu\n", Size);
|
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 */
|
/* Dump the header of the given object file */
|
||||||
{
|
{
|
||||||
ObjHeader H;
|
ObjHeader H;
|
||||||
|
|
||||||
/* Output a header */
|
|
||||||
printf (" Header:\n");
|
|
||||||
|
|
||||||
/* Seek to the header position */
|
/* Seek to the header position */
|
||||||
fseek (F, 0, SEEK_SET);
|
FileSeek (F, Offset);
|
||||||
|
|
||||||
/* Read the header */
|
/* Read the header */
|
||||||
ReadObjHeader (F, &H);
|
ReadObjHeader (F, &H);
|
||||||
|
|
||||||
/* Now dump the information */
|
/* Now dump the information */
|
||||||
|
|
||||||
|
/* Output a header */
|
||||||
|
printf (" Header:\n");
|
||||||
|
|
||||||
/* Magic */
|
/* Magic */
|
||||||
printf (" Magic: 0x%08lX\n", H.Magic);
|
printf (" Magic: 0x%08lX\n", H.Magic);
|
||||||
|
|
||||||
/* Version */
|
/* Version */
|
||||||
printf (" Version: %10u\n", H.Version);
|
printf (" Version: %10u\n", H.Version);
|
||||||
|
|
||||||
/* Flags */
|
/* Flags */
|
||||||
printf (" Flags: 0x%04X (", H.Flags);
|
printf (" Flags: 0x%04X (", H.Flags);
|
||||||
if (H.Flags & OBJ_FLAGS_DBGINFO) {
|
if (H.Flags & OBJ_FLAGS_DBGINFO) {
|
||||||
printf ("OBJ_FLAGS_DBGINFO");
|
printf ("OBJ_FLAGS_DBGINFO");
|
||||||
}
|
}
|
||||||
printf (")\n");
|
printf (")\n");
|
||||||
|
|
||||||
/* Options */
|
/* Options */
|
||||||
DumpHeaderSection ("Options", H.OptionOffs, H.OptionSize);
|
DumpObjHeaderSection ("Options", H.OptionOffs, H.OptionSize);
|
||||||
|
|
||||||
/* Files */
|
/* Files */
|
||||||
DumpHeaderSection ("Files", H.FileOffs, H.FileSize);
|
DumpObjHeaderSection ("Files", H.FileOffs, H.FileSize);
|
||||||
|
|
||||||
/* Segments */
|
/* Segments */
|
||||||
DumpHeaderSection ("Segments", H.SegOffs, H.SegSize);
|
DumpObjHeaderSection ("Segments", H.SegOffs, H.SegSize);
|
||||||
|
|
||||||
/* Imports */
|
/* Imports */
|
||||||
DumpHeaderSection ("Imports", H.ImportOffs, H.ImportSize);
|
DumpObjHeaderSection ("Imports", H.ImportOffs, H.ImportSize);
|
||||||
|
|
||||||
/* Exports */
|
/* Exports */
|
||||||
DumpHeaderSection ("Exports", H.ExportOffs, H.ExportSize);
|
DumpObjHeaderSection ("Exports", H.ExportOffs, H.ExportSize);
|
||||||
|
|
||||||
/* Debug symbols */
|
/* 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,14 +43,17 @@
|
|||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* Code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void DumpHeader (FILE* F, unsigned long Offset);
|
void DumpObjHeader (FILE* F, unsigned long Offset);
|
||||||
/* Dump the header of the given object file */
|
/* Dump the header of the given object file */
|
||||||
|
|
||||||
|
void DumpObjOptions (FILE* F, unsigned long Offset);
|
||||||
|
/* Dump the file options */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* End of dump.h */
|
/* End of dump.h */
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
@ -50,6 +51,16 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void FileSeek (FILE* F, unsigned long Pos)
|
||||||
|
/* Seek to the given absolute position, fail on errors */
|
||||||
|
{
|
||||||
|
if (fseek (F, Pos, SEEK_SET) != 0) {
|
||||||
|
Error ("Cannot seek: %s", strerror (errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned Read8 (FILE* F)
|
unsigned Read8 (FILE* F)
|
||||||
/* Read an 8 bit value from the file */
|
/* Read an 8 bit value from the file */
|
||||||
{
|
{
|
||||||
|
@ -52,6 +52,9 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void FileSeek (FILE* F, unsigned long Pos);
|
||||||
|
/* Seek to the given absolute position, fail on errors */
|
||||||
|
|
||||||
unsigned Read8 (FILE* F);
|
unsigned Read8 (FILE* F);
|
||||||
/* Read an 8 bit value from the file */
|
/* Read an 8 bit value from the file */
|
||||||
|
|
||||||
|
@ -45,6 +45,12 @@
|
|||||||
|
|
||||||
|
|
||||||
#define D_HEADER 0x00000001UL /* Dump the header */
|
#define D_HEADER 0x00000001UL /* Dump the header */
|
||||||
|
#define D_OPTIONS 0x00000002UL /* Dump the options */
|
||||||
|
#define D_FILES 0x00000004UL /* Dump source file info */
|
||||||
|
#define D_SEGMENTS 0x00000008UL /* Dump segment info */
|
||||||
|
#define D_IMPORTS 0x00000010UL /* Dump imported symbols */
|
||||||
|
#define D_EXPORTS 0x00000020UL /* Dump exported symbols */
|
||||||
|
#define D_DBGSYMS 0x00000040UL /* Dump debug symbols */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -78,6 +78,7 @@ static void Usage (void)
|
|||||||
"\n"
|
"\n"
|
||||||
"Long options:\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"
|
" --help\t\tHelp (this text)\n"
|
||||||
" --version\t\tPrint the version number and exit\n",
|
" --version\t\tPrint the version number and exit\n",
|
||||||
ProgName);
|
ProgName);
|
||||||
@ -93,6 +94,14 @@ static void OptDumpHeader (const char* Opt, const char* Arg)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
static void OptHelp (const char* Opt, const char* Arg)
|
||||||
/* Print usage information and exit */
|
/* Print usage information and exit */
|
||||||
{
|
{
|
||||||
@ -130,7 +139,7 @@ static void DumpFile (const char* Name)
|
|||||||
if (Magic != OBJ_MAGIC) {
|
if (Magic != OBJ_MAGIC) {
|
||||||
|
|
||||||
/* Unknown format */
|
/* Unknown format */
|
||||||
printf ("%s: (no xo65 object file)\n", Name);
|
printf ("%s: (no x65 object file)\n", Name);
|
||||||
|
|
||||||
} else if (What == 0) {
|
} else if (What == 0) {
|
||||||
|
|
||||||
@ -144,9 +153,11 @@ static void DumpFile (const char* Name)
|
|||||||
|
|
||||||
/* Check what to dump */
|
/* Check what to dump */
|
||||||
if (What & D_HEADER) {
|
if (What & D_HEADER) {
|
||||||
DumpHeader (F, 0);
|
DumpObjHeader (F, 0);
|
||||||
}
|
}
|
||||||
|
if (What & D_OPTIONS) {
|
||||||
|
DumpObjOptions (F, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Close the file */
|
/* Close the file */
|
||||||
@ -161,6 +172,7 @@ int main (int argc, char* argv [])
|
|||||||
/* Program long options */
|
/* Program long options */
|
||||||
static const LongOpt OptTab[] = {
|
static const LongOpt OptTab[] = {
|
||||||
{ "--dump-header", 0, OptDumpHeader },
|
{ "--dump-header", 0, OptDumpHeader },
|
||||||
|
{ "--dump-options", 0, OptDumpOptions },
|
||||||
{ "--help", 0, OptHelp },
|
{ "--help", 0, OptHelp },
|
||||||
{ "--version", 0, OptVersion },
|
{ "--version", 0, OptVersion },
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user