Fix the access alignment bug on 64 bit archs.

This commit is contained in:
Bill Currie 2007-04-07 01:41:23 +00:00 committed by Jeff Teunissen
parent b203512eb7
commit 124506fda2
7 changed files with 76 additions and 43 deletions

View file

@ -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];

View file

@ -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;
}

View file

@ -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");

View file

@ -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);

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);
}