Linux Kernel - почему адрес функции в System.map является одним байтом, предшествующим его адресу, как показано в режиме реального времени? - программирование

Linux Kernel - почему адрес функции в System.map является одним байтом, предшествующим его адресу, как показано в режиме реального времени?

В исходном коде ядра Linux добавлены эти строки в код tasklet_action:

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

На выходе я получаю:

tasklet_action = c03441a1
tasklet_action = c03441a1
tasklet_action = c03441a1

Но при поиске в файле system.map адрес tasklet_action находится в c03441a0, поэтому есть смещение в 1 байт.

  • Почему у меня есть это смещение?
  • Всегда ли это однобайтное смещение?
4b9b3361

Ответ 1

Я предполагаю, что вы работаете в режиме ARM в режиме Thumb или в какой-то другой архитектуре, которая использует нижний бит указателя функции, чтобы указать, какой из режимов должен выполняться.

Если это так, ответ заключается в том, что ваша функция действительно находится по адресу в system.map.

Значение, которое вы получаете во время выполнения, - это местоположение и режим.

Инструкции по этим типам архитектур всегда должны быть выровнены по 2 или 4 байта, что оставило бы нижний бит всегда равным нулю. Когда архитектура выросла в дополнительном режиме, дизайнеры использовали бит "впустую" для кодирования режима. Это умный, но запутанный, а не только для вас: много программного обеспечения, вроде отладчиков, во многих неприятных случаях вошло, когда это было впервые изобретено.

Концепция особенно запутанна для программистов x86, которые используются для инструкций переменной длины с любым случайным выравниванием.