Freeman пишет:Включение XD Pascal под вопросом. Критерий для добавления в SDK — полезность в разработке и использования в Колибри. Автор DCU32Int — русский, нужно спросить у него разрешение.
Ну про XD Pascal, думаю, тоже не мешает с автором проконсультироваться, так как он свой код знает лучше.
Сейчас там нет поддержки родного формата KolibriOS, желательно ещё добавить хотя бы директиву inline(а лучше asm, конечно), иначе без извращений не получится использовать системные вызовы.
Добавлено 2020-06-30 в 15:29
Если бы поддерживалась директива inline, то можно было бы вставлять уже скомпилированный код, как это сделано в Oberon-07, например, в этом модуле используется SYSTEM.CODE(...), внутри содержится уже готовый код.
Так как это не поддерживается, то я решил сделать по-другому.
Этот пример компилируется Delphi 7
program Test;
const
// Procedure TerminateThread
_TerminateThread: array[0..4] of Byte = (
$83, $C8, $FF, $CD, $40
);
// Function LoadLibrary(Path: PAnsiChar): Pointer; StdCall
_LoadLibrary: array[0..20] of Byte = (
$53, $B8, $44, $00, $00, $00, $BB, $13, $00, $00, $00, $8B, $4C, $24, $08,
$CD, $40, $5B, $C2, $04, $00
);
// Function GetProcAddress(hLib: Pointer; ProcName: PAnsiChar): Pointer; StdCall;
_GetProcAddress: array[0..55] of Byte = (
$56, $57, $53, $8B, $54, $24, $10, $31, $C0, $85, $D2, $74, $25, $8B, $7C,
$24, $14, $B9, $FF, $FF, $FF, $FF, $F2, $AE, $89, $CB, $F7, $D3, $8B, $32,
$85, $F6, $74, $10, $89, $D9, $8B, $7C, $24, $14, $83, $C2, $08, $F3, $A6,
$75, $ED, $8B, $42, $FC, $5B, $5F, $5E, $C2, $08, $00
);
type
TGetProcAddressProc = function(hLib: Pointer; ProcName: PAnsiChar): Pointer; stdcall;
TLoadLibraryProc = function(Path: PAnsiChar): Pointer; stdcall;
TTerminateThreadProc = procedure; stdcall;
var
LoadLibrary: TLoadLibraryProc absolute TLoadLibraryProc(@_LoadLibrary);
GetProcAddress: TGetProcAddressProc absolute TGetProcAddressProc(@_GetProcAddress);
TerminateThread: TTerminateThreadProc absolute TTerminateThreadProc(@_TerminateThread);
hConsole: Pointer;
ConsoleInit: procedure(WndWidth, WndHeight, ScrWidth, ScrHeight: LongWord; Title: PAnsiChar); stdcall;
ConsoleExit: procedure(CloseWindow: Boolean); stdcall;
PrintF: function(Str: PAnsiChar): LongInt; cdecl varargs;
begin
hConsole := LoadLibrary('/sys/lib/console.obj');
ConsoleInit := GetProcAddress(hConsole, 'con_init');
ConsoleExit := GetProcAddress(hConsole, 'con_exit');
PrintF := GetProcAddress(hConsole, 'con_printf');
ConsoleInit($ffffffff, $ffffffff, $ffffffff, $ffffffff, 'Test');
PrintF('%s%s'#10, 'Hello ', 'World!');
ConsoleExit(False);
TerminateThread;
end.
как видно, даже модуль KolibriOS здесь не подключен.
Но к сожалению, судя по грамматике XD Pascal директива absolute тоже не поддерживается.
Тогда вызывать системные функции, объявленные таким образом, можно только вот так
hConsole := TLoadLibraryProc(@_LoadLibrary)('/sys/lib/console.obj');
Я надеюсь, что такой способ работать будет.
Теперь осталось ещё решить вопрос с выходным форматом KolibriOS.
Там в файле Linker.pas вот так:
задаётся базовый адрес
потом вызывается
Relocate(IMGBASE + Headers.CodeSectionHeader.VirtualAddress,
IMGBASE + Headers.DataSectionHeader.VirtualAddress,
IMGBASE + Headers.BSSSectionHeader.VirtualAddress,
IMGBASE + Headers.ImportSectionHeader.VirtualAddress + LookupTableOffset);
сама функция выглядит так
procedure Relocate(CodeDeltaAddr, InitDataDeltaAddr, UninitDataDeltaAddr, ImportDeltaAddr: Integer);
var
i, DeltaAddr: Integer;
begin
DeltaAddr := 0;
for i := 1 to NumRelocs do
begin
case Reloc[i].RelocType of
CODERELOC: DeltaAddr := CodeDeltaAddr;
INITDATARELOC: DeltaAddr := InitDataDeltaAddr;
UNINITDATARELOC: DeltaAddr := UninitDataDeltaAddr;
IMPORTRELOC: DeltaAddr := ImportDeltaAddr
else
Error('Internal fault: Illegal relocation type');
end;
GenDWordAt(Reloc[i].Pos, Reloc[i].Value + DeltaAddr);
end;
end;
она находится в файле CodeGen.pas
Добавлено 2020-06-30 в 18:25
Думаю, что заменить необходимые функции с Windows на аналоги KolibriOS будет не сложно.
С помощью своего проекта PELoad мне удалось запустить приложение xdpw.exe в KolibriOS.
Я лишь закомментировал в System вот это
//function LoadLibraryA(const lpLibFileName: string): LongInt stdcall; external 'KERNEL32.DLL';
//function GetProcAddress(hModule: LongInt;
//const lpProcName: string): Pointer stdcall; external 'KERNEL32.DLL';
эти функции всё равно не используются, ну и аналогов пока для них нет, поэтому они не эмулируются.

Пробовал собрать под Windows с помощью Delphi7 и с помощью XDPascal — оба раза успешно.
Теперь осталось собрать версию под KolibriOS, и мы получим ещё один компилятор, работающий из-под самой KolibriOS.
Кому-то помнится нужен был как раз компилятор Паскаля, так вот, это он 
Ну и, возможно, такой компилятор пригодится тем, кто использует Pascal Pro(хотя asm-вставки здесь не поддерживаются).
Добавлено 2020-07-01 в 12:17
▼вот это компилируется в XDPascal
program Test;
type
PAnsiChar = PChar;
const
// Procedure TerminateThread
_TerminateThread: array[0..4] of Byte = (
$83, $C8, $FF, $CD, $40
);
// Function LoadLibrary(Path: PAnsiChar): Pointer; StdCall
_LoadLibrary: array[0..20] of Byte = (
$53, $B8, $44, $00, $00, $00, $BB, $13, $00, $00, $00, $8B, $4C, $24, $08,
$CD, $40, $5B, $C2, $04, $00
);
// Function GetProcAddress(hLib: Pointer; ProcName: PAnsiChar): Pointer; StdCall;
_GetProcAddress: array[0..55] of Byte = (
$56, $57, $53, $8B, $54, $24, $10, $31, $C0, $85, $D2, $74, $25, $8B, $7C,
$24, $14, $B9, $FF, $FF, $FF, $FF, $F2, $AE, $89, $CB, $F7, $D3, $8B, $32,
$85, $F6, $74, $10, $89, $D9, $8B, $7C, $24, $14, $83, $C2, $08, $F3, $A6,
$75, $ED, $8B, $42, $FC, $5B, $5F, $5E, $C2, $08, $00
);
type
TGetProcAddressProc = function(hLib: Pointer; ProcName: PAnsiChar): Pointer stdcall;
TLoadLibraryProc = function(Path: PAnsiChar): Pointer stdcall;
TTerminateThreadProc = procedure stdcall;
var
LoadLibrary: TLoadLibraryProc;
GetProcAddress: TGetProcAddressProc;
TerminateThread: TTerminateThreadProc;
hConsole: Pointer;
ConsoleInit: procedure(WndWidth, WndHeight, ScrWidth, ScrHeight: Integer; Title: PAnsiChar) stdcall;
ConsoleExit: procedure(CloseWindow: Boolean) stdcall;
WriteASCIIZ: function(Str: PAnsiChar): Integer stdcall;
begin
LoadLibrary := TLoadLibraryProc(@_LoadLibrary);
GetProcAddress := TGetProcAddressProc(@_GetProcAddress);
TerminateThread := TTerminateThreadProc(@_TerminateThread);
hConsole := LoadLibrary('/sys/lib/console.obj');
ConsoleInit := GetProcAddress(hConsole, 'con_init');
ConsoleExit := GetProcAddress(hConsole, 'con_exit');
WriteASCIIZ := GetProcAddress(hConsole, 'con_write_asciiz');
ConsoleInit($ffffffff, $ffffffff, $ffffffff, $ffffffff, 'Test');
WriteASCIIZ('Hello World!');
ConsoleExit(False);
TerminateThread();
end.
и принципиально так работает после конвертации exe2kos
только надо в InitSystem убрать вызов виндовых GetProcessHeap и GetStdHandle
Слэши в путях нужно поменять с "\" на "/".
Тут было бы хорошо иметь возможность использовать оптимизированный ассемблерный код в
стандартной библиотеке, хотя бы через директиву inline.
Для компилятора Context примерно так через директиву inline я и делал
Post's attachments
XDPascal.png 35.59 Кб, 89 скачиваний с 2020-06-30