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 c...@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;}))); } }
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);} }
LI35.asm
Description: LI35.asm