Noyau Linux – Pourquoi l’adresse d’une fonction dans System.map est-elle un octet précédant son adresse, telle qu’elle est vue en temps réel?

Dans le code source du kernel linux, tasklet_action ces lignes dans le code de la tasklet_action :

 printk("tasklet_action = %p\n" , *tasklet_action); printk("tasklet_action = %p\n" , &tasklet_action); printk("tasklet_action = %p\n" , tasklet_action); 

Dans la sortie je reçois:

 tasklet_action = c03441a1 tasklet_action = c03441a1 tasklet_action = c03441a1 

Mais lors de la recherche dans le fichier tasklet_action adresse tasklet_action est à c03441a0 il y a donc un décalage de 1 octet.

  • Pourquoi ai-je cette compensation?
  • Est-ce toujours un décalage d’un octet?

Je suppose que vous utilisez ARM en mode Thumb ou une autre architecture utilisant le bit inférieur du pointeur de fonction pour indiquer le mode à exécuter.

Si oui, la réponse est que votre fonction est vraiment située à l’adresse dans le system.map .

La valeur obtenue à l’exécution correspond à l’emplacement et au mode .

Les instructions, sur ces types d’architectures, doivent toujours être alignées sur 2 ou 4 octets, ce qui laisserait le bit du bas toujours égal à zéro. Lorsque l’architecture a développé un mode supplémentaire, les concepteurs ont utilisé le bit ‘gaspillé’ pour encoder le mode. C’est astucieux, mais déroutant, et pas seulement pour vous: beaucoup de logiciels, comme les débogueurs, ont brisé de nombreuses manières désagréables quand cela a été inventé pour la première fois.

Le concept est particulièrement déroutant pour les programmeurs x86 qui sont habitués à des instructions de longueur variable avec tout alignement aléatoire.