Delphi SDK для Колибри
-
У меня есть загрузчик PE программ. Пока с библиотеками PE не очень работает(глюки и с таблицей релокаций вообще не работает, но это будет). Но для проб писал прогу в PE формате использующую функции Колибри и она корректно работала. Ну в общем если кому-то надо поскорей, то приведу в порядок исходники и выложу. Если не срочно, то сначала добью всё-таки эти библиотеки:)Чем больше сыра, тем больше в нём дыр. Чем больше дыр, тем меньше в нём собственно сыра. Значит, чем больше сыра, тем меньше сыра!
Не-а, идея в том, чтобы писать в родном для "Колибри" формате и собирать штатным компилятором (FASM), полностью контролируя весь процесс. Это особенно актуально для библиотек, поскольку, как мне кажется, именно разработка библиотек на Delphi будет актуальна для "Колибри".
Сборка FASM-ом позволит писать на ЯВУ только самое необходимое, что очень сложно реализовать в обозримые сроки на ассемблере. Системные функции и всякие хаки можно написать сразу на FASM, причем только те, что реально нужны, не заморачиваясь полным System. И писать их можно будет по мере надобности, а не все сразу.
Я уже попробовал собрать FastMM для "Колибри" при помощи "Пифии". Кто тут про прикладной диспетчер кучи заикался? Для больших и сложных программ вроде браузера диспетчер вроде FastMM -- самое то.
Пока, правда, собрать FastMM не получилось. Оказалось, что FASM чувствителен к порядку аргументов CMPXCHG. К тому же, похоже, у меня поломался разборщик map-файлов.
Сборка FASM-ом позволит писать на ЯВУ только самое необходимое, что очень сложно реализовать в обозримые сроки на ассемблере. Системные функции и всякие хаки можно написать сразу на FASM, причем только те, что реально нужны, не заморачиваясь полным System. И писать их можно будет по мере надобности, а не все сразу.
Я уже попробовал собрать FastMM для "Колибри" при помощи "Пифии". Кто тут про прикладной диспетчер кучи заикался? Для больших и сложных программ вроде браузера диспетчер вроде FastMM -- самое то.
Пока, правда, собрать FastMM не получилось. Оказалось, что FASM чувствителен к порядку аргументов CMPXCHG. К тому же, похоже, у меня поломался разборщик map-файлов.
Эээ... диспетчер кучи - это чтобы любые блоки памяти выделять, а не по странице? Тогда выкладываю только часть загрузчика PE прог Там инклудник и если не вкомпилится, то не пинайте, просто скажите чего не так Описания все внутри. Ну и ReAllocMem нет. Пока не нужен был просто.
- Attachments
-
-
MemoryManager.inc (5.58 KiB)Downloaded 451 times
-
Чем больше сыра, тем больше в нём дыр. Чем больше дыр, тем меньше в нём собственно сыра. Значит, чем больше сыра, тем меньше сыра!
Ты, конечно, извини меня за прямоту, но неужели ты думаешь, что напишешь на коленке лучше FastMM, который работает в тысячах программ?GerdtR wrote:Тогда выкладываю только часть загрузчика PE прог
А мне как-то внезапно пришло осознание, что формат OMF в Delphi 4 поменялся не просто так, а именно из-за появления перегружаемых функций. Связал оба события...
Freeman wrote:Кто тут про прикладной диспетчер кучи заикался?
Хм, ну Вы сами напросились, вот и скинул)
Freeman wrote:Ты, конечно, извини меня за прямоту, но неужели ты думаешь, что напишешь на коленке лучше FastMM, который работает в тысячах программ?
Конечно я так не считаю. Но работает же
Чем больше сыра, тем больше в нём дыр. Чем больше дыр, тем меньше в нём собственно сыра. Значит, чем больше сыра, тем меньше сыра!
В чем проблема, делфи и так не плохо компилит под Колибри, получаются рабочие исполняемые файлы. При чем не только 3 версия, но запускал и 7ю. Менаджер памяти, тоже есть под него, переписывай не хочу.))) Выкладывал на сайте в темах файлик, который переделывает под исполняемый файл колибри.
Исходник:
выходной файл: 856 байт, при оптимизации 630 байт, после kpack без оптимизации - 441 байт, с оптимизацией 321 байт.
http://akyltist.ucoz.org/asm/ww.kos
PS: Delphi 3. Для 7ки собирал точно такой же, но там геморойней)
Исходник:
Spoiler:
Code: Select all
unit ww;
interface
type system_colors = record
frame: integer;
grab: integer;
grab_button: integer;
grab_button_text: integer;
grab_text: integer;
work: integer;
work_button: integer;
work_button_text: integer;
work_text: integer;
work_graph: integer;
end;
const
wnd_x = 200;
wnd_y = 200;
wnd_w = 317;
wnd_h = 116;
procedure main;
Procedure Wnd_DrawBegin; Assembler;
Procedure Wnd_DrawEnd; Assembler;
Procedure Wnd_SetWindows; Assembler;
var
sc: system_colors;
psc: pointer;
key: cardinal;
wnd_c: pchar;
implementation
procedure main;
label xstart,xdraw,xstill,xkey,xbutton,xexit;
begin
psc := @sc;
wnd_c := 'Hello World!';
asm
xstart:
call xdraw
xstill:
mov eax,10 // функция 10 - ждать события
int $40 // Прерывание
cmp eax,1 // перерисовать окно ?
je xstart // если да - на метку xstart
cmp eax,2 // нажата клавиша ?
je xkey // если да - на key
cmp eax,3 // нажата кнопка ?
je xbutton // если да - на button
jmp xstill // если другое событие - в начало цикла
xkey:
mov eax,10 // функция 2 - считать код символа (в ah) (тут в принципе не нужна)
int $40 // Прерывание
jmp xstill // вернуться к началу цикла
xbutton:
mov eax,17 // функция 17 - получить идентификатор нажатой кнопки
int $40 // Прерывание
cmp ah, 1 // если нажата кнопка с номером 1,
jz xexit // выходим
jmp xstill // вернуться к началу цикла
xexit:
mov eax,-1 // функция -1 - выход
int $40 // Прерывание
xdraw:
call Wnd_DrawBegin
call Wnd_SetWindows
mov eax,48 // Функция 48 - стили отображения окон.
mov ebx,4 // Подфункция 4 - возвращает eax = высота скина.
int $40 // Прерывание
mov ecx,eax // Запоминаем высоту скина
xor eax,eax // Очищаем eax (mov eax,0) (Функция 0)
mov ebx,wnd_x shl 16+wnd_w // [координата по оси x]*65536 + [размер по оси x]
add ecx,wnd_y shl 16+wnd_h // Высота скина + [координата по y]*65536 + [размер по y]
mov edx,[sc.work]
or edx,$34000000 // Или окно со скином фиксированных размеров
mov edi,wnd_c // Заголовок окна
int $40 // Прерывание
call Wnd_DrawEnd
ret
end;
end;
Procedure Wnd_DrawBegin(); Assembler;
Asm
mov eax,12
mov ebx,1
int $40
End;
Procedure Wnd_DrawEnd(); Assembler;
Asm
mov eax,12
mov ebx,2
int $40
End;
Procedure Wnd_SetWindows; Assembler;
Asm
mov eax,48 // Функция 48 - стили отображения окон
mov ebx,3 // Подфункция 3 - получить стандартные цвета окон.
mov ecx,psc // Указатель на буфер размером edx байт, под структуру
mov edx,40 // Размер таблицы цветов (должен быть 40 байт)
int $40 // Прерывание
end;
begin
main();
end.
http://akyltist.ucoz.org/asm/ww.kos
PS: Delphi 3. Для 7ки собирал точно такой же, но там геморойней)
А библиотеку?Akyltist wrote:Выкладывал на сайте в темах файлик, который переделывает под исполняемый файл колибри.
Доказал что может, зачем библиотека?).Freeman wrote:Поскольку Дельфи не может компилировать в формат Колибри, придётся сделать поддержку PE.
PS: работаю над своим компилятором паскаля)
В этот раз не 5 лет прошло, а всего 2...
Глядя на товарища ALEXS1983, решил выложить свою альфу. В части поддержки KolibriOS это даже не альфа, а скорее концепт, поскольку генерируемые файлы неработоспособны в KolibriOS. Нужно дорабатывать и отлаживать, но времени нет. Пример ww.pas я взял из сообщения выше, только переделал в программу, поскольку для PE Tool нужен exe- или dll-файл, а не .dcu.
PE Tool — это единая утилита для пересборки PE-файлов, основанная на самописном модуле ExeImages, выполняющем все манипуляции. От других утилит (pe2kos, exe2kos, pe2kex) PE Tool отличается полноценным разбором PE-файла и богатым набором ключей, где планируемый экспорт в MENUETxx — только один из режимов. Остальные функции уже работают, программа давно лежит на SourceForge, иногда ее скачивают. Если поддержку KolibriOS удастся довести до ума, получится по-настоящему гибкая технологическая утилита, не зависящая от имен секций, предопределенных адресов, версий компиляторов и пр. Скажем, выбор между MENUET01 и MENUET02 в ней делается автоматически, на основе присутствия сегмента TLS в PE-файле, а присутствие TLS определяется не по имени .tls, а из соответствующего поля в каталоге данных PE.
С момента выкладывания 3 года назад формат KOLIBRI был выпилен, зато реализовано перебазирование (метод ExeImages.TImage.Rebase), которое и нужно доработать. Об особенностях форматов MENUETxx я объяснял на видео. Поскольку MENUETxx -- плоский бинарник с заголовком, без заголовка это будет плоский бинарник (да, кэп!), то есть на Delphi формально можно будет написать ядро ОС. "Тулчейн" для Delphi будет включать в себя dcc32 и pet.
Примеры вызова PE Tool:
От официально вышедшей PE Tool 0.5 выкладываемая альфа отличается присутствием ключа -menuet. Можете скачать, собрать, поотлаживать...
В теории экспорт не привязан к Delphi, преобразовывать в MENUETxx можно будет PE-файлы других компиляторов. На практике для C/C++ это неактуально, поскольку у них есть свой ld. На Delphi же никто не пишет, поэтому спроса нет, и разработка идет вяло. Ну, и время, уже говорил.
Глядя на товарища ALEXS1983, решил выложить свою альфу. В части поддержки KolibriOS это даже не альфа, а скорее концепт, поскольку генерируемые файлы неработоспособны в KolibriOS. Нужно дорабатывать и отлаживать, но времени нет. Пример ww.pas я взял из сообщения выше, только переделал в программу, поскольку для PE Tool нужен exe- или dll-файл, а не .dcu.
PE Tool — это единая утилита для пересборки PE-файлов, основанная на самописном модуле ExeImages, выполняющем все манипуляции. От других утилит (pe2kos, exe2kos, pe2kex) PE Tool отличается полноценным разбором PE-файла и богатым набором ключей, где планируемый экспорт в MENUETxx — только один из режимов. Остальные функции уже работают, программа давно лежит на SourceForge, иногда ее скачивают. Если поддержку KolibriOS удастся довести до ума, получится по-настоящему гибкая технологическая утилита, не зависящая от имен секций, предопределенных адресов, версий компиляторов и пр. Скажем, выбор между MENUET01 и MENUET02 в ней делается автоматически, на основе присутствия сегмента TLS в PE-файле, а присутствие TLS определяется не по имени .tls, а из соответствующего поля в каталоге данных PE.
С момента выкладывания 3 года назад формат KOLIBRI был выпилен, зато реализовано перебазирование (метод ExeImages.TImage.Rebase), которое и нужно доработать. Об особенностях форматов MENUETxx я объяснял на видео. Поскольку MENUETxx -- плоский бинарник с заголовком, без заголовка это будет плоский бинарник (да, кэп!), то есть на Delphi формально можно будет написать ядро ОС. "Тулчейн" для Delphi будет включать в себя dcc32 и pet.
Примеры вызова PE Tool:
Code: Select all
// преобразование в MENUETxx
pet -strip -trunc -menuet -dropsect .idata,.rsrc ww.exe -into ww.kex
// получение списка секций PE-файла
pet -ls ww.exe
Этот инструмент вырезает ненужные секции? Про ld - я делал так:Freeman wrote:"Тулчейн" для Delphi будет включать в себя dcc32 и pet.
Примеры вызова PE Tool:В теории экспорт не привязан к Delphi, преобразовывать в MENUETxx можно будет PE-файлы других компиляторов. На практике для C/C++ это неактуально, поскольку у них есть свой ld. На Delphi же никто не пишет, поэтому спроса нет, и разработка идет вяло. Ну, и время, уже говорил.Code: Select all
// преобразование в MENUETxx pet -strip -trunc -menuet -dropsect .idata,.rsrc ww.exe -into ww.kex // получение списка секций PE-файла pet -ls ww.exe
Code: Select all
dcc32.exe system.pas sysinit.pas strings.pas -JP -M -Y -Z -$D- -0 > sysbuild.log
omf2d system.obj system2.obj /U- /U_* /CP@initialization$qqrv=@system_initialization /CP@Finalization$qqrv=@system_finalization
omf2d sysinit.obj sysinit2.obj /U- /U_* /CP@initialization$qqrv=@sysinit_initialization /CP@Finalization$qqrv=@sysinit_finalization
omf2d strings.obj strings2.obj /U- /U_* /CP@initialization$qqrv=@strings_initialization /CP@Finalization$qqrv=@strings_finalization
del system.obj
del sysinit.obj
del strings.obj
ren system2.obj system.obj
ren sysinit2.obj sysinit.obj
ren strings2.obj strings.obj
Code: Select all
link.exe /ALIGN:16 /FILEALIGN:16 /FORCE:UNRESOLVED /SUBSYSTEM:WINDOWS /SECTION:.text,ERW /MERGE:.rdata=.text /MERGE:_INIT_=.text /MERGE:_EXIT_=.text /ENTRY:Start$qqsuiuiui Hello.obj system.obj kernel32.lib user32.lib /out:Hello.exe
Модуль ExeImages, вокруг которого строится PE Tool, писался как набор классов (библиотека, движок) для написания патчей. В планах была также работа с ресурсами и вывод содержимого PE-файла по аналогии с утилитами tdump или objdump. Ничего из этого пока не реализовано, работает лишь функциональность в PE Tool, поскольку пока это единственная программа, использующая ExeImages.//DG wrote:Этот инструмент вырезает ненужные секции?
Для MENUETxx возможный алгоритм выглядит так:
- PE-файл грузится и разбирается обычным порядком.
- Обрабатываются ключи, не влияющие на перебазирование.
- Вырезаются секции, задаваемые ключом -dropsect.
- В зависимости от наличия секции TLS определяется формат -- MENUET01 или MENUET02.
- Выполняется перебазирование файла на смещение заголовка MENUETxx (MENUET02 на 4 байта длиннее). Во время перебазирования секции укладываются друг за другом с минимальным выравниванием, чтобы получающийся файл был как можно меньше.
- Обрабатывается ключ -strip, вырезающий секцию перемещаемых символов из образа.
- Полученный образ сохраняется в файл.
Я не уверен, что сторонние компоновщики смогут правильно связать программы с перегруженными процедурами на Delphi. Borland поменяла формат OMF именно ради перегруженных (overload) процедур Delphi 4. Можно, конечно, писать на Delphi 3 в стиле Turbo Pascal 3.0 -- без модулей, чисто на {$include} но это неполноценная поддержка Delphi, не обеспечивающая ожидаемой гибкости.//DG wrote:omf2d - преобразует объектные файлы из борландовского в coff формат(а, не, вру: из нового бороандовского в старый, еще есть objconv, который может в COFF преобразовать + PEDUMP, который показывает все, что есть в PE), который понимается MSовским линкером.
Если писать конвертер не на коленке, а по-честному, PE-файл может быть любым, не обязательно "чистым". Тут, собственно, сталкиваются две культуры: компиляция и компоновка разными утилитами (Microsoft, GNU) или одной утилитой (Delphi, FASM). Мне кажется, что культуре "Колибри" соответствует FASM, а не GNU.
omf2d работает отлично с D7.
"Если писать конвертер не на коленке, а по-честному, PE-файл может быть любым, не обязательно "чистым"."
А я и не говорю, что нужно расчитывать на чистый. Я просто подумал, что делать ту работу, которую замечательно делает линкер - дублирование.
Так, на всякий случай, я делал конвертре с релокацией под один свой формат.
"Если писать конвертер не на коленке, а по-честному, PE-файл может быть любым, не обязательно "чистым"."
А я и не говорю, что нужно расчитывать на чистый. Я просто подумал, что делать ту работу, которую замечательно делает линкер - дублирование.
Так, на всякий случай, я делал конвертре с релокацией под один свой формат.
" и вывод содержимого PE-файла"
Это есть в утилите PEDUMP от 1995(!) года.
Это есть в утилите PEDUMP от 1995(!) года.
Пока не увижу примера с перегруженными функциями, не поверю.//DG wrote:omf2d работает отлично с D7.
Для уверенности в работоспособности библиотеки по-любому нужен объемлющий тест. PE Tool таковым и является. Писать тест ради теста скучно, оформил в виде утилиты.//DG wrote:" и вывод содержимого PE-файла"
Это есть в утилите PEDUMP от 1995(!) года.
Такое устроит? Или надо через несколько модулей?Freeman wrote:Пока не увижу примера с перегруженными функциями, не поверю.//DG wrote:omf2d работает отлично с D7.Для уверенности в работоспособности библиотеки по-любому нужен объемлющий тест. PE Tool таковым и является. Писать тест ради теста скучно, оформил в виде утилиты.//DG wrote:" и вывод содержимого PE-файла"
Это есть в утилите PEDUMP от 1995(!) года.
Code: Select all
function Func1(AParam: integer): boolean; overload;
begin
MessageBox(0,'Header','TinyPE in Delphi',0);
end;
function Func1(AParam: boolean): boolean; overload;
begin
MessageBox(0,'Header','TinyPE in Delphi',0);
end;
function Start(hModule, hReason, hReserved: DWORD): LongBool;
begin
Func1(3);
Func1(True);
Result:= TRUE;
end;
Who is online
Users browsing this forum: No registered users and 3 guests