Chiunque ha un riferimento per la rappresentazione di va_list
nell'ABI x86_64 (quello utilizzato su Linux)? Sto cercando di eseguire il debug del codice in cui la pila o argomenti sembrano corrotta e sarebbe davvero aiutare a capire quello che sto suppone di essere visto ...Qual è il formato della struttura va_list x86_64?
risposta
ho fatto il mio commento in una risposta.
This may help. È un riferimento, anche se leggero.
la variabile inizia riferimento lista degli argomenti a pagina 50, allora si perviene, pagina 52-53 documenti va_list
:
Il tipo va_list
Il tipo va_list è una matrice contenente un elemento singolo di una struttura contenente le informazioni necessarie per implementare la macro va_arg . La definizione C de fi di va_list tipo è riportata nella figura 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];
il va_start Macro
La macro va_start inizializza la struttura come segue:
reg_save_area
I punti dell'elemento a l'inizio dell'area di salvataggio del registro.
overflow_arg_area
Questo puntatore viene utilizzato per recuperare gli argomenti passati nello stack . Viene inizializzato con l'indirizzo del primo argomento passato su lo stack, se presente, e quindi sempre aggiornato per indicare l'inizio dell'argomento successivo nello stack.
gp_offset
L'elemento contiene l'offset in byte da reg_save_area al luogo dove parato disponibile successivo generale scopo registro argomento. Nel caso tutti i registri degli argomenti sono stati scaricati , è impostato sul valore 48 (6 * 8).
fp_offset
L'elemento contiene l'offset in byte dal reg_save_area al luogo cui è salvato successivo disponibile floating point registro l'argomento. Nel caso tutti i registri degli argomenti sono stati scaricati , è impostato sul valore 304 (6 * 8 + 16 * 16).
Grazie. Sto accettando questo e anche mettendo una spiegazione del problema e come l'ho risolto come un'altra risposta. –
@R ..: Felice di aiutare. – Skurmedel
Sono abbastanza sicuro che questi registri "in virgola mobile" siano in realtà registri SSE e che ce ne siano solo 8. –
Si scopre che il problema è che gcc sta rendendo va_list
un tipo di matrice.La mia funzione era della firma:
void foo(va_list ap);
e volevo passare un puntatore a ap
a un'altra funzione, così ho fatto:
void foo(va_list ap)
{
bar(&ap);
}
Purtroppo, tipi di array decadimento ai tipi di puntatore in liste di argomenti di funzione , quindi piuttosto che passare un puntatore alla struttura originale, stavo passando un puntatore a un puntatore.
Per aggirare il problema, ho cambiato il codice per:
void foo(va_list ap)
{
va_list ap2;
va_copy(ap2, ap);
bar(&ap2);
va_end(ap2);
}
Questa è l'unica soluzione portatile ho potuto trovare, che tiene conto sia la possibilità che va_list
è un tipo di matrice e la possibilità che non lo è.
Non potresti aver appena fatto 'pippo'? Prendere un argomento di tipo' va_list * '? – caf
@caf: 'foo' ha una firma fissa che non posso cambiare. E anche se no, le funzioni 'v *' accettano sempre un argomento 'va_list', non un argomento' va_list * '. Questa è una convenzione standard e sarebbe una seccatura per gli utenti della funzione violarla. –
Perché hai dovuto passare un puntatore a ap2 nella chiamata a bar()? – ydroneaud
Per chi ama il vicinato: cosa stai pensando? Non è fuori tema; si tratta di programmare su Linux! –