Greetings! The caller is call_proc_new, and the callee LI35. At the
head of the caller, %d2 is saved to stack address 0xefffdedc:
=============================================================================
(gdb)
call_proc_new (sym=0x6f9d00, link=0x1b1350 <LnkLI276>, argd=2051,
first=0x870b48, ll=0xefffe040) at funlink.c:729
729 {object fun;
3: x/i $pc
=> 0x2c70a <call_proc_new>: linkw %fp,#-260
(gdb)
0x0002c70e 729 {object fun;
3: x/i $pc
=> 0x2c70e <call_proc_new+4>: moveml %d2-%d6/%a2-%a4,%sp@-
(gdb)
0x0002c712 729 {object fun;
3: x/i $pc
=> 0x2c712 <call_proc_new+8>: movel %fp@(16),%d3
(gdb) i reg sp
sp 0xefffdedc 0xefffdedc
(gdb) p/x *(((unsigned long *)0xefffdedc)-8)@8
$50 = {0xffffffff, 0xffffffff, 0x7fff0000, 0xffffffff, 0xffffffff,
0x7fff0000, 0xffffffff, 0xffffffff}
(gdb) p/x *(((unsigned long *)0xefffdedc)-0)@8
$51 = {0x870b48, 0x6faf30, 0x0, 0x508840, 0x50c9d8, 0x84678, 0x8adf60,
0x50cedc}
(gdb) i reg d2
d2 0x870b48 8850248
=============================================================================
This address is then clobberred in the call to LI35:
=============================================================================
(gdb)
784 return(LCAST(fn)(x0,x1,x2));
3: x/i $pc
=> 0x2cb50 <call_proc_new+1094>: movel %d1,%sp@-
(gdb)
0x0002cb52 784 return(LCAST(fn)(x0,x1,x2));
3: x/i $pc
=> 0x2cb52 <call_proc_new+1096>: movel %d0,%sp@-
(gdb)
0x0002cb54 784 return(LCAST(fn)(x0,x1,x2));
3: x/i $pc
=> 0x2cb54 <call_proc_new+1098>: movel %fp@(20),%sp@-
(gdb) i reg sp
sp 0xefffded4 0xefffded4
(gdb) p/x *(((unsigned long *)0xefffdedc)-0)@8
$52 = {0x870b48, 0x6faf30, 0x0, 0x508840, 0x50c9d8, 0x84678, 0x8adf60,
0x50cedc}
(gdb) ni
0x0002cb58 784 return(LCAST(fn)(x0,x1,x2));
3: x/i $pc
=> 0x2cb58 <call_proc_new+1102>: jsr %a4@
(gdb)
0x0002cb5a 784 return(LCAST(fn)(x0,x1,x2));
3: x/i $pc
=> 0x2cb5a <call_proc_new+1104>: lea %sp@(12),%sp
(gdb) p/x *(((unsigned long *)0xefffdedc)-0)@8
$53 = {0x50c9d8, 0x6faf30, 0x0, 0x508840, 0x50c9d8, 0x84678, 0x8adf60,
0x50cedc}
=============================================================================
Breakpoint 9, 0x0002cb58 in call_proc_new (sym=0x6f9d00,
link=0x1b1350 <LnkLI276>, argd=2051, first=0x870aa8, ll=0xefffe048)
at funlink.c:784
784 return(LCAST(fn)(x0,x1,x2));
3: x/i $pc
=> 0x2cb58 <call_proc_new+1102>: jsr %a4@
(gdb) i reg fp
fp 0xefffe000 0xefffe000
(gdb) p/x *(((unsigned long *)0xefffdedc)-0)@8
$55 = {0x870aa8, 0x6faf30, 0x0, 0x508840, 0x50c9d8, 0x84678, 0x8ad510,
0x50cedc}
(gdb) watch *(((unsigned long *)0xefffdedc)-0)
Watchpoint 10: *(((unsigned long *)0xefffdedc)-0)
(gdb) ni
Watchpoint 10: *(((unsigned long *)0xefffdedc)-0)
Old value = 8850088
New value = 5294552
LI35 (V285=0x870aa8, V284=0x6faf30, V283=0x50c9d8 <Cnil_body>,
first=0x50c9d8 <Cnil_body>) at gcl_sloop.c:1947
1947 if((V287)==Cnil){
3: x/i $pc
=> 0x10dda0 <LI35+62>: cmpal #5294552,%a3
(gdb) disassemble
Dump of assembler code for function LI35:
0x0010dd62 <+0>: linkw %fp,#0
0x0010dd66 <+4>: moveml %d2-%d5/%a2-%a5,%sp@-
0x0010dd6a <+8>: movel %fp@(8),%d2
0x0010dd6e <+12>: moveal %fp@(12),%a3
0x0010dd72 <+16>: movel 0x50796c <fcall+4>,%d4
0x0010dd78 <+22>: moveal 0x615f34 <vs_top>,%a4
0x0010dd7e <+28>: moveq #16,%d3
0x0010dd80 <+30>: addl %a4,%d3
0x0010dd82 <+32>: movel %d3,0x615f34 <vs_top>
0x0010dd88 <+38>: cmpl 0x1ae474 <vs_limit>,%d3
0x0010dd8e <+44>: bccw 0x10e03e <LI35+732>
0x0010dd92 <+48>: moveq #3,%d0
0x0010dd94 <+50>: cmpl %d4,%d0
0x0010dd96 <+52>: blts 0x10dda0 <LI35+62>
0x0010dd98 <+54>: movel #5294552,%fp@(20)
=> 0x0010dda0 <+62>: cmpal #5294552,%a3
0x0010dda6 <+68>: beqw 0x10df10 <LI35+430>
0x0010ddaa <+72>: moveal 0x1b1570 <VVi+524>,%a0
0x0010ddb0 <+78>: moveal %a0@(4),%a2
0x0010ddb4 <+82>: cmpal #5294552,%a2
0x0010ddba <+88>: beqw 0x10de6a <LI35+264>
0x0010ddbe <+92>: movel %a2@(4),%d0
---Type <return> to continue, or q <return> to quit---q
=============================================================================
Breakpoint 12, LI35 (V285=0x8708c8, V284=0x6faf30, V283=0x50c9d8 <Cnil_body>,
first=0x8708c8) at gcl_sloop.c:1924
1924 {
3: x/i $pc
=> 0x10dd62 <LI35>: linkw %fp,#0
(gdb) i reg fp
fp 0xefffe000 0xefffe000
(gdb) p/x 0xefffe000+20
$64 = 0xefffe014
(gdb) si
0x0010dd66 1924 {
3: x/i $pc
=> 0x10dd66 <LI35+4>: moveml %d2-%d5/%a2-%a5,%sp@-
(gdb) i reg fp
fp 0xefffdec8 0xefffdec8
(gdb) p/x 0xefffdec8+20
$65 = 0xefffdedc
(gdb) i reg sp
sp 0xefffdec8 0xefffdec8
=============================================================================
This code used to work for years, but now that I examine it in greater
detail, call_proc_new is missing va_end(). I don't know if that is
relevant.
Full preprocessed source and disassembly for these two functions are
below. Further details from gdb available if needed.
Take care,
--
Camm Maguire camm@maguirefamily.org
==========================================================================
"The earth is but one country, and mankind its citizens." -- Baha'u'llah
object
call_proc_new(object sym, void **link, int argd, object first, va_list ll)
{object fun;
int nargs;
check_type_symbol(&sym);
fun=sym->s.s_gfdef;
if (fun && (({register object _z=(object)(fun); ((((ufixnum)(_z))>=0xf0000000) ? t_fixnum : ((!(_z)->d.e || (((ufixnum)((*(object *)(_z))))>=0xf0000000)) ? (_z==((object)&Cnil_body) ? t_symbol : t_cons) : _z->d.t));})==t_sfun
|| ({register object _z=(object)(fun); ((((ufixnum)(_z))>=0xf0000000) ? t_fixnum : ((!(_z)->d.e || (((ufixnum)((*(object *)(_z))))>=0xf0000000)) ? (_z==((object)&Cnil_body) ? t_symbol : t_cons) : _z->d.t));})==t_gfun
|| ({register object _z=(object)(fun); ((((ufixnum)(_z))>=0xf0000000) ? t_fixnum : ((!(_z)->d.e || (((ufixnum)((*(object *)(_z))))>=0xf0000000)) ? (_z==((object)&Cnil_body) ? t_symbol : t_cons) : _z->d.t));})== t_vfun)
&& Rset)
{object (*fn)();
fn = fun->sfn.sfn_self;
if (({register object _z=(object)(fun); ((((ufixnum)(_z))>=0xf0000000) ? t_fixnum : ((!(_z)->d.e || (((ufixnum)((*(object *)(_z))))>=0xf0000000)) ? (_z==((object)&Cnil_body) ? t_symbol : t_cons) : _z->d.t));})==t_vfun)
{
nargs=(argd & 0xff);
if (nargs < fun->vfn.vfn_minargs || nargs > fun->vfn.vfn_maxargs
|| (argd & ((~0xfff) | (0xf00 & ~(1 <<11)))))
goto WRONG_ARGS;
if (((1 <<11) & argd) == 0)
{
fcall.argd = nargs;
goto AFTER_LINK;
}
}
else
{ nargs= (argd & 0xff);
if ((argd & (~(1 <<11))) != fun->sfn.sfn_argd)
WRONG_ARGS:
FEerror("Arg or result mismatch in call to ~s",1,sym);
}
(void) vpush_extend(link,sLAlink_arrayA->s.s_dbind);
(void) vpush_extend(*link,sLAlink_arrayA->s.s_dbind);
*link = (void *)fn;
AFTER_LINK:
if (nargs < 10)
{object x0,x1,x2,x3,x4,x5,x6,x7,x8,x9;
if (nargs-- > 0)
x0=first;
else
{return((*fn)());}
if (nargs-- > 0)
x1=__builtin_va_arg(ll,object);
else
{ return((*fn)(x0));}
if (nargs-- > 0)
x2=__builtin_va_arg(ll,object);
else
{return((*fn)(x0,x1));}
if (nargs-- > 0) x3=__builtin_va_arg(ll,object);
else
return((*fn)(x0,x1,x2));
if (nargs-- > 0) x4=__builtin_va_arg(ll,object);
else
return((*fn)(x0,x1,x2,x3));
if (nargs-- > 0) x5=__builtin_va_arg(ll,object);
else
return((*fn)(x0,x1,x2,x3,x4));
if (nargs-- > 0) x6=__builtin_va_arg(ll,object);
else
return((*fn)(x0,x1,x2,x3,x4,x5));
if (nargs-- > 0) x7=__builtin_va_arg(ll,object);
else
return((*fn)(x0,x1,x2,x3,x4,x5,x6));
if (nargs-- > 0) x8=__builtin_va_arg(ll,object);
else
return((*fn)(x0,x1,x2,x3,x4,x5,x6,x7));
if (nargs-- > 0) x9=__builtin_va_arg(ll,object);
else
return((*fn)(x0,x1,x2,x3,x4,x5,x6,x7,x8));
return((*fn)(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9));
}
else {
object *new;
object Xxvl[65]; {int i; new=Xxvl; if (nargs >= 65) FEerror("va_list too long",0); for (i=0 ; i < (nargs); i++) new[i]=i ? __builtin_va_arg(ll,object) : first;};
return(c_apply_n(fn,nargs,new));}
}
else
{
object fun;
register object *base;
enum ftype result_type;
if(({register object _z=(object)(sym); ((((ufixnum)(_z))>=0xf0000000) ? t_fixnum : ((!(_z)->d.e || (((ufixnum)((*(object *)(_z))))>=0xf0000000)) ? (_z==((object)&Cnil_body) ? t_symbol : t_cons) : _z->d.t));})==t_symbol) fun = symbol_function(sym);
else fun = sym;
vs_base= (base = vs_top);
if (fun == ((void *)0)) FEinvalid_function(sym);
nargs=(argd & 0xff);
result_type=((enum ftype)(((argd) & (0xf00 & ~(1 <<11))) >> 8));
(argd=(argd>>10));
{int i=0;
if (argd==0)
{while(i < nargs)
{(*vs_top++ = (i ? __builtin_va_arg(ll,object) : first));
i++;}}
else
{
while(i < nargs) {
enum ftype typ=((enum ftype)((argd=(argd>>2))& 3));
object _xx;
if (typ==f_object)
_xx=i ? __builtin_va_arg(ll,object) : first;
else {
long _yy;
_yy=i ? __builtin_va_arg(ll,fixnum) : (fixnum)first;
_xx=({register fixnum _q1=(_yy);register object _q4; _q4=(!(((_q1)+(0x8000000>>1))&-0x8000000)) ? ((object)((_q1)+(0xf0000000 +(0x8000000>>1)))) : make_fixnum1(_q1);_q4;});
}
(*vs_top++ = (_xx));
i++;
}
}
}
if (vs_top >= vs_limit) vs_overflow();
funcall(fun);
vs_top=base;
return((result_type==f_object? vs_base[0] : (object)({register object _q2=(vs_base[0]);register fixnum _q3; _q3=(((ufixnum)(_q2))>=0xf0000000) ? (((fixnum)(_q2))-(0xf0000000 +(0x8000000>>1))) : (_q2)->FIX.FIXVAL;_q3;})));
}
}
Attachment:
call_proc_new.asm
Description: call_proc_new.asm
static object LI35(object V285,object V284,object V283,object first,...)
{
va_list ap;
int narg = fcall.argd; register object *base=vs_top; register object *sup=vs_top+4;vs_top=sup; if (vs_top >= vs_limit) vs_overflow();
{register object V286;
register object V287;
object V288;
object V289;
__builtin_va_start(ap,first);
V286= V285;
V287= V284;
V288= V283;
narg = narg - 3;
if (narg <= 0) goto T698;
else {
V289= first;}
--narg; goto T699;
goto T698;
T698:;
V289= ((object)&Cnil_body);
goto T699;
T699:;
{object V290;
V290= ((object)&Cnil_body);
if((V287)==((object)&Cnil_body)){
goto T703;}
{register object x= (V287),V291= (((object)(VVi)[131])->s.s_dbind);
while(V291!=((object)&Cnil_body))
if(({register object _a=(x);register object _b=(V291->c.c_car);_a==_b || (!((((ufixnum)(_a))>=0xf0000000)||_a==((object)&Cnil_body))&&!((((ufixnum)(_b))>=0xf0000000)||_b==((object)&Cnil_body))&&eql1(_a,_b));})){
goto T704;
}else V291=V291->c.c_cdr;}
goto T703;
goto T704;
T704:;
base[0]= (((object)(VVi)[54])->s.s_dbind);
base[1]= (V287);
vs_top=(vs_base=base+0)+2;
Lgetf();
vs_top=sup;
V287= vs_base[0];
if(((V287))!=((object)&Cnil_body)){
goto T706;}
goto T703;
goto T706;
T706:;
if((((object)(VVi)[132])->s.s_dbind)==((object)&Cnil_body)){
goto T703;}
(void)((fcall.argd=3,(*(LnkLI276))((V286),((object)(VVi)[133]),(V288),({register fixnum _q1=(0);register object _q4; _q4=(!(((_q1)+(0x8000000>>1))&-0x8000000)) ? ((object)((_q1)+(0xf0000000 +(0x8000000>>1)))) : make_fixnum1(_q1);_q4;}))));
goto T703;
T703:;
if(((V287))==((object)&Cnil_body)){
goto T711;}
if(((V288))!=((object)&Cnil_body)){
goto T712;}
if(((((object)(VVi)[47])->s.s_dbind))!=((object)&Cnil_body)){
goto T711;}
goto T712;
T712:;
{register object V292;
register object V293;
V292= (((object)(VVi)[46])->s.s_dbind);
V293= ((V292))->c.c_car;
goto T722;
T722:;
if(!(((V292))==((object)&Cnil_body))){
goto T723;}
goto T718;
goto T723;
T723:;
{register object x= (V286),V294= ((V293))->c.c_car;
while(V294!=((object)&Cnil_body))
if(({register object _a=(x);register object _b=(V294->c.c_car->c.c_car);_a==_b || (!((((ufixnum)(_a))>=0xf0000000)||_a==((object)&Cnil_body))&&!((((ufixnum)(_b))>=0xf0000000)||_b==((object)&Cnil_body))&&eql1(_a,_b));}) &&V294->c.c_car != ((object)&Cnil_body)){
goto T729;
}else V294=V294->c.c_cdr;
goto T727;}
goto T729;
T729:;
V290= ((object)&Ct_body);
{object V295;
register object V296;
register object V297;
if(!(({register object _z=(object)((V287)); ((((ufixnum)(_z))>=0xf0000000) ? t_fixnum : ((!(_z)->d.e || (((ufixnum)((*(object *)(_z))))>=0xf0000000)) ? (_z==((object)&Cnil_body) ? t_symbol : t_cons) : _z->d.t));})==t_cons)){
goto T735;}
if(!((((V287))->c.c_car)==(((object)(VVi)[122])))){
goto T735;}
V295= list(3,((object)(VVi)[122]),((V287))->c.c_cdr->c.c_car,(V286));
goto T733;
goto T735;
T735:;
if(((V289))==((object)&Cnil_body)){
goto T740;}
V295= list(3,((object)(VVi)[122]),(V287),(V286));
goto T733;
goto T740;
T740:;
V295= list(2,(V287),(V286));
goto T733;
T733:;
V296= (V293);
base[0]= (V295);
base[1]= ((V296))->c.c_cdr;
base[2]= ((object)(VVi)[30]);
base[3]= ((object)(VVi)[113]);
vs_top=(vs_base=base+0)+4;
Ladjoin();
vs_top=sup;
V297= vs_base[0];
((V296))->c.c_cdr = (V297);}
goto T718;
goto T727;
T727:;
V292= ((V292))->c.c_cdr;
V293= ((V292))->c.c_car;
goto T722;}
goto T718;
T718:;
if((V290)!=((object)&Cnil_body)){
goto T711;}
if((((object)(VVi)[53])->s.s_dbind)!=((object)&Cnil_body)){
goto T711;}
(void)((fcall.argd=2,(*(LnkLI247))(((object)(VVi)[134]),(V286))));
goto T711;
T711:;
{object V298 = (V286);
vs_top=base ; return(V298);}}
__builtin_va_end(ap);
base[0]=base[0];
return ((object)&Cnil_body);}
}
Attachment:
LI35.asm
Description: LI35.asm