Jump to page: 1 2
Thread overview
[Issue 9495] Win64 vararg issue when first argument is > 8 byte
Jan 24, 2015
yebblies
Jan 24, 2015
Benjamin Thaut
Jan 25, 2015
yebblies
Jan 25, 2015
Benjamin Thaut
Jan 25, 2015
yebblies
Jan 25, 2015
yebblies
January 24, 2015
https://issues.dlang.org/show_bug.cgi?id=9495

yebblies <yebblies@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
                 CC|                            |yebblies@gmail.com
         Resolution|FIXED                       |---

--- Comment #3 from yebblies <yebblies@gmail.com> ---
This bug still exists for va_start.

--
January 24, 2015
https://issues.dlang.org/show_bug.cgi?id=9495

--- Comment #4 from Benjamin Thaut <code@benjamin-thaut.de> ---
(In reply to yebblies from comment #3)
> This bug still exists for va_start.

Repo case?

--
January 25, 2015
https://issues.dlang.org/show_bug.cgi?id=9495

--- Comment #5 from yebblies <yebblies@gmail.com> ---
(In reply to Benjamin Thaut from comment #4)
> Repo case?

>From https://github.com/D-Programming-Language/phobos/pull/2902

void printf(string format, ...)
{
    va_list ap;
    va_start(ap, format);
    vprintf(format, ap);
    va_end(ap);
}

va_start does something like `ap = (cast(void*)&format + size_t.sizeof)`, which
doesn't work as &format is the address of where the slice is stored on the
stack, not the address of where the low-level argument (a pointer to the slice)
was passed.

A workaround is to pass const(char)* only or pass ptr and length in distinct parameters to avoid the >8 bytes case in the abi.

--
January 25, 2015
https://issues.dlang.org/show_bug.cgi?id=9495

--- Comment #6 from Benjamin Thaut <code@benjamin-thaut.de> ---
But this is then a completely different issue. The page https://msdn.microsoft.com/en-us/library/ms235286.aspx states for the Win64 calling convention:

"Any argument that doesn’t fit in 8 bytes, or is not 1, 2, 4, or 8 bytes, must be passed by reference."

That means the implementation of the argument passing is correct. The issue is va_start which relies on "format" _not_ beeing passed by reference, which is clearly not the case for win 64.

For a propper implementation on Win64 you could do:

va_list ap = cast(va_list)_argptr;


I also don't see any way to fix va_start other then maybe inline assembly or turning it into a compiler intrinsic.

--
January 25, 2015
https://issues.dlang.org/show_bug.cgi?id=9495

--- Comment #7 from yebblies <yebblies@gmail.com> ---
(In reply to Benjamin Thaut from comment #6)
> But this is then a completely different issue. The page https://msdn.microsoft.com/en-us/library/ms235286.aspx states for the Win64 calling convention:
> 
> "Any argument that doesn’t fit in 8 bytes, or is not 1, 2, 4, or 8 bytes, must be passed by reference."
> 
> That means the implementation of the argument passing is correct. The issue is va_start which relies on "format" _not_ beeing passed by reference, which is clearly not the case for win 64.

Basically.  va_start just does va = &lastNamedArg + sizeof(void*)

> For a propper implementation on Win64 you could do:
> 
> va_list ap = cast(va_list)_argptr;
> 

I consider the varargs implementation to be broken so long as the portable interface doesn't work.  I don't think _argptr works for extern(C) vararg functions on win64, as the offset is calculated in the frontend where it is impossible to get the address of the stack slot the struct reference is stored in.

> 
> I also don't see any way to fix va_start other then maybe inline assembly or turning it into a compiler intrinsic.

Yes, I am working on turning it into a compiler intrinsic.

--
January 25, 2015
https://issues.dlang.org/show_bug.cgi?id=9495

--- Comment #8 from yebblies <yebblies@gmail.com> ---
See https://github.com/D-Programming-Language/dmd/pull/4336

--
January 25, 2015
https://issues.dlang.org/show_bug.cgi?id=9495

--- Comment #10 from github-bugzilla@puremagic.com ---
Commits pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/185b0ab5fdef3592b0a9bdd2d0fef32dfb59c1e7 Fix Issue 9495 - Win64 vararg issue when first argument is > 8 byte

https://github.com/D-Programming-Language/dmd/commit/32b8adabb57f3c7780049cc9cedfedb113e699e2 Merge pull request #4336 from yebblies/issue9495

Issue 9495 - Win64 vararg issue when first argument is > 8 byte

--
January 25, 2015
https://issues.dlang.org/show_bug.cgi?id=9495

--- Comment #9 from github-bugzilla@puremagic.com ---
Commit pushed to master at https://github.com/D-Programming-Language/druntime

https://github.com/D-Programming-Language/druntime/commit/153a0de0d89d36ae54d497d38fc9ea2f19969ea6 Merge pull request #1126 from yebblies/issue9495

Required fix for issue 9495

--
January 25, 2015
https://issues.dlang.org/show_bug.cgi?id=9495

github-bugzilla@puremagic.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|REOPENED                    |RESOLVED
         Resolution|---                         |FIXED

--
February 19, 2015
https://issues.dlang.org/show_bug.cgi?id=9495

--- Comment #11 from github-bugzilla@puremagic.com ---
Commit pushed to 2.067 at https://github.com/D-Programming-Language/druntime

https://github.com/D-Programming-Language/druntime/commit/153a0de0d89d36ae54d497d38fc9ea2f19969ea6 Merge pull request #1126 from yebblies/issue9495

--
« First   ‹ Prev
1 2