Я занимаюсь разработкой для встраиваемой платформы, и мне трудно разобраться, как динамически связывать разделяемые библиотеки.Я использую формат файла bFLT и не могу контролировать, куда загружается исполняемая и разделяемая библиотека.
Мой загрузчик правильно загружает разделяемую библиотеку и исполняемый файл в память и изменяет GOT исполняемого файла во время выполнения, чтобы связать его с разделяемой библиотекой.
Я могу успешно получить адрес функции, и я знаю, что это правильно, если разобрать код в этом месте.Однако, если я пытаюсь вызвать функцию, все происходит сбой.
Оказывается, GCC добавляет «кодовую оболочку» при вызове функций совместно используемой библиотеки и делает обход, когда функция вызывается и фактически не ветвитсяпо адресу функции.Адрес, на который ветвится кодовый шпон, не перемещен должным образом, потому что он не отображается в списке перемещений в исполняемом двоичном файле.
Разборка шпона выглядит следующим образом:
000008d0 <__library_call_veneer>:
8d0: e51ff004 ldr pc, [pc, #-4] ; 8d4 <__library_call_veneer+0x4>
8d4: 03000320 .word 0x03000320 ; This address isn't correctly relocated!
Если я возьму адрес функции и вставлю его в указатель функции (следовательно, обходя «кодовую оболочку») и вызову его, совместно используемая библиотека будет работать отлично.
Так, например:
#define DIRECT_LIB_CALL(x, args...) do { \
typeof(x) * volatile tmp = x; \
tmp(#args); \
} while (0)
DIRECT_LIB_CALL(library_call); /* works */
library_call(); /* crashes */
Есть ли способ либо сказать GCC, чтобы он не создавал кодовый шпон и разветвлялся непосредственно по адресу, расположенному в GOT, либо каким-либо образом сделать адрес, который ветвями кодового шпона, отображается в списке перемещенийвыполнять?