diff --git a/tools/qfcc/include/obj_type.h b/tools/qfcc/include/obj_type.h index 65897a5cd..b8ff2b4e2 100644 --- a/tools/qfcc/include/obj_type.h +++ b/tools/qfcc/include/obj_type.h @@ -86,7 +86,7 @@ typedef struct qfot_array_s { arrays. */ typedef struct qfot_type_s { - pr_int_t ty; ///< meta type: ty_type_e + pr_int_t ty; ///< meta type: ty_meta_e pr_int_t size; ///< total word size of this encoding string_t encoding; ///< Objective-QC encoding union { diff --git a/tools/qfcc/include/qfprogs.h b/tools/qfcc/include/qfprogs.h index 102851b34..af3bcafe7 100644 --- a/tools/qfcc/include/qfprogs.h +++ b/tools/qfcc/include/qfprogs.h @@ -56,5 +56,6 @@ void dump_strings (struct progs_s *pr); void qfo_globals (struct qfo_s *qfo); void qfo_functions (struct qfo_s *qfo); void qfo_relocs (struct qfo_s *qfo); +void qfo_types (struct qfo_s *qfo); #endif//__qfprogs_h diff --git a/tools/qfcc/source/dump_globals.c b/tools/qfcc/source/dump_globals.c index d8220323f..687cbe4be 100644 --- a/tools/qfcc/source/dump_globals.c +++ b/tools/qfcc/source/dump_globals.c @@ -44,6 +44,7 @@ #include "QF/va.h" #include "obj_file.h" +#include "obj_type.h" #include "qfprogs.h" #include "reloc.h" @@ -399,3 +400,71 @@ qfo_functions (qfo_t *qfo) puts (""); } } + +static const char *ty_meta_names[] = { + "ty_none", + "ty_struct", + "ty_union", + "ty_enum", + "ty_array", + "ty_class", +}; +#define NUM_META ((int)(sizeof (ty_meta_names) / sizeof (ty_meta_names[0]))) + +void +qfo_types (qfo_t *qfo) +{ + pointer_t type_ptr; + qfot_type_t *type; + const char *meta; + int i, count; + + for (type_ptr = 4; type_ptr < qfo->spaces[qfo_type_space].data_size; + type_ptr += type->size) { + type = &QFO_STRUCT (qfo, qfo_type_space, qfot_type_t, type_ptr); + if (type->ty < 0 || type->ty >= NUM_META) + meta = "invalid"; + else + meta = ty_meta_names[type->ty]; + printf ("%-5x %-9s %-20s", type_ptr, meta, + QFO_TYPESTR (qfo, type_ptr)); + switch ((ty_meta_e) type->ty) { + case ty_none: + printf (" %-10s", (type->t.type < 0 + || type->t.type >= ev_type_count) + ? "invalid type" + : pr_type_name[type->t.type]); + if (type->t.type == ev_func) { + printf ("%5x %d", type->t.func.return_type, + count = type->t.func.num_params); + if (count < 0) + count = ~count; //ones complement + for (i = 0; i < count; i++) + printf (" %x", type->t.func.param_types[i]); + } else if (type->t.type == ev_pointer + || type->t.type == ev_field) { + printf (" %x", type->t.fldptr.aux_type); + } + printf ("\n"); + break; + case ty_struct: + case ty_union: + case ty_enum: + printf (" %s\n", QFO_GETSTR (qfo, type->t.strct.tag)); + for (i = 0; i < type->t.strct.num_fields; i++) { + printf (" %-5x %4x %s\n", + type->t.strct.fields[i].type, + type->t.strct.fields[i].offset, + QFO_GETSTR (qfo, type->t.strct.fields[i].name)); + } + break; + case ty_array: + printf (" %-5x %d %d\n", type->t.array.type, + type->t.array.base, type->t.array.size); + break; + case ty_class: + printf (" %-5x\n", type->t.class); + break; + } + } +} diff --git a/tools/qfcc/source/qfprogs.c b/tools/qfcc/source/qfprogs.c index 4c7db4b2b..01aa56b6e 100644 --- a/tools/qfcc/source/qfprogs.c +++ b/tools/qfcc/source/qfprogs.c @@ -103,6 +103,7 @@ static const struct option long_options[] = { {"path", required_argument, 0, 'P'}, {"relocs", no_argument, 0, 'r'}, {"strings", no_argument, 0, 's'}, + {"types", no_argument, 0, 't'}, {"verbose", no_argument, 0, 'v'}, {NULL, 0, NULL, 0}, }; @@ -119,6 +120,7 @@ static const char *short_options = "P:" // path "r" // relocs "s" // strings + "t" // types "v" // verbose ; @@ -150,6 +152,7 @@ usage (int status) " -P, --path DIR Source path.\n" " -r, --relocs Dump reloc information.\n" " -s, --strings Dump static strings.\n" +" -t, --types Dump type encodings.\n" " -v, --verbose Display more output than usual.\n" ); exit (status); @@ -351,6 +354,7 @@ operation_t operations[] = { {dump_lines, 0}, // lines {dump_modules, 0}, // modules {0, qfo_relocs}, // relocs + {0, qfo_types}, // types }; int @@ -394,6 +398,9 @@ main (int argc, char **argv) case 's': func = &operations[2]; break; + case 't': + func = &operations[8]; + break; case 'v': verbosity++; break;