Как включить LD_PRELOAD чтоб он работал?

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

CRobin
постоялец
Сообщения: 145
Зарегистрирован: 26.01.2016 11:15:39

Как включить LD_PRELOAD чтоб он работал?

Сообщение CRobin »

Здравствуйте. Есть библиотека libnet.so, которая заменяет системные функции по части работы с сетью (в частности функции сокетов). Для приложений на С она работает следующим образом:
Из командной строки набираю

Код: Выделить всё

LD_PRELOAD=libnet.so ./project1

В этом случае библиотека подменяет системные функции своими и все работает корректно.

В случае приложения на FPC внешне всы выглядит точно так же, но на практике функции fpSend fpRecv не подменяются и приложение работает в обычном режиме. С чем это может быть связано и какрешить проблему?
fedan
новенький
Сообщения: 70
Зарегистрирован: 15.09.2016 20:18:48

Сообщение fedan »

Попробуй из С апи не кросс платформа конечно: send, recv, socket, open.
Если кроссплатформа, то рекомендую обертки к ним сделать.
CRobin
постоялец
Сообщения: 145
Зарегистрирован: 26.01.2016 11:15:39

Сообщение CRobin »

fedan в каком модуле находятся функции в таком виде? И разве fp аналоги не являются той же самой оберткой для родного сишного апи?
fedan
новенький
Сообщения: 70
Зарегистрирован: 15.09.2016 20:18:48

Сообщение fedan »

CRobin писал(а):fedan в каком модуле находятся функции в таком виде? И разве fp аналоги не являются той же самой оберткой для родного сишного апи?

system

Наверняка чтобы было: сделай обертки к этим функциям: external 'libnet.so'

PS: я сейчас в исходиках fpcsrc запустил find, там под каждую OS своя реализация, но в итоге все они в system.pp прилетают
CRobin
постоялец
Сообщения: 145
Зарегистрирован: 26.01.2016 11:15:39

Сообщение CRobin »

fedan если честно, я вообще не понимаю что не так. Как заставить Lazarus использовать системный АПИ вместо собственной (кроссплатформенной?) реализации?
Аватара пользователя
Лекс Айрин
долгожитель
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград
Контактная информация:

Сообщение Лекс Айрин »

CRobin, посмотрите в определении собственной (кросс) реализации.
CRobin
постоялец
Сообщения: 145
Зарегистрирован: 26.01.2016 11:15:39

Сообщение CRobin »

Лекс Айрин что вы имеете в виду?
Аватара пользователя
Лекс Айрин
долгожитель
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград
Контактная информация:

Сообщение Лекс Айрин »

CRobin, что собственная реализация это прокладка к внешней функции к dll. Иногда, просто импортирующая ее, а иногда адаптирующая к правилам языка.
CRobin
постоялец
Сообщения: 145
Зарегистрирован: 26.01.2016 11:15:39

Сообщение CRobin »

Лекс Айрин не могу найти место где происходит импорт(вызов) системной функции. Все функции типа fp^ не являются обвязкой, иначе бы LD_PRELOAD работал корректно.
Аватара пользователя
Дож
энтузиаст
Сообщения: 900
Зарегистрирован: 12.10.2008 16:14:47

Сообщение Дож »

не могу найти место где происходит импорт(вызов) системной функции. Все функции типа fp^ не являются обвязкой, иначе бы LD_PRELOAD работал корректно.

Нужно смотреть sockets.pp в исходниках rtl, что там реализовано для линуксовой версии функции. Скорее всего, это просто кроссплатформенные обёртки над Send и Recv.

1. Но вот какие Send и Recv -- из so'шки или на основе syscall'ов нужно смотреть.
2. Даже если на основе библиотеки, не исключено, что что-то влинковывается статично, т.е. вшивается в сам бинарь при компиляции.
3. Что такое libnet.so? Вы уверены, что это станадртная линуксовая библиотека, содержащая стандартные линуксовые Send и Recv, а не какая-то сторонняя либа?
fedan
новенький
Сообщения: 70
Зарегистрирован: 15.09.2016 20:18:48

Сообщение fedan »

int send(
_In_ SOCKET s,
_In_ const char *buf,
_In_ int len,
_In_ int flags
);

function send(s:TSocket; buf:PAnsiChar BufLen: Integer; Flags: LongWord): Integer; external 'libnet.so'
CRobin
постоялец
Сообщения: 145
Зарегистрирован: 26.01.2016 11:15:39

Сообщение CRobin »

Дож тут два варианта, либо fp* это хардкод паскаля под конкретную ОС, либо второй вариант как вы сказали. От PRELOAD пришлось отказаться, использую syscall c собственной обвязкой.
Последний раз редактировалось CRobin 21.09.2016 15:18:43, всего редактировалось 1 раз.
Аватара пользователя
Дож
энтузиаст
Сообщения: 900
Зарегистрирован: 12.10.2008 16:14:47

Сообщение Дож »

Я уже сам всё посмотрел в сурсах:

Код: Выделить всё

./packages/rtl-extra/src/linux/unixsock.inc:  fpRecv:=SocketCall(Socket_Sys_Recvfrom,S,tsysparam(buf),len,flags,0,0);

rtl/linux/x86_64/sysnr.inc:  syscall_nr_recvfrom                           = 45;

packages/rtl-extra/src/linux/unixsock.inc:
Function SocketCall(SockCallNr,a1,a2,a3,a4,a5,a6:TSysParam):cint; inline;
var
  Args:array[1..6] of TSysParam;
begin
  args[1]:=a1;
  args[2]:=a2;
  args[3]:=a3;
  args[4]:=a4;
  args[5]:=a5;
  args[6]:=a6;
  SocketCall:=do_Syscall(syscall_nr_socketcall,sockcallnr,TSysParam(@args));
  internal_socketerror:=fpgeterrno;
end;
CRobin
постоялец
Сообщения: 145
Зарегистрирован: 26.01.2016 11:15:39

Сообщение CRobin »

Дожто есть по сути, функции из либы здесь не могут быть вызваны никак? Я не совсем понимаю что делает Linux в случае объявления LD_PRELOAD.
Аватара пользователя
Дож
энтузиаст
Сообщения: 900
Зарегистрирован: 12.10.2008 16:14:47

Сообщение Дож »

syscall'ы -- это способ вызова системных функций в линуксе. Он не требует никаких либ, просто специальный ассемблерный код говорит какой по номеру вызов нужен (у recv и recvfrom, как мы видим, номер 45). Ни от каких so'шек такой код не зависит.
Ответить