mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-17 01:11:45 +00:00
Fix the access alignment bug on 64 bit archs.
This commit is contained in:
parent
b203512eb7
commit
124506fda2
7 changed files with 76 additions and 43 deletions
|
@ -953,12 +953,18 @@ typedef struct {
|
|||
pr_int_t binum;
|
||||
} builtin_t;
|
||||
|
||||
/** Aliased over the dfunction_t entry for builtin functions. Removes one
|
||||
level of indirection when calling a builtin function.
|
||||
\bug alignment access violations on 64 bit architectures (eg, alpha)
|
||||
/** Duplicate the dfunction_t descriptor with the addition of a pointer to the
|
||||
builtin function. Avoides a level of indirection when calling a builtin
|
||||
function.
|
||||
*/
|
||||
typedef struct {
|
||||
pr_int_t first_statement;
|
||||
pr_int_t parm_start;
|
||||
pr_int_t locals;
|
||||
pr_int_t profile;
|
||||
pr_int_t numparms;
|
||||
uint8_t parm_size[MAX_PARMS];
|
||||
dfunction_t *descriptor;
|
||||
builtin_proc func;
|
||||
} bfunction_t;
|
||||
|
||||
|
@ -988,7 +994,6 @@ builtin_t *PR_FindBuiltinNum (progs_t *pr, pr_int_t num);
|
|||
dfunction_t entry for all builtin functions to contain the function
|
||||
pointer to the C implementation of the builtin function. Automaticly
|
||||
during progs load.
|
||||
\bug alignment access violations on 64 bit architectures (eg, alpha)
|
||||
\param pr pointer to ::progs_t VM struct
|
||||
\return true for success, false for failure
|
||||
*/
|
||||
|
@ -1321,7 +1326,7 @@ typedef struct strref_s strref_t;
|
|||
|
||||
typedef struct {
|
||||
pr_int_t s;
|
||||
dfunction_t *f;
|
||||
bfunction_t *f;
|
||||
strref_t *tstr;
|
||||
} prstack_t;
|
||||
|
||||
|
@ -1388,6 +1393,7 @@ struct progs_s {
|
|||
strref_t *pr_xtstr;
|
||||
|
||||
dfunction_t *pr_functions;
|
||||
bfunction_t *function_table;
|
||||
char *pr_strings;
|
||||
int pr_stringsize;
|
||||
ddef_t *pr_globaldefs;
|
||||
|
@ -1409,7 +1415,7 @@ struct progs_s {
|
|||
|
||||
qboolean pr_trace;
|
||||
int pr_trace_depth;
|
||||
dfunction_t *pr_xfunction;
|
||||
bfunction_t *pr_xfunction;
|
||||
int pr_xstatement;
|
||||
|
||||
prstack_t pr_stack[MAX_STACK_DEPTH];
|
||||
|
|
|
@ -151,9 +151,9 @@ bi_no_function (progs_t *pr)
|
|||
// no need for checking: the /only/ way to get here is via a function
|
||||
// descriptor with a bad builtin number
|
||||
dstatement_t *st = pr->pr_statements + pr->pr_xstatement;
|
||||
dfunction_t *func = pr->pr_functions + G_FUNCTION (pr, st->a);
|
||||
const char *bi_name = PR_GetString (pr, func->s_name);
|
||||
int ind = -func->first_statement;
|
||||
dfunction_t *desc = pr->pr_functions + G_FUNCTION (pr, st->a);
|
||||
const char *bi_name = PR_GetString (pr, desc->s_name);
|
||||
int ind = -desc->first_statement;
|
||||
|
||||
PR_RunError (pr, "Bad builtin called: %s = #%d", bi_name, ind);
|
||||
}
|
||||
|
@ -163,20 +163,34 @@ PR_RelocateBuiltins (progs_t *pr)
|
|||
{
|
||||
pr_int_t i, ind;
|
||||
int bad = 0;
|
||||
dfunction_t *func;
|
||||
dfunction_t *desc;
|
||||
bfunction_t *func;
|
||||
builtin_t *bi;
|
||||
builtin_proc proc;
|
||||
const char *bi_name;
|
||||
|
||||
for (i = 1; i < pr->progs->numfunctions; i++) {
|
||||
func = pr->pr_functions + i;
|
||||
if (pr->function_table)
|
||||
free (pr->function_table);
|
||||
pr->function_table = calloc (pr->progs->numfunctions,
|
||||
sizeof (bfunction_t));
|
||||
|
||||
if (func->first_statement > 0)
|
||||
for (i = 1; i < pr->progs->numfunctions; i++) {
|
||||
desc = pr->pr_functions + i;
|
||||
func = pr->function_table + i;
|
||||
|
||||
func->first_statement = desc->first_statement;
|
||||
func->parm_start = desc->parm_start;
|
||||
func->locals = desc->locals;
|
||||
func->numparms = desc->numparms;
|
||||
memcpy (func->parm_size, desc->parm_size, sizeof (func->parm_size));
|
||||
func->descriptor = desc;
|
||||
|
||||
if (desc->first_statement > 0)
|
||||
continue;
|
||||
|
||||
bi_name = PR_GetString (pr, func->s_name);
|
||||
bi_name = PR_GetString (pr, desc->s_name);
|
||||
|
||||
if (!func->first_statement) {
|
||||
if (!desc->first_statement) {
|
||||
bi = PR_FindBuiltin (pr, bi_name);
|
||||
if (!bi) {
|
||||
Sys_Printf ("PR_RelocateBuiltins: %s: undefined builtin %s\n",
|
||||
|
@ -184,19 +198,20 @@ PR_RelocateBuiltins (progs_t *pr)
|
|||
bad = 1;
|
||||
continue;
|
||||
}
|
||||
func->first_statement = -bi->binum;
|
||||
desc->first_statement = -bi->binum;
|
||||
}
|
||||
|
||||
ind = -func->first_statement;
|
||||
ind = -desc->first_statement;
|
||||
if (pr->bi_map)
|
||||
ind = pr->bi_map (pr, ind);
|
||||
bi = PR_FindBuiltinNum (pr, ind);
|
||||
if (!bi || !(proc = bi->proc)) {
|
||||
Sys_DPrintf ("WARNING: Bad builtin call number: %s = #%d\n",
|
||||
bi_name, -func->first_statement);
|
||||
bi_name, -desc->first_statement);
|
||||
proc = bi_no_function;
|
||||
}
|
||||
((bfunction_t *) func)->func = proc;
|
||||
func->first_statement = desc->first_statement;
|
||||
func->func = proc;
|
||||
}
|
||||
return !bad;
|
||||
}
|
||||
|
|
|
@ -381,11 +381,12 @@ ddef_t *
|
|||
PR_Get_Local_Def (progs_t *pr, pr_int_t offs)
|
||||
{
|
||||
pr_uint_t i;
|
||||
dfunction_t *func = pr->pr_xfunction;
|
||||
dfunction_t *func;
|
||||
pr_auxfunction_t *aux_func;
|
||||
|
||||
if (!func)
|
||||
if (!pr->pr_xfunction)
|
||||
return 0;
|
||||
func = pr->pr_xfunction->descriptor;
|
||||
aux_func = pr->auxfunction_map[func - pr->pr_functions];
|
||||
if (!aux_func)
|
||||
return 0;
|
||||
|
@ -405,15 +406,16 @@ PR_DumpState (progs_t *pr)
|
|||
if (pr_debug->int_val && pr->debug) {
|
||||
pr_lineno_t *lineno;
|
||||
pr_auxfunction_t *func = 0;
|
||||
dfunction_t *descriptor = pr->pr_xfunction->descriptor;
|
||||
pr_int_t addr = pr->pr_xstatement;
|
||||
|
||||
lineno = PR_Find_Lineno (pr, addr);
|
||||
if (lineno)
|
||||
func = PR_Get_Lineno_Func (pr, lineno);
|
||||
if (func && pr->pr_xfunction == pr->pr_functions + func->function)
|
||||
if (func && descriptor == pr->pr_functions + func->function)
|
||||
addr = PR_Get_Lineno_Addr (pr, lineno);
|
||||
else
|
||||
addr = max (pr->pr_xfunction->first_statement, addr - 5);
|
||||
addr = max (descriptor->first_statement, addr - 5);
|
||||
|
||||
while (addr != pr->pr_xstatement)
|
||||
PR_PrintStatement (pr, pr->pr_statements + addr++, 1);
|
||||
|
@ -696,7 +698,7 @@ PR_PrintStatement (progs_t *pr, dstatement_t *s, int contents)
|
|||
static void
|
||||
dump_frame (progs_t *pr, prstack_t *frame)
|
||||
{
|
||||
dfunction_t *f = frame->f;
|
||||
dfunction_t *f = frame->f->descriptor;
|
||||
|
||||
if (!f) {
|
||||
Sys_Printf ("<NO FUNCTION>\n");
|
||||
|
|
|
@ -121,7 +121,7 @@ PR_PopFrame (progs_t *pr)
|
|||
undefined behavior.
|
||||
*/
|
||||
static void
|
||||
PR_EnterFunction (progs_t *pr, dfunction_t *f)
|
||||
PR_EnterFunction (progs_t *pr, bfunction_t *f)
|
||||
{
|
||||
pr_int_t i, j, c, o;
|
||||
pr_int_t k;
|
||||
|
@ -210,7 +210,7 @@ static void
|
|||
PR_LeaveFunction (progs_t *pr)
|
||||
{
|
||||
int c;
|
||||
dfunction_t *f = pr->pr_xfunction;
|
||||
bfunction_t *f = pr->pr_xfunction;
|
||||
|
||||
PR_PopFrame (pr);
|
||||
|
||||
|
@ -279,14 +279,14 @@ signal_hook (int sig, void *data)
|
|||
VISIBLE int
|
||||
PR_CallFunction (progs_t *pr, func_t fnum)
|
||||
{
|
||||
dfunction_t *f;
|
||||
bfunction_t *f;
|
||||
|
||||
if (!fnum)
|
||||
PR_RunError (pr, "NULL function");
|
||||
f = pr->pr_functions + fnum;
|
||||
f = pr->function_table + fnum;
|
||||
if (f->first_statement < 0) {
|
||||
// negative statements are built in functions
|
||||
((bfunction_t *) f)->func (pr);
|
||||
f->func (pr);
|
||||
return 0;
|
||||
} else {
|
||||
PR_EnterFunction (pr, f);
|
||||
|
|
|
@ -74,7 +74,7 @@ PF_error (progs_t *pr)
|
|||
|
||||
s = PF_VarString (pr, 0);
|
||||
Con_Printf ("======SERVER ERROR in %s:\n%s\n",
|
||||
PR_GetString (pr, pr->pr_xfunction->s_name), s);
|
||||
PR_GetString (pr, pr->pr_xfunction->descriptor->s_name), s);
|
||||
ed = PROG_TO_EDICT (pr, *sv_globals.self);
|
||||
ED_Print (pr, ed);
|
||||
|
||||
|
@ -98,7 +98,7 @@ PF_objerror (progs_t *pr)
|
|||
|
||||
s = PF_VarString (pr, 0);
|
||||
Con_Printf ("======OBJECT ERROR in %s:\n%s\n",
|
||||
PR_GetString (pr, pr->pr_xfunction->s_name), s);
|
||||
PR_GetString (pr, pr->pr_xfunction->descriptor->s_name), s);
|
||||
ed = PROG_TO_EDICT (pr, *sv_globals.self);
|
||||
ED_Print (pr, ed);
|
||||
ED_Free (pr, ed);
|
||||
|
@ -774,7 +774,6 @@ PF_precache_model (progs_t *pr)
|
|||
void
|
||||
PF_walkmove (progs_t *pr)
|
||||
{
|
||||
dfunction_t *oldf;
|
||||
edict_t *ent;
|
||||
float yaw, dist;
|
||||
int oldself;
|
||||
|
@ -796,13 +795,11 @@ PF_walkmove (progs_t *pr)
|
|||
move[2] = 0;
|
||||
|
||||
// save program state, because SV_movestep may call other progs
|
||||
oldf = pr->pr_xfunction;
|
||||
oldself = *sv_globals.self;
|
||||
|
||||
R_FLOAT (pr) = SV_movestep (ent, move, true);
|
||||
|
||||
// restore program state
|
||||
pr->pr_xfunction = oldf;
|
||||
*sv_globals.self = oldself;
|
||||
}
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ PF_error (progs_t *pr)
|
|||
|
||||
s = PF_VarString (pr, 0);
|
||||
SV_Printf ("======SERVER ERROR in %s:\n%s\n",
|
||||
PR_GetString (pr, pr->pr_xfunction->s_name), s);
|
||||
PR_GetString (pr, pr->pr_xfunction->descriptor->s_name), s);
|
||||
ed = PROG_TO_EDICT (pr, *sv_globals.self);
|
||||
ED_Print (pr, ed);
|
||||
|
||||
|
@ -102,7 +102,7 @@ PF_objerror (progs_t *pr)
|
|||
|
||||
s = PF_VarString (pr, 0);
|
||||
SV_Printf ("======OBJECT ERROR in %s:\n%s\n",
|
||||
PR_GetString (pr, pr->pr_xfunction->s_name), s);
|
||||
PR_GetString (pr, pr->pr_xfunction->descriptor->s_name), s);
|
||||
ed = PROG_TO_EDICT (pr, *sv_globals.self);
|
||||
ED_Print (pr, ed);
|
||||
ED_Free (pr, ed);
|
||||
|
@ -799,7 +799,6 @@ PF_precache_model (progs_t *pr)
|
|||
static void
|
||||
PF_walkmove (progs_t *pr)
|
||||
{
|
||||
dfunction_t *oldf;
|
||||
edict_t *ent;
|
||||
float yaw, dist;
|
||||
int oldself;
|
||||
|
@ -821,13 +820,11 @@ PF_walkmove (progs_t *pr)
|
|||
move[2] = 0;
|
||||
|
||||
// save program state, because SV_movestep may call other progs
|
||||
oldf = pr->pr_xfunction;
|
||||
oldself = *sv_globals.self;
|
||||
|
||||
R_FLOAT (pr) = SV_movestep (ent, move, true);
|
||||
|
||||
// restore program state
|
||||
pr->pr_xfunction = oldf;
|
||||
*sv_globals.self = oldself;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,12 @@ static __attribute__ ((used)) const char rcsid[] =
|
|||
|
||||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
@ -61,10 +67,20 @@ disassemble_progs (progs_t *pr)
|
|||
unsigned int i;
|
||||
|
||||
for (i = 0; i < pr->progs->numstatements; i++) {
|
||||
dfunction_t *f = func_find (i);
|
||||
if (f) {
|
||||
Sys_Printf ("%s:\n", PR_GetString (pr, f->s_name));
|
||||
pr->pr_xfunction = f;
|
||||
dfunction_t *desc = func_find (i);
|
||||
|
||||
if (desc) {
|
||||
bfunction_t func;
|
||||
|
||||
func.first_statement = desc->first_statement;
|
||||
func.parm_start = desc->parm_start;
|
||||
func.locals = desc->locals;
|
||||
func.numparms = desc->numparms;
|
||||
memcpy (func.parm_size, desc->parm_size, sizeof (func.parm_size));
|
||||
func.descriptor = desc;
|
||||
|
||||
Sys_Printf ("%s:\n", PR_GetString (pr, desc->s_name));
|
||||
pr->pr_xfunction = &func;
|
||||
}
|
||||
PR_PrintStatement (pr, &pr->pr_statements[i], 0);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue