I've spotted a likely candidate for the mcode stack
problem while looking through the debug instruction
output from the back end.

 I have not yet verified that the emitted binary code
has the duplicated Emit_Call's shown below, but if they
are there, then this could very well be causing the weird
stack-alignment-dependent crashes.

 I also have not looked into what is causing these
doubled-up calls to be generated, nor for any other
side effects caused by this two-for-one special.

Detail:

In the 0.29.1 debug output below, note that 'Setup_Frame'
is followed by duplicate, back-to-back, 'call's.
( also see end of message for 0.25 vs. 0.29.1 output )

"  Setup_Frame
"  push (fp,-16 {INSTANCE})
"  call:Nil  work__tristate_bug__ARCH__crashes__ELAB
"  call:Nil  work__tristate_bug__ARCH__crashes__ELAB

Looking at the call support routines in
<ortho\mcode\ortho_code-x86-emits.adb>

 Emit_Setup_Frame:
   if Get_Subprg_Stack space required is not aligned
   on Flags.Stack_Boundary, pad stack as needed

 Emit_Call:
   - Gen_Call calls the subprogram
   - Cleanup stack
       Val =  Get_Subprg_Stack + alignment padding
       addl esp,Val

 So, if Emit_Call is ever invoked __without__ a preceding
Emit_Setup_Frame, Bad Things will happen whenever the
Emit_Call cleanup code attempts to remove stack alignment
padding that is not actually there.

 Whether the stack actually gets padded so as to expose
this problem is dependent on the stack alignment settings,
current stack alignment, number of args, etc.

Brian


Example debug output snippet from GHDL 0.25

command line:
ghdl -r  --be-debug=i --workdir=work.ghd tristate_bug

-----------

1214   public procedure __ghdl_ELABORATE
  # block start
 1216   block until 1218
 1217   local ARCH_INSTANCE: 1102, offset=-12
 1218   local INSTANCE: 1094, offset=-16
  push [00000010]
  reg_7{ax  } = call:P32 __ghdl_malloc0
  assign:P32 (fp,-12 {ARCH_INSTANCE}) <- reg_7{ax  }
  reg_12{ax  } = indir:P32 (fp,-12 {ARCH_INSTANCE})
  assign:P32 (fp,-16 {INSTANCE}) <- reg_12{ax  }
  reg_20{ax  } = indir:P32 (fp,-16 {INSTANCE})
  assign:P32 (reg_20{ax  } + [00000004]) <- [00000000]
  reg_27{ax  } = indir:P32 (fp,-12 {ARCH_INSTANCE})
  assign:P32 (&__ghdl_rti_top_instance) <- reg_27{ax  }
  assign:P32 (&__ghdl_rti_top_ptr) <- &__ghdl_rti_top
  push (fp,-16 {INSTANCE})
  call:Nil  work__tristate_bug__ARCH__crashes__ELAB
  push (fp,-12 {ARCH_INSTANCE})
  call:Nil  work__tristate_bug__ARCH__crashes__DEFAULT_CONFIG
  # block end
L3:
leave

-----------


Example debug output snippet from GHDL 0.29.1 patched
-----
<ortho\mcode\ortho_code-x86-abi.adb>
+        when OE_Setup_Frame =>
+           Put_Line ("  Setup_Frame");

         when OE_Call =>
            if Get_Expr_Mode (Stmt) /= Mode_Nil then
-----

command line:
ghdl -r  --be-debug=i --workdir=work.ghd tristate_bug

-----------

1249   public procedure __ghdl_ELABORATE
  # block start
 1251   block until 1253
 1252   local ARCH_INSTANCE: 1106, offset=-12
 1253   local INSTANCE: 1098, offset=-16
  Setup_Frame
  push [00000012]
  reg_7{ax  } = call:P32 __ghdl_malloc0
  assign:P32 (fp,-12 {ARCH_INSTANCE}) <- reg_7{ax  }
  reg_12{ax  } = indir:P32 (fp,-12 {ARCH_INSTANCE})
  assign:P32 (fp,-16 {INSTANCE}) <- reg_12{ax  }
  reg_20{ax  } = indir:P32 (fp,-16 {INSTANCE})
  assign:P32 (reg_20{ax  } + [00000004]) <- [00000000]
  reg_27{ax  } = indir:P32 (fp,-12 {ARCH_INSTANCE})
  assign:P32 (&__ghdl_rti_top_instance) <- reg_27{ax  }
  assign:P32 (&__ghdl_rti_top_ptr) <- &__ghdl_rti_top
  Setup_Frame
  push (fp,-16 {INSTANCE})
  call:Nil  work__tristate_bug__ARCH__crashes__ELAB
  call:Nil  work__tristate_bug__ARCH__crashes__ELAB
  Setup_Frame
  push (fp,-12 {ARCH_INSTANCE})
  call:Nil  work__tristate_bug__ARCH__crashes__DEFAULT_CONFIG
  call:Nil  work__tristate_bug__ARCH__crashes__DEFAULT_CONFIG
  # block end
L3:
leave

-----------



_______________________________________________
Ghdl-discuss mailing list
[email protected]
https://mail.gna.org/listinfo/ghdl-discuss

Reply via email to