Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Управление сборкой таблицы импорта вызовов (раннее связывание)

16K
09 декабря 2010 года
asmforce
186 / / 05.01.2010
Интересует перенаправление вызовов из исполнимого файла в динамическую (в принципе, в статическую аналогично) библиотеку на этапе сборки исполнимого.

Суть задачи сводится к перенаправлению связей между точками вызова функций(*.exe) и точками их реализаций (*.dll), с сохранением совместимости библиотеки на уровне бинарного кода, и исполнимого файла на уровне исходников.

Пробовал механизм сборки архивов (*.а), с использованием *.def файлов, что, вероятно, позволяет управлять соответствием имен функций в *.exe и *.dll, для решения проблемы разности манглинга(mangling) имен, но не вышло.

Скажем, не получилось желанное чудо. Если удается собрать архив с желанным экспортом, и исполнимый скомпоновать, то, как и следовало предположить, при запуске точка входа не находится, т.к. в таблице импорта у исполнимого ничего не изменилось,. Т.е. промежуточное звено (архив - *.a) дает компоновщику основание считать, что необходимая функция есть в библиотеке, а не переадресовывает её, как ожидалось.



Как-то так:
-Библиотека экспортирует функцию "_do_something":

// userlib.cpp:
 
Код:
extern "C" void __declspec(dllexport) do_something()
{
  //...
};


-Исполнимый импортирует функцию "_do_some".
// main.cpp:
 
Код:
extern "C" void __declspec(dllimport) do_some();

//...
  do_some();
//...



//userlib.def:
 
Код:
EXPORTS
  do_something = do_some // _do_something = _do_some



//makefile
Код:
CXX =   g++ -c
LINK    =   g++ -s -static-libgcc
DLLTOOL =   dlltool
REMOVE  =   erase /F
TARGET  =   executive.exe
LIBS    =   -L.\ -luserlib
LIBRARY =   userlib.dll


all: $(LIBRARY) $(TARGET)

$(LIBRARY): userlib.o
    $(LINK) -shared -o $@ $^
    $(DLLTOOL) --input-def userlib.def --dllname $(LIBRARY) --output-lib libuserlib.a

userlib.o: userlib.cpp
    $(CXX) -o $@ $^

$(TARGET): main.o
    $(LINK) $(LIBS) -o $@ $^ libuserlib.a

main.o: main.cpp
    $(CXX) -o $@ $^

clean:
    $(REMOVE) $(TARGET) $(LIBRARY) libuserlib.a userlib.o main.o


Для упрощения опущены некоторые детали, но если хочется/нужно, могу выложить весь "проект" :)
16K
09 декабря 2010 года
asmforce
186 / / 05.01.2010
Публикую тут решение, т.к. прошлый раз долбался несколько часов, потом решил отложить до лучших времен. А сейчас вот, за двадцать-тридцать минут сообразил!

Вообщем тут детально описывать не буду, скажу только вот, что:

// main.def:
 
Код:
IMPORTS
  do_some = lib.dll.do_something


// makefile
 
Код:
...
...
$(TARGET): main.o main.def
    $(LINK) $(INCLUDE) $(LIBS) -o $@ $^


Весь недо-"проект" во вложении.

И вот еще ссылка - binutils. Может кто-то сочтёт полезной.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог