Компоновщик не занимается поиском макросов. Макросы обрабатываются препроцессором, который запускается задолго до компоновщика. Если компоновщик жалуется на неопределенную ссылку, это означает, что расширение макроса пошло не так. Он излучает KERNEL_THREAD_SAVED_KERNEL_TOP_OFFSET
там, где его не должно быть.
Проблема связана с
SET_KERNEL_THREAD_TOP_OFFSET(KERNEL_THREAD_SAVED_KERNEL_TOP_OFFSET, rbx)
, которая будет расширяться до
"movq " "KERNEL_THREAD_SAVED_KERNEL_TOP_OFFSET" "(%%" "rbx" "), %%rsp \n"
, тогда как вы хотите, чтобы она расширялась into (используя значение в kthread.h
)
"movq " "208" "(%%" "rbx" "), %%rsp \n"
Причина, по которой это происходит, заключается в том, как обрабатываются аргументы для работы подобно макросам. Они не имеют промежуточного раскрытия go при использовании в операторе строкового кодирования #
.
Вы можете обойти это, введя слой косвенности.
#define SET_KERNEL_THREAD_TOP_OFFSET(offset, reg) \
SET_KERNEL_THREAD_TOP_OFFSET_(offset, reg)
#define SET_KERNEL_THREAD_TOP_OFFSET_(offset, reg) \
"movq " #offset "(%%" #reg "), %%rsp \n"
Теперь, когда вы пытаетесь выполнить расширение, оно расширяется за несколько проходов. Сначала
SET_KERNEL_THREAD_TOP_OFFSET_(208, rbx)
(rbx
не является именем макроса, поэтому он остается неизменным). Это тогда становится
"movq " "208" "(%%" "rbx" "), %%rsp \n"