Delphi SDK для Колибри

High-level languages programming questions
  • Не-а, идея в том, чтобы писать в родном для "Колибри" формате и собирать штатным компилятором (FASM), полностью контролируя весь процесс. Это особенно актуально для библиотек, поскольку, как мне кажется, именно разработка библиотек на Delphi будет актуальна для "Колибри".

    Сборка FASM-ом позволит писать на ЯВУ только самое необходимое, что очень сложно реализовать в обозримые сроки на ассемблере. Системные функции и всякие хаки можно написать сразу на FASM, причем только те, что реально нужны, не заморачиваясь полным System. И писать их можно будет по мере надобности, а не все сразу.

    Я уже попробовал собрать FastMM для "Колибри" при помощи "Пифии". Кто тут про прикладной диспетчер кучи заикался? Для больших и сложных программ вроде браузера диспетчер вроде FastMM -- самое то.

    Пока, правда, собрать FastMM не получилось. Оказалось, что FASM чувствителен к порядку аргументов CMPXCHG. К тому же, похоже, у меня поломался разборщик map-файлов. :(
  • Эээ... диспетчер кучи - это чтобы любые блоки памяти выделять, а не по странице? Тогда выкладываю только часть загрузчика PE прог :D Там инклудник и если не вкомпилится, то не пинайте, просто скажите чего не так :roll: Описания все внутри. Ну и ReAllocMem нет. Пока не нужен был просто.
    Attachments
    Downloaded 448 times
    Чем больше сыра, тем больше в нём дыр. Чем больше дыр, тем меньше в нём собственно сыра. Значит, чем больше сыра, тем меньше сыра!
  • GerdtR wrote:Тогда выкладываю только часть загрузчика PE прог :D
    Ты, конечно, извини меня за прямоту, но неужели ты думаешь, что напишешь на коленке лучше FastMM, который работает в тысячах программ?

    А мне как-то внезапно пришло осознание, что формат OMF в Delphi 4 поменялся не просто так, а именно из-за появления перегружаемых функций. Связал оба события...
  • Freeman wrote:Кто тут про прикладной диспетчер кучи заикался?

    Хм, ну Вы сами напросились, вот и скинул)
    Freeman wrote:Ты, конечно, извини меня за прямоту, но неужели ты думаешь, что напишешь на коленке лучше FastMM, который работает в тысячах программ?

    Конечно я так не считаю. Но работает же :mrgreen:
    Чем больше сыра, тем больше в нём дыр. Чем больше дыр, тем меньше в нём собственно сыра. Значит, чем больше сыра, тем меньше сыра!
  • В чем проблема, делфи и так не плохо компилит под Колибри, получаются рабочие исполняемые файлы. При чем не только 3 версия, но запускал и 7ю. Менаджер памяти, тоже есть под него, переписывай не хочу.))) Выкладывал на сайте в темах файлик, который переделывает под исполняемый файл колибри.
    Image
    Исходник:
    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.
    выходной файл: 856 байт, при оптимизации 630 байт, после kpack без оптимизации - 441 байт, с оптимизацией 321 байт.
    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:

    Code: Select all

    // преобразование в MENUETxx
    pet -strip -trunc -menuet -dropsect .idata,.rsrc ww.exe -into ww.kex
    
    // получение списка секций PE-файла
    pet -ls ww.exe
    
    От официально вышедшей PE Tool 0.5 выкладываемая альфа отличается присутствием ключа -menuet. Можете скачать, собрать, поотлаживать...
    Downloaded 391 times
    В теории экспорт не привязан к Delphi, преобразовывать в MENUETxx можно будет PE-файлы других компиляторов. На практике для C/C++ это неактуально, поскольку у них есть свой ld. На Delphi же никто не пишет, поэтому спроса нет, и разработка идет вяло. Ну, и время, уже говорил.
  • Freeman wrote:"Тулчейн" для 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
    
    В теории экспорт не привязан к Delphi, преобразовывать в MENUETxx можно будет PE-файлы других компиляторов. На практике для C/C++ это неактуально, поскольку у них есть свой ld. На Delphi же никто не пишет, поэтому спроса нет, и разработка идет вяло. Ну, и время, уже говорил.
    Этот инструмент вырезает ненужные секции? Про ld - я делал так:

    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
    Оно так же совместит секции. omf2d - преобразует объектные файлы из борландовского в coff формат(а, не, вру: из нового бороандовского в старый, еще есть objconv, который может в COFF преобразовать + PEDUMP, который показывает все, что есть в PE), который понимается MSовским линкером. После этого PEшник чистый, конвертировать его можно легко куда угодно.
  • //DG wrote:Этот инструмент вырезает ненужные секции?
    Модуль ExeImages, вокруг которого строится PE Tool, писался как набор классов (библиотека, движок) для написания патчей. В планах была также работа с ресурсами и вывод содержимого PE-файла по аналогии с утилитами tdump или objdump. Ничего из этого пока не реализовано, работает лишь функциональность в PE Tool, поскольку пока это единственная программа, использующая ExeImages.

    Для MENUETxx возможный алгоритм выглядит так:
    • PE-файл грузится и разбирается обычным порядком.
    • Обрабатываются ключи, не влияющие на перебазирование.
    • Вырезаются секции, задаваемые ключом -dropsect.
    • В зависимости от наличия секции TLS определяется формат -- MENUET01 или MENUET02.
    • Выполняется перебазирование файла на смещение заголовка MENUETxx (MENUET02 на 4 байта длиннее). Во время перебазирования секции укладываются друг за другом с минимальным выравниванием, чтобы получающийся файл был как можно меньше.
    • Обрабатывается ключ -strip, вырезающий секцию перемещаемых символов из образа.
    • Полученный образ сохраняется в файл.
    На практике получается не так однозначно, поскольку секция перемещаемых символов нужна для перебазирования, но при укладывании она уже не должна учитываться, поскольку формат MENUETxx не имеет механизма перемещаемых символов. Для текущей реализации ExeImages.TImage.Rebase это оказалось нетривиально, из-за чего я приостановил разработку.
    //DG wrote:omf2d - преобразует объектные файлы из борландовского в coff формат(а, не, вру: из нового бороандовского в старый, еще есть objconv, который может в COFF преобразовать + PEDUMP, который показывает все, что есть в PE), который понимается MSовским линкером.
    Я не уверен, что сторонние компоновщики смогут правильно связать программы с перегруженными процедурами на Delphi. Borland поменяла формат OMF именно ради перегруженных (overload) процедур Delphi 4. Можно, конечно, писать на Delphi 3 в стиле Turbo Pascal 3.0 -- без модулей, чисто на {$include} но это неполноценная поддержка Delphi, не обеспечивающая ожидаемой гибкости.

    Если писать конвертер не на коленке, а по-честному, PE-файл может быть любым, не обязательно "чистым". Тут, собственно, сталкиваются две культуры: компиляция и компоновка разными утилитами (Microsoft, GNU) или одной утилитой (Delphi, FASM). Мне кажется, что культуре "Колибри" соответствует FASM, а не GNU.
  • omf2d работает отлично с D7.

    "Если писать конвертер не на коленке, а по-честному, PE-файл может быть любым, не обязательно "чистым"."
    А я и не говорю, что нужно расчитывать на чистый. Я просто подумал, что делать ту работу, которую замечательно делает линкер - дублирование.
    Так, на всякий случай, я делал конвертре с релокацией под один свой формат.
  • " и вывод содержимого PE-файла"
    Это есть в утилите PEDUMP от 1995(!) года.
  • //DG wrote:omf2d работает отлично с D7.
    Пока не увижу примера с перегруженными функциями, не поверю.
    //DG wrote:" и вывод содержимого PE-файла"
    Это есть в утилите PEDUMP от 1995(!) года.
    Для уверенности в работоспособности библиотеки по-любому нужен объемлющий тест. PE Tool таковым и является. Писать тест ради теста скучно, оформил в виде утилиты.
  • Freeman wrote:
    //DG wrote:omf2d работает отлично с D7.
    Пока не увижу примера с перегруженными функциями, не поверю.
    //DG wrote:" и вывод содержимого PE-файла"
    Это есть в утилите PEDUMP от 1995(!) года.
    Для уверенности в работоспособности библиотеки по-любому нужен объемлющий тест. PE Tool таковым и является. Писать тест ради теста скучно, оформил в виде утилиты.
    Такое устроит? Или надо через несколько модулей?

    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;
    
    В разных модулях надо mangle дописывать(например, FuncName$qqruc), но преобразование работает. Но не суть - без перегруженных можно обойтись.
  • Who is online

    Users browsing this forum: No registered users and 2 guests