2011-02-10 13 views
18

Cualquiera tiene una referencia para la representación de va_list en x86_64 ABI (la utilizada en Linux)? Estoy tratando de depurar un poco de código en la pila o argumentos parecen corrupto y que sería de gran ayuda para entender lo que estoy supone a estar viendo ...¿Cuál es el formato de la estructura va_list x86_64?

+11

Para el que se acerca: ¿qué estás pensando? No está fuera de tema; ¡se trata de programar en Linux! –

Respuesta

24

hice mi comentario en una respuesta.

This may help. Es una referencia, aunque ligera.

la referencia de lista de argumentos variable comienza en la página 50, luego continúa, página 52-53 documentos va_list:

El Tipo va_list

El tipo va_list es una matriz que contiene un único elemento de una estructura que contiene la información necesaria para implementar la macro va_arg . La definición C de fi de va_list tipo se da en la fi gura 3,34

// Figure 3.34 
typedef struct { 
    unsigned int gp_offset; 
    unsigned int fp_offset; 
    void *overflow_arg_area; 
    void *reg_save_area; 
} va_list[1]; 

El va_start Macro

La macro va_start inicializa la estructura como sigue:

reg_save_area Los puntos elemento a el inicio del área de guardar registro.

overflow_arg_area Este puntero se utiliza para recuperar argumentos pasados ​​en la pila . Se inicializa con la dirección del primer argumento pasado en la pila, si existe, y luego siempre actualizada para apuntar al inicio del siguiente argumento en la pila.

gp_offset El elemento tiene el desplazamiento en bytes desde reg_save_area al lugar donde se guarda el siguiente registro general argumento finalidad disponible. En caso todos los registros de argumento han sido agotado, se establece en el valor 48 (6 * 8).

fp_offset El elemento tiene el desplazamiento en bytes desde reg_save_area al lugar donde se guarda la siguiente disposición flotante punto de registro de argumentos. En caso todos los registros de argumento han sido agotado, se establece en el valor 304 (6 * 8 + 16 * 16).

+0

Gracias. Estoy aceptando esto y también estoy explicando el problema y cómo lo resolví como otra respuesta. –

+0

@R ..: Me alegra ayudar. – Skurmedel

+0

Estoy bastante seguro de que estos registros de "coma flotante" son realmente registros SSE, y que solo hay 8 de ellos. –

13

Resulta que el problema fue que gcc hizo va_list un tipo de matriz.Mi función era la de la firma:

void foo(va_list ap); 

y quería pasar un puntero a ap a otra función, por lo que hizo:

void foo(va_list ap) 
{ 
    bar(&ap); 
} 

Por desgracia, los tipos de matriz descomposición de los tipos de puntero en las listas de argumentos de funciones , entonces, en lugar de pasar un puntero a la estructura original, estaba pasando un puntero a un puntero.

Para evitar el problema, he cambiado el código para:

void foo(va_list ap) 
{ 
    va_list ap2; 
    va_copy(ap2, ap); 
    bar(&ap2); 
    va_end(ap2); 
} 

Ésta es la única solución portátil que podía llegar a, que tenga en cuenta tanto la posibilidad de que va_list es un tipo de matriz y la posibilidad eso no es

+0

¿No podría haber hecho 'foo' tomar un argumento de tipo' va_list * '? – caf

+1

@caf: 'foo' tiene una firma fija que no puedo cambiar. E incluso si no, las funciones 'v *' siempre toman un argumento 'va_list', no un argumento' va_list * '. Esta es una convención estándar y sería molesto para los usuarios de la función violarla. –

+0

¿Por qué necesitó pasar un puntero a ap2 en la llamada a bar()? – ydroneaud

Cuestiones relacionadas