OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Понедельник, 09 Декабрь, 2019 08:44

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 163 ]  На страницу Пред.  1 ... 4, 5, 6, 7, 8, 9  След.
Автор Сообщение
 Заголовок сообщения: Re: ElfLinker
СообщениеДобавлено: Понедельник, 07 Ноябрь, 2016 19:23 
Аватара пользователя

Зарегистрирован: Среда, 29 Март, 2006 12:09
Сообщения: 495
Я, честно говоря, так и не понял, как переменные отображаются в память из модулей-dll.
Т.е. как заставить загрузчик Linux связать stdin с местом в памяти я понимаю, а вот как привязать Libc.stdin к этому участку - нет.
Похоже, надо читать символьный файл дополнительно.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ElfLinker
СообщениеДобавлено: Понедельник, 07 Ноябрь, 2016 19:35 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 2474
Сама идея динамической библиотеки не должна тебе позволять привязывать переменную к другому месту в памяти, так как другие приложения могут эту переменную использовать ведь...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ElfLinker
СообщениеДобавлено: Понедельник, 07 Ноябрь, 2016 19:55 

Зарегистрирован: Понедельник, 30 Июль, 2007 10:53
Сообщения: 1538
Откуда: Беларусь, Минск
А наоборот сделать можно? Не переменную привязать к другой, внешней библиотеке, а библиотеку ко внешней переменной. То есть, на этапе компоновки указать библиотеке (или модулю), что вот эта переменная находится вот по такому смещению в стеке или по такому адресу в куче.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ElfLinker
СообщениеДобавлено: Понедельник, 07 Ноябрь, 2016 22:35 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1210
Можно не импортировать, а экспортировать. :roll: По идее должно работать.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ElfLinker
СообщениеДобавлено: Вторник, 08 Ноябрь, 2016 09:43 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1210
Действительно, работает.
Добавляем в LnkBase
Код:
PROCEDURE ExportVar*(mod: Module; IN name: STRING; addr: INTEGER);
   VAR sym: Symbol;
BEGIN
   NEW(sym);
   sym.name := name$;
   sym.sect := mod.vars;
   sym.addr := addr;
   sym.next := expList;
   expList := sym;
   INC(expCount);
END ExportVar;

Правим CollectExports
Код:
   
PROCEDURE CollectExports(mod: Module);
VAR p, numobj: INTEGER;
      id, vis, mode, addr: INTEGER;
      name: StrPtr;
BEGIN
   IF ~mod.exported THEN
      GetDir(mod, p, numobj);
      WHILE numobj > 0 DO
         id := DWord(mod,  p + 8);   
         mode := id MOD 16;
         vis := id DIV 16 MOD 16;
         IF (vis # mInternal) THEN
            name := GetPName(mod, id DIV 256);
            addr := DWord(mod,  p + 4);
            IF (mode = mProc) THEN   LB.ExportProc(mod, name$, addr)   
            ELSIF (mode = mVar) THEN   LB.ExportVar(mod, name$, addr)   
            END;
         END;
         DEC(numobj); INC(p, 16)
      END;
      mod.exported := TRUE;
   END;
END CollectExports;      

Теперь объявляем в модуле
Код:
VAR  stdin*, stdout*, stderr* : Libc.PtrFILE;
и экспортируем его. Voila.

Только проблема возникает. Поскольку имена переменных экпортируются без префикса, надо следить, чтобы не смешивались.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ElfLinker
СообщениеДобавлено: Вторник, 08 Ноябрь, 2016 12:12 
Аватара пользователя

Зарегистрирован: Среда, 29 Март, 2006 12:09
Сообщения: 495
Это уже сделано.
Я добавил процедуры LB.ExportVar и Load.ExportVariable, которые делают то, что нужно.
Проблема в том, что переменные, экспортируемые таким способом, должны находиться НЕ в модуле-dll.
И тут есть три варианта:
  • экспортируем переменные вручную, как это сделано для переменных __progname и environ во FreeBSD;
  • экспортируем все переменные во всех модулях подряд, но следим, чтобы не было переменных в dll-модулях;
  • собираем все требуемые переменные в один модуль и потом экспортируем только один модуль.

У меня не получилось экспортировать переменные из Libc. Пробежался по подсистеме Win, там вообще нет переменных в dll-модулях.

Так что, полагаю, можно попробовать остановиться на последнем варианте и сделать процедуру ExportModuleVars(mod) для единовременного вызова при любой компоновке.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ElfLinker
СообщениеДобавлено: Вторник, 08 Ноябрь, 2016 13:02 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1210
Димыч писал(а):
Проблема в том, что переменные, экспортируемые таким способом, должны находиться НЕ в модуле-dll.

Ну конечно. То, что в dll, импортируется, а не экспортируется.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ElfLinker
СообщениеДобавлено: Вторник, 08 Ноябрь, 2016 13:08 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1210
Димыч писал(а):
Пробежался по подсистеме Win, там вообще нет переменных в dll-модулях.

В Windows нельзя импортировать переменную из dll. Точнее, можно, но не с этим компилятором. Там схема напоминает GOT, нужен дополнительный уровень косвенности.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ElfLinker
СообщениеДобавлено: Среда, 09 Ноябрь, 2016 09:51 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 2474
Trurl писал(а):
Только проблема возникает. Поскольку имена переменных экпортируются без префикса, надо следить, чтобы не смешивались.

Проблема не сильно страшная, так как переменных не очень много. Стоит сделать проверку, и если возникают такие коллизии, то в журнал будет выдаваться предупреждение.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ElfLinker
СообщениеДобавлено: Среда, 09 Ноябрь, 2016 13:00 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1133
Откуда: СССР v2.0 rc 1
Хм... Строго говоря в .Net DLL переменную экспортировать вполне себе можно. Как и объекты.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ElfLinker
СообщениеДобавлено: Среда, 09 Ноябрь, 2016 16:14 
Аватара пользователя

Зарегистрирован: Среда, 29 Март, 2006 12:09
Сообщения: 495
Димыч писал(а):
Это уже сделано.
...
...
Так что, полагаю, можно попробовать остановиться на последнем варианте и сделать процедуру ExportModuleVars(mod) для единовременного вызова при любой компоновке.

В общем я так и сделал. ConsHello0 собирается хорошо.
Добавлен модуль LinLibcVars, из Libc переменные убраны, добавлен вызов процедуры ExportModuleVars.


Вложения:
LinuxGUI.tar.gz [3.05 МБ]
Скачиваний: 1090
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ElfLinker
СообщениеДобавлено: Среда, 09 Ноябрь, 2016 16:33 
Аватара пользователя

Зарегистрирован: Среда, 29 Март, 2006 12:09
Сообщения: 495
Возможно надо перекомпилировать все модули в цепочке сборки.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ElfLinker
СообщениеДобавлено: Среда, 09 Ноябрь, 2016 22:05 
Аватара пользователя

Зарегистрирован: Суббота, 26 Ноябрь, 2005 02:12
Сообщения: 458
Откуда: Егорьевск
Trurl писал(а):
Навскидку 3 варианта:
1. Использовать функции, работающие со стандартными потоками (printf, scanf).
2. Роботать с дескрипторами (read, write).
3. Переоткрыть дескрипторы с помощью fdopen.

Убрал stdin из Libc и реализовал 3-й вариант.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ElfLinker
СообщениеДобавлено: Четверг, 10 Ноябрь, 2016 22:08 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 2474
Alexander Shiryaev писал(а):
Trurl писал(а):
Навскидку 3 варианта:
1. Использовать функции, работающие со стандартными потоками (printf, scanf).
2. Роботать с дескрипторами (read, write).
3. Переоткрыть дескрипторы с помощью fdopen.

Убрал stdin из Libc и реализовал 3-й вариант.

Александр, есть еще h_errno в LinNet.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ElfLinker
СообщениеДобавлено: Пятница, 11 Ноябрь, 2016 07:04 
Аватара пользователя

Зарегистрирован: Среда, 29 Март, 2006 12:09
Сообщения: 495
Alexander Shiryaev писал(а):
Убрал stdin из Libc и реализовал 3-й вариант.

Подход имеет право на существование, но потенциально имеет и проблемы.
stdin и stdout инициализирует libc и, строго говоря, мы не знаем, как она это делает.
Приложение по факту получает готовый дескриптор. Который затем использует
в своих целях.

Для этого приложение указывает загрузчику "разъем", куда нужно "воткнуть" значение дескриптора.
Когда мы экспортируем переменные в ELF, мы и помещаем слоты переменных так, чтобы libc могла их использовать.
Поэтому мне подход с экспортом кажется более правильным.

Хотя, еще раз, подход с переоткрытием дескрипторов тоже уместен.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ElfLinker
СообщениеДобавлено: Пятница, 11 Ноябрь, 2016 08:50 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1210
Ну, строго говоря, дескрипторами занимается ядро. Libc создает обертки-потоки для доступа к файлам. То, что мы не знаем как она это делает, неважно. Мы делаем точно так же, вызывая fdopen. А проблемы могут быть. Если включена буферизация, а мы начнем вызывать попеременно printf/fprintf, то вывод может перемешаться.

А трюк с экпортом работает из-за особенностей динамической линковки. В libc есть свои stdin/stdout/stderr, но по умочанию поиск символов начинается с исполнимого файла. Но если кто-от соберет libc с флагом DT_SYMBOLIC, будет облом.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ElfLinker
СообщениеДобавлено: Пятница, 11 Ноябрь, 2016 11:08 
Аватара пользователя

Зарегистрирован: Суббота, 26 Ноябрь, 2005 02:12
Сообщения: 458
Откуда: Егорьевск
Димыч писал(а):
stdin и stdout инициализирует libc и, строго говоря, мы не знаем, как она это делает.
Приложение по факту получает готовый дескриптор. Который затем использует
в своих целях.
...
Для этого приложение указывает загрузчику "разъем", куда нужно "воткнуть" значение дескриптора.

Вот так в OpenBSD, например (а вот fdopen).
B ещё там нет на экспорт переменных stdin, stdout, stderr. Вместо них -- __sF.
Код:
#define stdin   (&__sF[0])
#define stdout  (&__sF[1])
#define stderr  (&__sF[2])

И приходилось к ним получать доступ так:
Код:
MODULE LinLibc;

   ...

   VAR
      (* OpenBSD: stdin, stdout, stderr *)
         __sF*: ARRAY [untagged] 3 OF FILE; (* OpenBSD /usr/include/stdio.h *)
            (*
               stdin = SYSTEM.ADR(__sF[0])
               stdout = SYSTEM.ADR(__sF[1])
               stderr = SYSTEM.ADR(__sF[2])
            *)

   ...

END LinLibc.

В FreeBSD:
Код:
VAR stdin* ["__stdinp"]: PtrFILE;


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ElfLinker
СообщениеДобавлено: Пятница, 11 Ноябрь, 2016 11:29 
Аватара пользователя

Зарегистрирован: Среда, 29 Март, 2006 12:09
Сообщения: 495
Какие же все-таки разные подходы в ОС...
Согласен, тут без fdopen сложно.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ElfLinker
СообщениеДобавлено: Пятница, 11 Ноябрь, 2016 12:22 
Аватара пользователя

Зарегистрирован: Суббота, 26 Ноябрь, 2005 02:12
Сообщения: 458
Откуда: Егорьевск
Иван Денисов писал(а):
Alexander Shiryaev писал(а):
Trurl писал(а):
Навскидку 3 варианта:
1. Использовать функции, работающие со стандартными потоками (printf, scanf).
2. Роботать с дескрипторами (read, write).
3. Переоткрыть дескрипторы с помощью fdopen.

Убрал stdin из Libc и реализовал 3-й вариант.

Александр, есть еще h_errno в LinNet.

Исправил.
В Linux h_errno на самом деле нет, есть __h_errno_location()

А вот в OpenBSD переменная h_errno есть, а функции, аналогичной __h_errno_location(), нет ;(


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ElfLinker
СообщениеДобавлено: Пятница, 11 Ноябрь, 2016 12:50 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1210
h_errno deprecated в posix-2001 и совсем удалена в posix-2008, надо от неё избавляться.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 163 ]  На страницу Пред.  1 ... 4, 5, 6, 7, 8, 9  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


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

Найти:
cron
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2019, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB