#50 va_arg broken on 64-bit linux

closed-fixed
nobody
None
5
2006-11-29
2006-11-29
Anonymous
No

The transformation of va_arg is broken on 64-bit linux. The problem seems to be that __builtin_va_arg is prototyped with arguments (va_list, uint) in cil.ml but this should be (va_list, ulong). The problem manifests itself when
va_arg(ap, int) is transformed to
__builtin_va_arg(ap, (unsigned int) sizeof(int)) which is no longer matched by the pattern in cabs2cil.ml (the pattern is "marker :: SizeOf resType :: _".

The fix may be simply to change the prototype to take ulong, although a more robust fix may be to prevent CIL from doing any transformations to the code after va_arg is parsed into the SizeOf() form.

Discussion

  • Matt Harren
    Matt Harren
    2006-11-29

    Logged In: YES
    user_id=1278428
    Originator: NO

    Hi,

    We just found this last week. The solution is to change the type of prototype to take "!typeOfSizeOf" instead of "intType", but doing this required delaying initialization of the builtins hashtable until after initCIL is called. This is fixed in our version of CIL, but we haven't gotten anonymous Subversion access set up yet. So here's a simpler workaround: just change the match code.

    Thanks!
    Matt

    --- src/frontc/cabs2cil.ml (revision 8093)
    +++ src/frontc/cabs2cil.ml (working copy)
    @@ -3791,7 +3791,8 @@
    Lval(Var fv, NoOffset) -> begin
    if fv.vname = "__builtin_va_arg" then begin
    match !pargs with
    - marker :: SizeOf resTyp :: _ -> begin
    + marker :: SizeOf resTyp :: _
    + | marker :: CastE(_, SizeOf resTyp) :: _ -> begin
    (* Make a variable of the desired type *)
    let destlv, destlvtyp =
    match !pwhat with

     
  • Matt Harren
    Matt Harren
    2006-11-29

    • status: open --> closed-fixed