Domanda

Ho scritto un programma di "pericoloso" in C ++ che salta avanti e indietro da uno stack frame ad un altro. L'obiettivo è quello di essere salto dal livello più basso di una chiamata pila a un chiamante, fare qualcosa, e poi salta giù di nuovo, ogni volta saltare tutte le chiamate in mezzo.

Lo faccio modificando manualmente il (%ebp impostazione) indirizzo di base stack e saltare ad un indirizzo di etichetta. E 'del tutto funziona, con gcc e ICC sia, senza alcun danneggiamento di stack a tutti. Il giorno questo ha funzionato è stata una giornata fredda.

Ora sto prendendo lo stesso programma e ri-scrittura in C, e non funziona. In particolare, non funziona con gcc v4.0.1 (Mac OS). Una volta che mi salta alla nuova stack frame (con il puntatore base dello stack impostato correttamente), le seguenti istruzioni vengono eseguite, essendo appena prima di una chiamata a fprintf. L'ultima istruzione elencati qui si blocca, NULL dereferenziazione:

lea    0x18b8(%ebx), %eax
mov    (%eax), %eax
mov    (%eax), %eax

Ho fatto qualche debug, e ho capito che impostando manualmente il registro %ebx quando passo stack frame (utilizzando un valore ho osservato prima di lasciare la funzione in primo luogo), posso correggere il bug. Ho letto che si occupa di questo registro con "posizione del codice indipendente" in gcc.

Qual è la posizione di codice indipendente? Come funziona posizione di lavoro di codice indipendente? A che cosa è questo registro che punta?

È stato utile?

Soluzione

PIC è il codice che viene trasferita dinamicamente quando viene caricato. Il codice che è non-PIC ha indirizzi di salto e call fissati in fase di collegamento. PIC ha una tabella che fa riferimento a tutti i luoghi in cui esistono tali valori, molto simile a una dll.

Quando l'immagine viene caricata, il caricatore viene aggiornata automaticamente questi valori. Altri schemi riferimento a un valore di dati che definisce una "base" e l'indirizzo di destinazione è decisa eseguendo calcoli sulla base. La base è di solito impostata dal nuovo caricatore.

Infine, altri schemi di utilizzare vari trampolini che chiamano a noti Offset relativi. Gli spostamenti relativi contengono codice e / o di dati che vengono aggiornati da un caricatore.

Ci sono diversi motivi per cui vengono scelti diversi regimi. Alcuni sono veloci quando viene eseguito, ma più lento a caricare. Alcuni sono veloci da caricare, ma hanno meno prestazioni di runtime.

Altri suggerimenti

punti EBX alla tabella globale Offset. Vedere questo riferimento su PIC i386. Il collegamento spiega cosa PIC è una modalità di utilizzo EBX.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top