mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-12-11 21:31:30 +00:00
New dump format for progs. It looks like assembly code. setting pr_debug to 2
or higher adds more debug information.
This commit is contained in:
parent
d9eff16941
commit
e551c1f22b
2 changed files with 94 additions and 62 deletions
|
@ -43,6 +43,7 @@ static const char rcsid[] =
|
||||||
#include "QF/idparse.h"
|
#include "QF/idparse.h"
|
||||||
#include "QF/crc.h"
|
#include "QF/crc.h"
|
||||||
#include "QF/cvar.h"
|
#include "QF/cvar.h"
|
||||||
|
#include "QF/dstring.h"
|
||||||
#include "QF/hash.h"
|
#include "QF/hash.h"
|
||||||
#include "QF/progs.h"
|
#include "QF/progs.h"
|
||||||
#include "QF/qdefs.h"
|
#include "QF/qdefs.h"
|
||||||
|
@ -341,27 +342,29 @@ PR_UglyValueString (progs_t * pr, etype_t type, pr_type_t *val)
|
||||||
/*
|
/*
|
||||||
PR_GlobalString
|
PR_GlobalString
|
||||||
|
|
||||||
Returns a string with a description and the contents of a global,
|
Returns a string with a description and the contents of a global
|
||||||
padded to 20 field width
|
|
||||||
*/
|
*/
|
||||||
char *
|
dstring_t *
|
||||||
PR_GlobalString (progs_t * pr, int ofs, etype_t type)
|
PR_GlobalString (progs_t * pr, int ofs, etype_t type)
|
||||||
{
|
{
|
||||||
char *s;
|
ddef_t *def = NULL;
|
||||||
int i;
|
static dstring_t *line = NULL;
|
||||||
ddef_t *def = 0;
|
char *s;
|
||||||
static char line[128];
|
|
||||||
|
if (!line)
|
||||||
|
line = dstring_newstr();
|
||||||
|
|
||||||
if (type == ev_short) {
|
if (type == ev_short) {
|
||||||
snprintf (line, sizeof (line), "%-20d", (short) ofs);
|
dsprintf (line, "%04x", (short) ofs);
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pr_debug->int_val && pr->debug)
|
if (pr_debug->int_val && pr->debug)
|
||||||
def = PR_Get_Local_Def (pr, ofs);
|
def = PR_Get_Local_Def (pr, ofs);
|
||||||
if (!def)
|
if (!def)
|
||||||
def = ED_GlobalAtOfs (pr, ofs);
|
def = ED_GlobalAtOfs (pr, ofs);
|
||||||
if (!def && type == ev_void)
|
if (!def && type == ev_void)
|
||||||
snprintf (line, sizeof (line), "%i(?)", ofs);
|
dsprintf (line, "[%04x]", ofs);
|
||||||
else {
|
else {
|
||||||
char *name = "?";
|
char *name = "?";
|
||||||
char *oi = "";
|
char *oi = "";
|
||||||
|
@ -370,48 +373,53 @@ PR_GlobalString (progs_t * pr, int ofs, etype_t type)
|
||||||
type = def->type;
|
type = def->type;
|
||||||
name = PR_GetString (pr, def->s_name);
|
name = PR_GetString (pr, def->s_name);
|
||||||
if (type != (def->type & ~DEF_SAVEGLOBAL))
|
if (type != (def->type & ~DEF_SAVEGLOBAL))
|
||||||
oi = "!";
|
oi = "?";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ofs > pr->globals_size)
|
if (ofs > pr->globals_size)
|
||||||
s = "Out of bounds";
|
s = "Out of bounds";
|
||||||
else
|
else
|
||||||
s = PR_ValueString (pr, type, &pr->pr_globals[ofs]);
|
s = PR_ValueString (pr, type, &pr->pr_globals[ofs]);
|
||||||
snprintf (line, sizeof (line), "%i(%s%s)%s", ofs, oi, name, s);
|
|
||||||
|
if (strequal(name, "IMMEDIATE") || strequal(name, ".imm")) {
|
||||||
|
if (type == ev_string)
|
||||||
|
dsprintf (line, "\"%s\"", s);
|
||||||
|
else
|
||||||
|
dsprintf (line, "%s", s);
|
||||||
|
} else if (strequal(name, "?"))
|
||||||
|
dsprintf (line, "[%04x]", ofs);
|
||||||
|
else {
|
||||||
|
if (type == ev_func)
|
||||||
|
dsprintf (line, "%s%s", name, oi);
|
||||||
|
else
|
||||||
|
dsprintf (line, "%s%s(%s)", name, oi, s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
i = strlen (line);
|
|
||||||
for (; i < 20; i++)
|
|
||||||
strncat (line, " ", sizeof (line) - strlen (line));
|
|
||||||
strncat (line, " ", sizeof (line) - strlen (line));
|
|
||||||
|
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
dstring_t *
|
||||||
PR_GlobalStringNoContents (progs_t * pr, int ofs, etype_t type)
|
PR_GlobalStringNoContents (progs_t * pr, int ofs, etype_t type)
|
||||||
{
|
{
|
||||||
int i;
|
static dstring_t *line = NULL;
|
||||||
ddef_t *def = 0;
|
ddef_t *def = NULL;
|
||||||
static char line[128];
|
|
||||||
|
if (!line)
|
||||||
|
line = dstring_newstr();
|
||||||
|
|
||||||
if (type == ev_short) {
|
if (type == ev_short) {
|
||||||
snprintf (line, sizeof (line), "%-20d", (short) ofs);
|
dsprintf (line, "%x", (short) ofs);
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pr_debug->int_val && pr->debug)
|
if (pr_debug->int_val && pr->debug)
|
||||||
def = PR_Get_Local_Def (pr, ofs);
|
def = PR_Get_Local_Def (pr, ofs);
|
||||||
if (!def)
|
if (!def)
|
||||||
def = ED_GlobalAtOfs (pr, ofs);
|
def = ED_GlobalAtOfs (pr, ofs);
|
||||||
if (!def)
|
if (!def)
|
||||||
snprintf (line, sizeof (line), "%i(?)", ofs);
|
dsprintf (line, "[%x]", ofs);
|
||||||
else
|
else
|
||||||
snprintf (line, sizeof (line), "%i(%s)", ofs,
|
dsprintf (line, "%s", PR_GetString (pr, def->s_name));
|
||||||
PR_GetString (pr, def->s_name));
|
|
||||||
|
|
||||||
i = strlen (line);
|
|
||||||
for (; i < 20; i++)
|
|
||||||
strncat (line, " ", sizeof (line) - strlen (line));
|
|
||||||
strncat (line, " ", sizeof (line) - strlen (line));
|
|
||||||
|
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,12 +48,12 @@ static const char rcsid[] =
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PR_PrintStatement (progs_t * pr, dstatement_t *s)
|
PR_PrintStatement (progs_t * pr, dstatement_t *s)
|
||||||
{
|
{
|
||||||
int addr = s - pr->pr_statements;
|
int addr = s - pr->pr_statements;
|
||||||
opcode_t *op;
|
int ofs;
|
||||||
|
opcode_t *op;
|
||||||
|
|
||||||
if (pr_debug->int_val && pr->debug) {
|
if (pr_debug->int_val && pr->debug) {
|
||||||
const char *source_line = PR_Get_Source_Line (pr, addr);
|
const char *source_line = PR_Get_Source_Line (pr, addr);
|
||||||
|
@ -61,41 +61,65 @@ PR_PrintStatement (progs_t * pr, dstatement_t *s)
|
||||||
if (source_line)
|
if (source_line)
|
||||||
Sys_Printf ("%s\n", source_line);
|
Sys_Printf ("%s\n", source_line);
|
||||||
}
|
}
|
||||||
Sys_Printf ("%-7d ", addr);
|
|
||||||
op = PR_Opcode (s->op);
|
op = PR_Opcode (s->op);
|
||||||
if (!op) {
|
if (!op) {
|
||||||
Sys_Printf ("unknown opcode %d\n", s->op);
|
Sys_Printf ("Unknown instruction %d\n", s->op);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Sys_Printf ("%-9s ", op->opname);
|
|
||||||
|
|
||||||
if (s->op == OP_IF || s->op == OP_IFNOT || s->op == OP_IFBE
|
Sys_Printf ("%04x ", addr);
|
||||||
|| s->op == OP_IFB || s->op == OP_IFAE || s->op == OP_IFA) {
|
if (pr_debug->int_val > 1)
|
||||||
int ofs = (short) s->b;
|
Sys_Printf ("%02x %04x(%s) %04x(%s) %04x(%s)\t",
|
||||||
Sys_Printf ("%sbranch %i (%i)",
|
s->op,
|
||||||
PR_GlobalString (pr, s->a, ev_integer), ofs, addr + ofs);
|
s->a, pr_type_name[op->type_a],
|
||||||
} else if (s->op == OP_GOTO) {
|
s->b, pr_type_name[op->type_b],
|
||||||
int ofs = (short) s->a;
|
s->c, pr_type_name[op->type_c]);
|
||||||
Sys_Printf ("branch %i (%i)", ofs, addr + ofs);
|
|
||||||
} else if (s->op == OP_RETURN || s->op == OP_DONE) {
|
Sys_Printf ("%s ", op->opname);
|
||||||
Sys_Printf ("%s", PR_GlobalString (pr, s->a, ev_void));
|
|
||||||
} else {
|
switch (s->op) {
|
||||||
if (op->type_a != ev_void)
|
case OP_IF:
|
||||||
Sys_Printf ("%s", PR_GlobalString (pr, s->a, op->type_a));
|
case OP_IFNOT:
|
||||||
if (op->type_b != ev_void) {
|
case OP_IFBE:
|
||||||
if (op->type_c != ev_void)
|
case OP_IFB:
|
||||||
Sys_Printf ("%s", PR_GlobalString (pr, s->b, op->type_b));
|
case OP_IFAE:
|
||||||
else
|
case OP_IFA:
|
||||||
Sys_Printf ("%s", PR_GlobalStringNoContents (pr, s->b,
|
ofs = (short) s->b;
|
||||||
op->type_b));
|
|
||||||
}
|
Sys_Printf ("%s branch %i (%i)",
|
||||||
if (op->type_c != ev_void) {
|
PR_GlobalString (pr, s->a, ev_integer)->str, ofs, addr + ofs);
|
||||||
if (op->type_b == ev_pointer && op->type_c == ev_integer)
|
break;
|
||||||
Sys_Printf ("%s", PR_GlobalString (pr, s->c, op->type_c));
|
|
||||||
else
|
case OP_GOTO:
|
||||||
Sys_Printf ("%s", PR_GlobalStringNoContents (pr, s->c,
|
ofs = (short) s->a;
|
||||||
op->type_c));
|
Sys_Printf ("branch %i (%i)", ofs, addr + ofs);
|
||||||
}
|
break;
|
||||||
|
|
||||||
|
case OP_RETURN:
|
||||||
|
case OP_DONE:
|
||||||
|
Sys_Printf ("%s", PR_GlobalString (pr, s->a, ev_void)->str);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (op->type_a != ev_void)
|
||||||
|
Sys_Printf ("%s", PR_GlobalString (pr, s->a, op->type_a)->str);
|
||||||
|
|
||||||
|
if (op->type_b != ev_void) {
|
||||||
|
if (op->type_c != ev_void)
|
||||||
|
Sys_Printf (", %s", PR_GlobalString (pr, s->b, op->type_b)->str);
|
||||||
|
else
|
||||||
|
Sys_Printf (", %s",
|
||||||
|
PR_GlobalStringNoContents (pr, s->b, op->type_b)->str);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op->type_c != ev_void) {
|
||||||
|
if (op->type_b == ev_pointer && op->type_c == ev_integer)
|
||||||
|
Sys_Printf (", %s", PR_GlobalString (pr, s->c, op->type_c)->str);
|
||||||
|
else
|
||||||
|
Sys_Printf (", %s",
|
||||||
|
PR_GlobalStringNoContents (pr, s->c, op->type_c)->str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Sys_Printf ("\n");
|
Sys_Printf ("\n");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue