Question

I have a c-function that uses varadic arguments in a standard fashion, below a simplified example:

    void func(parameter,...) {
     va_list args;
     va_start(args, parameter);

     //process args
     v1 = va_arg(args,sometype);
     v2 = va_arg(args,sometype);
        ...
     vn = va_arg(args,sometype);

     va_end(args);
}


//call func

func(parameter, p1, p2, ..., pn);

On all devices armv7s and lower as well as all simulators including 64-bit simulator this succeeds and variable v1 to vn is assigned p1 to pn, but when this executes on arm64 it seems like the variadic list is backwards ( v1 = pn, v2 = pn-1, ..., vn = p1)

Is there any fix for this? Or did I miss the documentation describing this change?

Thanks

EDIT:

I failed to mention a key element to this issue that I didn't think to mention before. I was attempting to swizzle non-variadic functions with a generic variadic function.

Note: the compiler being used was Apple LLVM 5.0

Was it helpful?

Solution 2

First, I want to apologize for not responding in a reasonable amount of time. I've been heads-down the this past month.

I posted this question on the Apple forum and it seems that the manner the parameters are packed in variadic functions differs from a the way non-variadic functions pack parameters.

So, while this works in armv7 and armv7s, you can't depend on it to work in arm64 or even if a high level of optimization is applied.

I feel that if this is true it sort of violates the ABI, but I'll take it for what it is.

OTHER TIPS

I suspect this is to do with a change in how arguments are passed to functions.

There are three ways of doing this: in registers, on the stack and a combination of both that depends on the number and type of arguments. It seems there is a difference across ARMv6, ARMv7 and ARM64 architectures as to which convention the ABI adheres to.

Regardless of the actual convention, the compiler should be handling this transparently, so you may have to look into updating your toolchain if it's not behaving as per the standard (You don't mention the compiler in your question but this is key).

Apple's documentation on the different calling conventions across different architecture versions may be helpful here to track down any changes not accounted for by your compiler.

For more information on how ARM expects the arguments to be passed, see section 5.5 of Procedure Call Standard for the ARM architecture(ARMv6, ARMv7 and section 5.4 in the 64 bit version of the ABI

Varargs only work if you use the same types in the caller and callee. If for example you pass 1 and try to read it as an NSInteger, that fails on 64 bit because the programmer didn't understand varargs, not because of a compiler bug.

We still haven't seen any code that fails.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top