Pregunta

I'm writing a 64bit operating system using g++, and I have a variadic function like:

void DbgPrint(const char *fmt, ...);

which shall behave quite like printf. The problem here is that g++ follows the System V ABI, and thus it passes the first arguments in RDI, RSI, RDX, RCX, R8, R9, then pushes remaining (if any) on the stack.

Using the old stdarg.h macros va_start, va_arg, etc, with cdecl, was all quite easy as va_arg just took the next element on the stack. But now those macros won't work at all until the 7th argument.

The only possibile solutions are (IMHO):

  • Forcing g++ to create a cdecl function. This seems impossible as __attribute__((cdecl)) is deliberately and clearly highlighted as ignored.
  • Have a new set of macros that work with the new way of passing arguments.

(I'm actually working on Win, so I don't have the glibc headers to check their implementation).

Anyone with a solution? Thanks in advance.

¿Fue útil?

Solución

stdarg.h is NOT part of libc, it's part of the compiler itself. So if you're using g++ it should have a stdarg.h that comes with it to handle this -- it generally gets installed in gcc's private include directory, which is searched automatically before the system includes.

If you look in gcc's stdarg.h, you see that the va_ macros are all defined to map to __builtin functions that the compiler magically knows how to deal with:

typedef __builtin_va_list __gnuc_va_list;
typedef __gnuc_va_list va_list;

#define va_start(v,l)   __builtin_va_start(v,l)
#define va_end(v)   __builtin_va_end(v)
#define va_arg(v,l) __builtin_va_arg(v,l)

and those builtins all understand the calling conventions that are used by the target ABI.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top