Identifier si une adresse appartient à tas ou stack ou registres

J’ai un pointeur disponible avec moi pour une variable C / C ++. Est-il possible de déterminer exactement à quel segment de la mémoire cette variable appartient? Si oui comment?

Remarque: je n’ai que l’adresse de cette variable, aucune information supplémentaire si la variable est locale / globale, etc.

Déterminez si votre architecture comporte des pointeurs sur votre région de tas ou de stack. Il y a généralement des stackpointers ou des framepointers.

Comparez ensuite votre adresse réelle à ces adresses et décidez à quoi elles appartiennent.

Si vous utilisez linux (vous n’êtes pas sûr des autres systèmes), vous pourrez peut-être trouver les informations dans le fichier /proc//maps

Vous pouvez d’abord identifier le début et la fin des différentes sections de votre exécutable. Pour cela, vous devez éventuellement append des variables dans le script de l’éditeur de liens autour de chaque section, comme ceci:

 SECTIONS { [...] .data : { data_start = .; *(.data) data_end = .; } [...] } 

Vous pouvez ensuite déclarer ces variables comme externes dans votre code C / C ++ et les utiliser directement pour comparer l’adresse que vous souhaitez identifier.

Il peut ne pas être facile de modifier le script de l’éditeur de liens. Avec gcc, vous pouvez le vider avec:

 gcc -Wl,-verbose whatever.c 

puis essayez de trouver les variables déjà définies dans la sortie (désordonnée).

Pour obtenir les limites de la stack, vous pouvez instancier une variable muette au début de votre fonction main (), enregistrer son adresse en haut de la stack, puis en instancier une autre à la position actuelle, ce qui vous donnera le bas. . Cependant, notez que le compilateur peut ne pas se comporter exactement de la même manière (l’ordre de stack des variables en C n’est pas garanti, pas même l’utilisation de la stack), donc cela devrait fonctionner sans être portable.

Enfin, pour le tas, je n’ai aucune astuce. Je voudrais simplement en déduire qu’une variable ne figurant pas dans data / bss / dérivé et non dans la stack serait dans le tas (à l’exclusion des registres, mais si vous pouvez obtenir l’adresse, je parierais que le compilateur n’utilisera jamais de stockage de registre seulement ).

Je ne sais pas exactement si cela correspond à votre situation, mais vous pouvez essayer objdump -t pour voir la table des symboles d’un fichier elf. Tout ce dont vous avez besoin est l’adresse de votre variable. Vous y trouverez des drapeaux indiquant la section de chaque variable. Reportez-vous à la page de objdump pour plus de détails.

Exemple de sortie:

 0804a020 g O .bss 00000004 var 

Il est dit que var est un object 0804a020 dans l’adresse 0804a020 , section .bss