git-svn-id: https://svn.code.sf.net/p/kolmck/code@38 91bb2d04-0c0c-4d2d-88a5-bbb6f4c1fa07
This commit is contained in:
18
System/D2006betaECM/SYSWSTR.PAS
Normal file
18
System/D2006betaECM/SYSWSTR.PAS
Normal file
@ -0,0 +1,18 @@
|
||||
unit syswstr;
|
||||
{X: this unit contains some definitions and initializations, needed to
|
||||
support wide string variables. To use it, just place reference to syswstr
|
||||
unit in your dpr/units uses clause *as first as possible* }
|
||||
|
||||
interface
|
||||
|
||||
implementation
|
||||
|
||||
initialization
|
||||
|
||||
WStrAddRefProc := WStrAddRef;
|
||||
WStrClrProc := WStrClr;
|
||||
WStrArrayClrProc := WStrArrayClr;
|
||||
|
||||
finalization
|
||||
|
||||
end.
|
148
System/D2006betaECM/ShareMem.pas
Normal file
148
System/D2006betaECM/ShareMem.pas
Normal file
@ -0,0 +1,148 @@
|
||||
{ *********************************************************************** }
|
||||
{ }
|
||||
{ Delphi / Kylix Cross-Platform Runtime Library }
|
||||
{ }
|
||||
{ Copyright (c) 1995-2001 Borland Software Corporation }
|
||||
{ }
|
||||
{ *********************************************************************** }
|
||||
|
||||
unit ShareMem;
|
||||
|
||||
interface
|
||||
|
||||
{$IFDEF MEMORY_DIAG}
|
||||
type
|
||||
TBlockEnumProc = function (Block: Pointer): Boolean;
|
||||
{$ENDIF}
|
||||
|
||||
function SysGetMem(Size: Integer): Pointer;
|
||||
function SysFreeMem(P: Pointer): Integer;
|
||||
function SysReallocMem(P: Pointer; Size: Integer): Pointer;
|
||||
function GetHeapStatus: THeapStatus;
|
||||
function GetAllocMemCount: Integer;
|
||||
function GetAllocMemSize: Integer;
|
||||
procedure DumpBlocks;
|
||||
|
||||
{$IFDEF MEMORY_DIAG}
|
||||
function InitBlockMarking: Boolean;
|
||||
function MarkBlocks: Integer;
|
||||
function GetMarkedBlocks(MarkID: Integer; Proc: TBlockEnumProc): Boolean;
|
||||
{$ENDIF}
|
||||
|
||||
implementation
|
||||
|
||||
{$IFDEF GLOBALALLOC}
|
||||
uses Windows;
|
||||
{$ENDIF}
|
||||
|
||||
{$IFDEF MEMORY_DIAG}
|
||||
type
|
||||
TInitBlockMarking = function: Boolean;
|
||||
TMarkBlocks = function: Integer;
|
||||
TGetMarkedBlocks = function (MarkID: Integer; Proc: TBlockEnumProc): Boolean;
|
||||
|
||||
var
|
||||
MMHandle: Integer = 0;
|
||||
SysInitBlockMarking: TInitBlockMarking = nil;
|
||||
SysMarkBlocks: TMarkBlocks = nil;
|
||||
SysGetMarkedBlocks: TGetMarkedBlocks = nil;
|
||||
{$ENDIF}
|
||||
|
||||
const
|
||||
DelphiMM = 'borlndmm.dll';
|
||||
|
||||
function SysGetMem(Size: Integer): Pointer; external DelphiMM name '@Borlndmm@SysGetMem$qqri';
|
||||
function SysFreeMem(P: Pointer): Integer; external DelphiMM name '@Borlndmm@SysFreeMem$qqrpv';
|
||||
function SysReallocMem(P: Pointer; Size: Integer): Pointer; external DelphiMM name '@Borlndmm@SysReallocMem$qqrpvi';
|
||||
function GetHeapStatus: THeapStatus; external DelphiMM;
|
||||
function GetAllocMemCount: Integer; external DelphiMM;
|
||||
function GetAllocMemSize: Integer; external DelphiMM;
|
||||
procedure DumpBlocks; external DelphiMM;
|
||||
|
||||
function GetModuleHandle(lpModuleName: PChar): Integer; stdcall;
|
||||
external 'kernel32.dll' name 'GetModuleHandleA';
|
||||
function GetProcAddress(hModule: Integer; lpProcName: PChar): Pointer; stdcall;
|
||||
external 'kernel32.dll' name 'GetProcAddress';
|
||||
|
||||
{$IFDEF MEMORY_DIAG}
|
||||
|
||||
procedure InitMMHandle;
|
||||
begin
|
||||
if MMHandle = 0 then MMHandle := GetModuleHandle(DelphiMM);
|
||||
end;
|
||||
|
||||
function InitBlockMarking: Boolean;
|
||||
begin
|
||||
InitMMHandle;
|
||||
if @SysInitBlockMarking = nil then
|
||||
@SysInitBlockMarking := GetProcAddress(MMHandle, 'InitBlockMarking');
|
||||
if @SysInitBlockMarking <> nil then
|
||||
Result := SysInitBlockMarking
|
||||
else Result := False;
|
||||
end;
|
||||
|
||||
function MarkBlocks: Integer;
|
||||
begin
|
||||
InitMMHandle;
|
||||
if @SysMarkBlocks = nil then
|
||||
@SysMarkBlocks := GetProcAddress(MMHandle, 'MarkBlocks');
|
||||
if @SysMarkBlocks <> nil then
|
||||
Result := SysMarkBlocks
|
||||
else Result := -1;
|
||||
end;
|
||||
|
||||
function GetMarkedBlocks(MarkID: Integer; Proc: TBlockEnumProc): Boolean;
|
||||
begin
|
||||
InitMMHandle;
|
||||
if @SysGetMarkedBlocks = nil then
|
||||
@SysGetMarkedBlocks := GetProcAddress(MMHandle, 'GetMarkedBlocks');
|
||||
if @SysGetMarkedBlocks <> nil then
|
||||
Result := SysGetMarkedBlocks(MarkID, Proc)
|
||||
else Result := False;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
{$IFDEF GLOBALALLOC}
|
||||
function xSysGetMem(Size: Integer): Pointer;
|
||||
begin
|
||||
Result := GlobalAllocPtr(HeapAllocFlags, Size);
|
||||
end;
|
||||
|
||||
function xSysFreeMem(P: Pointer): Integer;
|
||||
begin
|
||||
Result := GlobalFreePtr(P);
|
||||
end;
|
||||
|
||||
function xSysReallocMem(P: Pointer; Size: Integer): Pointer;
|
||||
begin
|
||||
Result := GlobalReallocPtr(P, Size, 0);
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
|
||||
procedure InitMemoryManager;
|
||||
var
|
||||
SharedMemoryManager: TMemoryManager;
|
||||
MM: Integer;
|
||||
begin
|
||||
// force a static reference to borlndmm.dll, so we don't have to LoadLibrary
|
||||
SharedMemoryManager.GetMem := SysGetMem;
|
||||
|
||||
MM := GetModuleHandle(DelphiMM);
|
||||
{$IFDEF GLOBALALLOC}
|
||||
SharedMemoryManager.GetMem := xSysGetMem;
|
||||
SharedMemoryManager.FreeMem := xSysFreeMem;
|
||||
SharedMemoryManager.ReallocMem := xSysReallocMem;
|
||||
{$ELSE}
|
||||
SharedMemoryManager.GetMem := GetProcAddress(MM,'@Borlndmm@SysGetMem$qqri');
|
||||
SharedMemoryManager.FreeMem := GetProcAddress(MM,'@Borlndmm@SysFreeMem$qqrpv');
|
||||
SharedMemoryManager.ReallocMem := GetProcAddress(MM, '@Borlndmm@SysReallocMem$qqrpvi');
|
||||
{$ENDIF}
|
||||
SetMemoryManager(SharedMemoryManager);
|
||||
end;
|
||||
|
||||
initialization
|
||||
if not IsMemoryManagerSet then
|
||||
InitMemoryManager;
|
||||
end.
|
||||
|
184
System/D2006betaECM/SysConst.pas
Normal file
184
System/D2006betaECM/SysConst.pas
Normal file
@ -0,0 +1,184 @@
|
||||
{ *********************************************************************** }
|
||||
{ }
|
||||
{ Delphi / Kylix Cross-Platform Runtime Library }
|
||||
{ }
|
||||
{ Copyright (c) 1995, 2001 Borland Software Corporation }
|
||||
{ }
|
||||
{ *********************************************************************** }
|
||||
|
||||
unit SysConst;
|
||||
|
||||
interface
|
||||
|
||||
resourcestring
|
||||
SUnknown = '<unknown>';
|
||||
SInvalidInteger = '''%s'' is not a valid integer value';
|
||||
SInvalidFloat = '''%s'' is not a valid floating point value';
|
||||
SInvalidCurrency = '''%s'' is not a valid currency value';
|
||||
SInvalidDate = '''%s'' is not a valid date';
|
||||
SInvalidTime = '''%s'' is not a valid time';
|
||||
SInvalidDateTime = '''%s'' is not a valid date and time';
|
||||
SInvalidDateTimeFloat = '''%g'' is not a valid date and time';
|
||||
SInvalidTimeStamp = '''%d.%d'' is not a valid timestamp';
|
||||
SInvalidGUID = '''%s'' is not a valid GUID value';
|
||||
SInvalidBoolean = '''%s'' is not a valid boolean value';
|
||||
STimeEncodeError = 'Invalid argument to time encode';
|
||||
SDateEncodeError = 'Invalid argument to date encode';
|
||||
SOutOfMemory = 'Out of memory';
|
||||
SInOutError = 'I/O error %d';
|
||||
SFileNotFound = 'File not found';
|
||||
SInvalidFilename = 'Invalid filename';
|
||||
STooManyOpenFiles = 'Too many open files';
|
||||
SAccessDenied = 'File access denied';
|
||||
SEndOfFile = 'Read beyond end of file';
|
||||
SDiskFull = 'Disk full';
|
||||
SInvalidInput = 'Invalid numeric input';
|
||||
SDivByZero = 'Division by zero';
|
||||
SRangeError = 'Range check error';
|
||||
SIntOverflow = 'Integer overflow';
|
||||
SInvalidOp = 'Invalid floating point operation';
|
||||
SZeroDivide = 'Floating point division by zero';
|
||||
SOverflow = 'Floating point overflow';
|
||||
SUnderflow = 'Floating point underflow';
|
||||
SInvalidPointer = 'Invalid pointer operation';
|
||||
SInvalidCast = 'Invalid class typecast';
|
||||
{$IFDEF MSWINDOWS}
|
||||
SAccessViolationArg3 = 'Access violation at address %p. %s of address %p';
|
||||
{$ENDIF}
|
||||
{$IFDEF LINUX}
|
||||
SAccessViolationArg2 = 'Access violation at address %p, accessing address %p';
|
||||
{$ENDIF}
|
||||
SAccessViolationNoArg = 'Access violation';
|
||||
SStackOverflow = 'Stack overflow';
|
||||
SControlC = 'Control-C hit';
|
||||
SQuit = 'Quit key hit';
|
||||
SPrivilege = 'Privileged instruction';
|
||||
SOperationAborted = 'Operation aborted';
|
||||
SException = 'Exception %s in module %s at %p.' + sLineBreak + '%s%s' + sLineBreak;
|
||||
SExceptTitle = 'Application Error';
|
||||
{$IFDEF LINUX}
|
||||
SSigactionFailed = 'sigaction call failed';
|
||||
{$ENDIF}
|
||||
SInvalidFormat = 'Format ''%s'' invalid or incompatible with argument';
|
||||
SArgumentMissing = 'No argument for format ''%s''';
|
||||
SDispatchError = 'Variant method calls not supported';
|
||||
SReadAccess = 'Read';
|
||||
SWriteAccess = 'Write';
|
||||
SResultTooLong = 'Format result longer than 4096 characters';
|
||||
SFormatTooLong = 'Format string too long';
|
||||
|
||||
SVarArrayCreate = 'Error creating variant or safe array';
|
||||
SVarArrayBounds = 'Variant or safe array index out of bounds';
|
||||
SVarArrayLocked = 'Variant or safe array is locked';
|
||||
SVarArrayWithHResult = 'Unexpected variant or safe array error: %s%.8x';
|
||||
|
||||
SInvalidVarCast = 'Invalid variant type conversion';
|
||||
SInvalidVarOp = 'Invalid variant operation';
|
||||
SInvalidVarNullOp = 'Invalid NULL variant operation';
|
||||
SInvalidVarOpWithHResultWithPrefix = 'Invalid variant operation (%s%.8x)'#10'%s';
|
||||
SVarTypeRangeCheck1 = 'Range check error for variant of type (%s)';
|
||||
SVarTypeRangeCheck2 = 'Range check error while converting variant of type (%s) into type (%s)';
|
||||
SVarTypeOutOfRangeWithPrefix = 'Custom variant type (%s%.4x) is out of range';
|
||||
SVarTypeAlreadyUsedWithPrefix = 'Custom variant type (%s%.4x) already used by %s';
|
||||
SVarTypeNotUsableWithPrefix = 'Custom variant type (%s%.4x) is not usable';
|
||||
SVarTypeTooManyCustom = 'Too many custom variant types have been registered';
|
||||
|
||||
// the following are not used anymore
|
||||
SVarNotArray = 'Variant is not an array' deprecated; // not used, use SVarInvalid instead
|
||||
SVarTypeUnknown = 'Unknown custom variant type ($%.4x)' deprecated; // not used anymore
|
||||
SVarTypeOutOfRange = 'Custom variant type ($%.4x) is out of range' deprecated;
|
||||
SVarTypeAlreadyUsed = 'Custom variant type ($%.4x) already used by %s' deprecated;
|
||||
SVarTypeNotUsable = 'Custom variant type ($%.4x) is not usable' deprecated;
|
||||
SInvalidVarOpWithHResult = 'Invalid variant operation ($%.8x)' deprecated;
|
||||
|
||||
SVarTypeCouldNotConvert = 'Could not convert variant of type (%s) into type (%s)';
|
||||
SVarTypeConvertOverflow = 'Overflow while converting variant of type (%s) into type (%s)';
|
||||
SVarOverflow = 'Variant overflow';
|
||||
SVarInvalid = 'Invalid argument';
|
||||
SVarBadType = 'Invalid variant type';
|
||||
SVarNotImplemented = 'Operation not supported';
|
||||
SVarOutOfMemory = 'Variant operation ran out memory';
|
||||
SVarUnexpected = 'Unexpected variant error';
|
||||
|
||||
SVarDataClearRecursing = 'Recursion while doing a VarDataClear';
|
||||
SVarDataCopyRecursing = 'Recursion while doing a VarDataCopy';
|
||||
SVarDataCopyNoIndRecursing = 'Recursion while doing a VarDataCopyNoInd';
|
||||
SVarDataInitRecursing = 'Recursion while doing a VarDataInit';
|
||||
SVarDataCastToRecursing = 'Recursion while doing a VarDataCastTo';
|
||||
SVarIsEmpty = 'Variant is empty';
|
||||
sUnknownFromType = 'Cannot convert from the specified type';
|
||||
sUnknownToType = 'Cannot convert to the specified type';
|
||||
SExternalException = 'External exception %x';
|
||||
SAssertionFailed = 'Assertion failed';
|
||||
SIntfCastError = 'Interface not supported';
|
||||
SSafecallException = 'Exception in safecall method';
|
||||
SAssertError = '%s (%s, line %d)';
|
||||
SAbstractError = 'Abstract Error';
|
||||
SModuleAccessViolation = 'Access violation at address %p in module ''%s''. %s of address %p';
|
||||
SCannotReadPackageInfo = 'Cannot access package information for package ''%s''';
|
||||
sErrorLoadingPackage = 'Can''t load package %s.'+sLineBreak+'%s';
|
||||
SInvalidPackageFile = 'Invalid package file ''%s''';
|
||||
SInvalidPackageHandle = 'Invalid package handle';
|
||||
SDuplicatePackageUnit = 'Cannot load package ''%s.'' It contains unit ''%s,''' +
|
||||
'which is also contained in package ''%s''';
|
||||
SOSError = 'System Error. Code: %d.'+sLineBreak+'%s';
|
||||
SUnkOSError = 'A call to an OS function failed';
|
||||
{$IFDEF MSWINDOWS}
|
||||
SWin32Error = 'Win32 Error. Code: %d.'#10'%s' deprecated; // use SOSError
|
||||
SUnkWin32Error = 'A Win32 API function failed' deprecated; // use SUnkOSError
|
||||
{$ENDIF}
|
||||
SNL = 'Application is not licensed to use this feature';
|
||||
|
||||
SShortMonthNameJan = 'Jan';
|
||||
SShortMonthNameFeb = 'Feb';
|
||||
SShortMonthNameMar = 'Mar';
|
||||
SShortMonthNameApr = 'Apr';
|
||||
SShortMonthNameMay = 'May';
|
||||
SShortMonthNameJun = 'Jun';
|
||||
SShortMonthNameJul = 'Jul';
|
||||
SShortMonthNameAug = 'Aug';
|
||||
SShortMonthNameSep = 'Sep';
|
||||
SShortMonthNameOct = 'Oct';
|
||||
SShortMonthNameNov = 'Nov';
|
||||
SShortMonthNameDec = 'Dec';
|
||||
|
||||
SLongMonthNameJan = 'January';
|
||||
SLongMonthNameFeb = 'February';
|
||||
SLongMonthNameMar = 'March';
|
||||
SLongMonthNameApr = 'April';
|
||||
SLongMonthNameMay = 'May';
|
||||
SLongMonthNameJun = 'June';
|
||||
SLongMonthNameJul = 'July';
|
||||
SLongMonthNameAug = 'August';
|
||||
SLongMonthNameSep = 'September';
|
||||
SLongMonthNameOct = 'October';
|
||||
SLongMonthNameNov = 'November';
|
||||
SLongMonthNameDec = 'December';
|
||||
|
||||
SShortDayNameSun = 'Sun';
|
||||
SShortDayNameMon = 'Mon';
|
||||
SShortDayNameTue = 'Tue';
|
||||
SShortDayNameWed = 'Wed';
|
||||
SShortDayNameThu = 'Thu';
|
||||
SShortDayNameFri = 'Fri';
|
||||
SShortDayNameSat = 'Sat';
|
||||
|
||||
SLongDayNameSun = 'Sunday';
|
||||
SLongDayNameMon = 'Monday';
|
||||
SLongDayNameTue = 'Tuesday';
|
||||
SLongDayNameWed = 'Wednesday';
|
||||
SLongDayNameThu = 'Thursday';
|
||||
SLongDayNameFri = 'Friday';
|
||||
SLongDayNameSat = 'Saturday';
|
||||
|
||||
{$IFDEF LINUX}
|
||||
SEraEntries = '';
|
||||
{$ENDIF}
|
||||
|
||||
SCannotCreateDir = 'Unable to create directory';
|
||||
SCodesetConversionError = 'Codeset conversion failure';
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
|
858
System/D2006betaECM/SysInit.pas
Normal file
858
System/D2006betaECM/SysInit.pas
Normal file
@ -0,0 +1,858 @@
|
||||
{ *********************************************************************** }
|
||||
{ }
|
||||
{ Delphi / Kylix Cross-Platform Runtime Library }
|
||||
{ System Initialization Unit }
|
||||
{ }
|
||||
{ Copyright (c) 1997-2002 Borland Software Corporation }
|
||||
{ }
|
||||
{ This file may be distributed and/or modified under the terms of the }
|
||||
{ GNU General Public License version 2 as published by the Free Software }
|
||||
{ Foundation and appearing at http://www.borland.com/kylix/gpl.html. }
|
||||
{ }
|
||||
{ Licensees holding a valid Borland No-Nonsense License for this }
|
||||
{ Software may use this file in accordance with such license, which }
|
||||
{ appears in the file license.txt that came with this software. }
|
||||
{ }
|
||||
{ *********************************************************************** }
|
||||
|
||||
unit SysInit;
|
||||
|
||||
interface
|
||||
|
||||
{$H+,I-,R-,S-,O+,W-}
|
||||
{$WARN SYMBOL_PLATFORM OFF}
|
||||
|
||||
{X+} // if your app really need to localize resource, call:
|
||||
{X+} procedure UseLocalizeResources;
|
||||
|
||||
{$IFDEF LINUX}
|
||||
const
|
||||
ExeBaseAddress = Pointer($8048000) platform;
|
||||
{$ENDIF}
|
||||
|
||||
var
|
||||
ModuleIsLib: Boolean; { True if this module is a dll (a library or a package) }
|
||||
ModuleIsPackage: Boolean; { True if this module is a package }
|
||||
ModuleIsCpp: Boolean; { True if this module is compiled using C++ Builder }
|
||||
TlsIndex: Integer = -1; { Thread local storage index }
|
||||
TlsLast: Byte; { Set by linker so its offset is last in TLS segment }
|
||||
HInstance: LongWord; { Handle of this instance }
|
||||
{$EXTERNALSYM HInstance}
|
||||
(*$HPPEMIT 'namespace Sysinit' *)
|
||||
(*$HPPEMIT '{' *)
|
||||
(*$HPPEMIT 'extern PACKAGE HINSTANCE HInstance;' *)
|
||||
(*$HPPEMIT '} /* namespace Sysinit */' *)
|
||||
DllProc: TDLLProc; { Called whenever DLL entry point is called }
|
||||
{ DllProcEx passes the Reserved param provided by WinNT on DLL load & exit }
|
||||
DllProcEx: TDLLProcEx absolute DllProc;
|
||||
DataMark: Integer = 0; { Used to find the virtual base of DATA seg }
|
||||
CoverageLibraryName: array [0..128] of char = '*'; { initialized by the linker! }
|
||||
{$IFDEF ELF}
|
||||
TypeImportsTable: array [0..0] of Pointer platform; { VMT and RTTI imports table for exes }
|
||||
_GLOBAL_OFFSET_TABLE_: ARRAY [0..2] OF Cardinal platform;
|
||||
(* _DYNAMIC: ARRAY [0..0] OF Elf32_Dyn; *)
|
||||
{$IFDEF PC_MAPPED_EXCEPTIONS}
|
||||
TextStartAdj: Byte platform; { See GetTextStart }
|
||||
CodeSegSize: Byte platform; { See GetTextStart }
|
||||
function GetTextStart : LongInt; platform;
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
|
||||
const
|
||||
PtrToNil: Pointer = nil; // provides pointer to nil for compiler codegen
|
||||
|
||||
function _GetTls: Pointer;
|
||||
{$IFDEF LINUX}
|
||||
procedure _InitLib(Context: PInitContext);
|
||||
procedure _GetCallerEIP;
|
||||
procedure _InitExe(InitTable: Pointer; Argc: Integer; Argp: Pointer);
|
||||
procedure _start; cdecl;
|
||||
function _ExitLib: Integer; cdecl;
|
||||
function _InitPkg: LongBool;
|
||||
{$ENDIF}
|
||||
{$IFDEF MSWINDOWS}
|
||||
procedure _InitLib;
|
||||
procedure _InitExe(InitTable: Pointer);
|
||||
function _InitPkg(Hinst: Integer; Reason: Integer; Resvd: Pointer): LongBool; stdcall;
|
||||
{$ENDIF}
|
||||
procedure _PackageLoad(const Table: PackageInfo);
|
||||
procedure _PackageUnload(const Table: PackageInfo);
|
||||
|
||||
{ Invoked by C++ startup code to allow initialization of VCL global vars }
|
||||
procedure VclInit(isDLL, isPkg: Boolean; hInst: LongInt; isGui: Boolean); cdecl;
|
||||
procedure VclExit; cdecl;
|
||||
|
||||
{$IFDEF LINUX}
|
||||
function GetThisModuleHandle: LongWord;
|
||||
{$ENDIF}
|
||||
|
||||
implementation
|
||||
|
||||
{$IFDEF MSWINDOWS}
|
||||
{X+}// ***********************************************************************
|
||||
{X+}// Moved to System.pas {by A.Torgashin}
|
||||
{X+}//const
|
||||
{X+}// kernel = 'kernel32.dll';
|
||||
{X+}//
|
||||
{X+}//function FreeLibrary(ModuleHandle: Longint): LongBool; stdcall;
|
||||
{X+}// external kernel name 'FreeLibrary';
|
||||
{X+}//
|
||||
{X+}//function GetModuleFileName(Module: Integer; Filename: PChar; Size: Integer): Integer; stdcall;
|
||||
{X+}// external kernel name 'GetModuleFileNameA';
|
||||
{X+}//
|
||||
{X+}//function GetModuleHandle(ModuleName: PChar): Integer; stdcall;
|
||||
{X+}// external kernel name 'GetModuleHandleA';
|
||||
{X+}//
|
||||
{X+}//function LocalAlloc(flags, size: Integer): Pointer; stdcall;
|
||||
{X+}// external kernel name 'LocalAlloc';
|
||||
{X+}//
|
||||
{X+}//function LocalFree(addr: Pointer): Pointer; stdcall;
|
||||
{X+}// external kernel name 'LocalFree';
|
||||
{X+}//
|
||||
{X+}//function TlsAlloc: Integer; stdcall;
|
||||
{X+}// external kernel name 'TlsAlloc';
|
||||
{X+}//
|
||||
{X+}//function TlsFree(TlsIndex: Integer): Boolean; stdcall;
|
||||
{X+}// external kernel name 'TlsFree';
|
||||
{X+}//
|
||||
{X+}//function TlsGetValue(TlsIndex: Integer): Pointer; stdcall;
|
||||
{X+}// external kernel name 'TlsGetValue';
|
||||
{X+}//
|
||||
{X+}//function TlsSetValue(TlsIndex: Integer; TlsValue: Pointer): Boolean; stdcall;
|
||||
{X+}// external kernel name 'TlsSetValue';
|
||||
{X+}//
|
||||
{X+}//function GetCommandLine: PChar; stdcall;
|
||||
{X+}// external kernel name 'GetCommandLineA';
|
||||
{X+}// ***********************************************************************
|
||||
|
||||
const
|
||||
tlsArray = $2C; { offset of tls array from FS: }
|
||||
LMEM_ZEROINIT = $40;
|
||||
|
||||
function AllocTlsBuffer(Size: Integer): Pointer;
|
||||
begin
|
||||
Result := LocalAlloc(LMEM_ZEROINIT, Size);
|
||||
end;
|
||||
|
||||
var
|
||||
tlsBuffer: Pointer; // RTM32 DOS support
|
||||
{$ENDIF}
|
||||
|
||||
{$IFDEF LINUX}
|
||||
|
||||
{$IFDEF PIC}
|
||||
function GetGOT: Pointer; export;
|
||||
begin
|
||||
asm
|
||||
MOV Result,EBX
|
||||
end;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
const
|
||||
RTLD_LAZY = 1;
|
||||
RTLD_NOW = 2;
|
||||
RTLD_BINDING_MASK = RTLD_LAZY or RTLD_NOW;
|
||||
RTLD_GLOBAL = $100;
|
||||
RTLD_LOCAL = 0;
|
||||
RTLD_NEXT = Pointer(-1);
|
||||
RTLD_DEFAULT = nil;
|
||||
|
||||
type
|
||||
TDLInfo = record
|
||||
Filename: PChar;
|
||||
BaseAddress: Pointer;
|
||||
NearestSymbolName: PChar;
|
||||
NearestSymbolAddr: Pointer;
|
||||
end;
|
||||
|
||||
const
|
||||
libcmodulename = 'libc.so.6';
|
||||
libdlmodulename = 'libdl.so.2';
|
||||
libpthreadmodulename = 'libpthread.so.0';
|
||||
tlsSizeName = '@Sysinit@tlsSize';
|
||||
|
||||
function malloc(Size: LongWord): Pointer; cdecl;
|
||||
external libcmodulename name 'malloc';
|
||||
|
||||
procedure free(P: Pointer); cdecl;
|
||||
external libcmodulename name 'free';
|
||||
|
||||
function dlopen(Filename: PChar; Flag: Integer): LongWord; cdecl;
|
||||
external libdlmodulename name 'dlopen';
|
||||
|
||||
function dlerror: PChar; cdecl;
|
||||
external libdlmodulename name 'dlerror';
|
||||
|
||||
function dlsym(Handle: LongWord; Symbol: PChar): Pointer; cdecl;
|
||||
external libdlmodulename name 'dlsym';
|
||||
|
||||
function dlclose(Handle: LongWord): Integer; cdecl;
|
||||
external libdlmodulename name 'dlclose';
|
||||
|
||||
function FreeLibrary(Handle: LongWord): Integer; cdecl;
|
||||
external libdlmodulename name 'dlclose';
|
||||
|
||||
function dladdr(Address: Pointer; var Info: TDLInfo): Integer; cdecl;
|
||||
external libdlmodulename name 'dladdr';
|
||||
|
||||
type
|
||||
TInitOnceProc = procedure; cdecl;
|
||||
TKeyValueDestructor = procedure(ValueInKey: Pointer); cdecl;
|
||||
|
||||
function pthread_once(var InitOnceSemaphore: Integer; InitOnceProc: TInitOnceProc): Integer; cdecl;
|
||||
external libpthreadmodulename name 'pthread_once';
|
||||
|
||||
function pthread_key_create(var Key: Integer; KeyValueDestructor: TKeyValueDestructor): Integer; cdecl;
|
||||
external libpthreadmodulename name 'pthread_key_create';
|
||||
|
||||
function pthread_key_delete(Key: Integer): Integer; cdecl;
|
||||
external libpthreadmodulename name 'pthread_key_delete';
|
||||
|
||||
function TlsGetValue(Key: Integer): Pointer; cdecl;
|
||||
external libpthreadmodulename name 'pthread_getspecific';
|
||||
|
||||
function TlsSetValue(Key: Integer; Ptr: Pointer): Integer; cdecl;
|
||||
external libpthreadmodulename name 'pthread_setspecific';
|
||||
|
||||
function AllocTlsBuffer(Size: Cardinal): Pointer;
|
||||
begin
|
||||
// The C++ rtl handles all tls in a C++ module
|
||||
if ModuleIsCpp then
|
||||
RunError(226);
|
||||
|
||||
Result := malloc(Size);
|
||||
if Result <> nil then
|
||||
FillChar(Result^, Size, 0);
|
||||
end;
|
||||
|
||||
procedure FreeTLSBuffer(ValueInKey: Pointer); export cdecl;
|
||||
begin
|
||||
// The C++ rtl handles all tls in a C++ module
|
||||
if ModuleIsCpp then
|
||||
RunError(226);
|
||||
free(ValueInKey);
|
||||
end;
|
||||
|
||||
procedure AllocTlsIndex; cdecl export;
|
||||
begin
|
||||
// guaranteed to reach here only once per process
|
||||
// The C++ rtl handles all tls in a C++ module
|
||||
if ModuleIsCpp then
|
||||
RunError(226);
|
||||
if pthread_key_create(TlsIndex, FreeTLSBuffer) <> 0 then
|
||||
begin
|
||||
TlsIndex := -1;
|
||||
RunError(226);
|
||||
end;
|
||||
end;
|
||||
|
||||
function GetThisModuleHandle: LongWord;
|
||||
var
|
||||
Info: TDLInfo;
|
||||
begin
|
||||
if (dladdr(@GetThisModuleHandle, Info) = 0) or (Info.BaseAddress = ExeBaseAddress) then
|
||||
Info.FileName := nil; // if we're not in a library, we must be main exe
|
||||
Result := LongWord(dlopen(Info.Filename, RTLD_LAZY));
|
||||
if Result <> 0 then
|
||||
dlclose(Result);
|
||||
end;
|
||||
|
||||
var
|
||||
InitOnceSemaphore: Integer;
|
||||
{$ENDIF}
|
||||
|
||||
var
|
||||
Module: TLibModule = (
|
||||
Next: nil;
|
||||
Instance: 0;
|
||||
CodeInstance: 0;
|
||||
DataInstance: 0;
|
||||
ResInstance: 0;
|
||||
Reserved: 0
|
||||
{$IFDEF LINUX}
|
||||
; InstanceVar: nil;
|
||||
GOT: 0;
|
||||
CodeSegStart: 0;
|
||||
CodeSegEnd: 0
|
||||
);
|
||||
{$ELSE}
|
||||
);
|
||||
{$ENDIF}
|
||||
|
||||
function GetTlsSize: Integer;
|
||||
{$IFDEF LINUX}
|
||||
asm
|
||||
MOV EAX, offset TlsLast
|
||||
end;
|
||||
{$ENDIF}
|
||||
{$IFDEF MSWINDOWS}
|
||||
begin
|
||||
Result := Integer(@TlsLast);
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
procedure InitThreadTLS;
|
||||
var
|
||||
p: Pointer;
|
||||
tlsSize: Integer;
|
||||
begin
|
||||
tlsSize := GetTlsSize;
|
||||
if tlsSize = 0 then Exit;
|
||||
{$IFDEF LINUX}
|
||||
pthread_once(InitOnceSemaphore, AllocTlsIndex);
|
||||
{$ENDIF}
|
||||
if TlsIndex = -1 then RunError(226);
|
||||
p := AllocTlsBuffer(tlsSize);
|
||||
if p = nil then
|
||||
RunError(226)
|
||||
else
|
||||
TlsSetValue(TlsIndex, p);
|
||||
end;
|
||||
|
||||
{$IFDEF MSWINDOWS}
|
||||
procedure InitProcessTLS;
|
||||
begin
|
||||
if @TlsLast = nil then
|
||||
Exit;
|
||||
TlsIndex := TlsAlloc;
|
||||
InitThreadTLS;
|
||||
tlsBuffer := TlsGetValue(TlsIndex); // RTM32 DOS support
|
||||
end;
|
||||
|
||||
procedure ExitThreadTLS;
|
||||
var
|
||||
p: Pointer;
|
||||
begin
|
||||
if @TlsLast = nil then
|
||||
Exit;
|
||||
if TlsIndex <> -1 then begin
|
||||
p := TlsGetValue(TlsIndex);
|
||||
if p <> nil then
|
||||
LocalFree(p);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure ExitProcessTLS;
|
||||
begin
|
||||
if @TlsLast = nil then
|
||||
Exit;
|
||||
ExitThreadTLS;
|
||||
if TlsIndex <> -1 then
|
||||
TlsFree(TlsIndex);
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
const
|
||||
DLL_PROCESS_DETACH = 0;
|
||||
DLL_PROCESS_ATTACH = 1;
|
||||
DLL_THREAD_ATTACH = 2;
|
||||
DLL_THREAD_DETACH = 3;
|
||||
|
||||
function _GetTls: Pointer;
|
||||
{$IFDEF LINUX}
|
||||
begin
|
||||
Result := TlsGetValue(TlsIndex);
|
||||
if Result = nil then
|
||||
begin
|
||||
InitThreadTLS;
|
||||
Result := TlsGetValue(TlsIndex);
|
||||
end;
|
||||
end;
|
||||
{$ENDIF}
|
||||
{$IFDEF MSWINDOWS}
|
||||
asm
|
||||
MOV CL,ModuleIsLib
|
||||
MOV EAX,TlsIndex
|
||||
TEST CL,CL
|
||||
JNE @@isDll
|
||||
MOV EDX,FS:tlsArray
|
||||
MOV EAX,[EDX+EAX*4]
|
||||
RET
|
||||
|
||||
@@initTls:
|
||||
CALL InitThreadTLS
|
||||
MOV EAX,TlsIndex
|
||||
PUSH EAX
|
||||
CALL TlsGetValue
|
||||
TEST EAX,EAX
|
||||
JE @@RTM32
|
||||
RET
|
||||
|
||||
@@RTM32:
|
||||
MOV EAX, tlsBuffer
|
||||
RET
|
||||
|
||||
@@isDll:
|
||||
PUSH EAX
|
||||
CALL TlsGetValue
|
||||
TEST EAX,EAX
|
||||
JE @@initTls
|
||||
end;
|
||||
|
||||
const
|
||||
TlsProc: array [DLL_PROCESS_DETACH..DLL_THREAD_DETACH] of procedure =
|
||||
(ExitProcessTLS,InitProcessTLS,InitThreadTLS,ExitThreadTLS);
|
||||
{$ENDIF}
|
||||
|
||||
{$IFDEF PC_MAPPED_EXCEPTIONS}
|
||||
const
|
||||
UNWINDFI_TOPOFSTACK = $BE00EF00;
|
||||
|
||||
{
|
||||
The linker sets the value of TextStartAdj to be the delta between GetTextStart
|
||||
and the start of the text segment. This allows us to get the pointer to the
|
||||
start of the text segment in a position independent fashion.
|
||||
}
|
||||
function GetTextStart : LongInt;
|
||||
asm
|
||||
CALL @@label1
|
||||
@@label1:
|
||||
POP EAX
|
||||
SUB EAX, 5 + offset TextStartAdj
|
||||
end;
|
||||
|
||||
{
|
||||
The linker sets the value of CodeSegSize to the length of the text segment,
|
||||
excluding the PC map. This allows us to get the pointer to the exception
|
||||
information that we need at runtime, also in a position independent fashion.
|
||||
}
|
||||
function GetTextEnd : LongInt;
|
||||
asm
|
||||
CALL GetTextStart
|
||||
ADD EAX, offset CodeSegSize
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
procedure InitializeModule;
|
||||
begin
|
||||
RegisterModule(@Module);
|
||||
end;
|
||||
|
||||
{X+}procedure UseLocalizeResources;
|
||||
{X+}var
|
||||
{X+} FileName: array[0..260] of Char;
|
||||
{X+}begin
|
||||
{X+} GetModuleFileName(HInstance, FileName, SizeOf(FileName));
|
||||
{X+} Module.ResInstance := LoadResourceModule(FileName);
|
||||
{X+} if Module.ResInstance = 0 then
|
||||
{X+} Module.ResInstance := Module.Instance;
|
||||
{X+}end;
|
||||
|
||||
procedure UninitializeModule;
|
||||
begin
|
||||
UnregisterModule(@Module);
|
||||
if (Module.ResInstance <> Module.Instance) and (Module.ResInstance <> 0) then
|
||||
FreeLibrary(Module.ResInstance);
|
||||
end;
|
||||
|
||||
procedure VclInit(isDLL, isPkg: Boolean; hInst: LongInt; isGui: Boolean); cdecl;
|
||||
begin
|
||||
ModuleIsLib := isDLL;
|
||||
ModuleIsPackage := isPkg;
|
||||
IsLibrary := isDLL and not isPkg;
|
||||
HInstance := hInst;
|
||||
Module.Instance := hInst;
|
||||
Module.CodeInstance := 0;
|
||||
Module.DataInstance := 0;
|
||||
ModuleIsCpp := True;
|
||||
{$IFDEF LINUX}
|
||||
if ModuleIsLib then
|
||||
Module.InstanceVar := @HInstance;
|
||||
{$IFDEF PIC}
|
||||
Module.GOT := LongWord(GetGot);
|
||||
{$ENDIF}
|
||||
{ Module.CodeSegStart, Module.CodeSegEnd not used: the C++
|
||||
rtl will feed the unwinder. }
|
||||
{$ENDIF}
|
||||
InitializeModule;
|
||||
if not ModuleIsLib then
|
||||
begin
|
||||
Module.CodeInstance := FindHInstance(@VclInit);
|
||||
Module.DataInstance := FindHInstance(@DataMark);
|
||||
{$IFDEF MSWINDOWS}
|
||||
{X}// CmdLine := GetCommandLine;
|
||||
IsConsole := not isGui;
|
||||
{$ENDIF}
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure VclExit; cdecl;
|
||||
var
|
||||
P: procedure;
|
||||
begin
|
||||
if not ModuleIsLib then
|
||||
while ExitProc <> nil do
|
||||
begin
|
||||
@P := ExitProc;
|
||||
ExitProc := nil;
|
||||
P;
|
||||
end;
|
||||
UnInitializeModule;
|
||||
end;
|
||||
|
||||
{$IFDEF PC_MAPPED_EXCEPTIONS}
|
||||
procedure RegisterPCMap;
|
||||
begin
|
||||
SysRegisterIPLookup(GetTextStart,
|
||||
GetTextEnd,
|
||||
Pointer(GetTextEnd),
|
||||
LongWord(@_Global_Offset_Table_));
|
||||
end;
|
||||
|
||||
procedure UnregisterPCMap;
|
||||
begin
|
||||
SysUnregisterIPLookup(GetTextStart);
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
{$IFDEF MSWINDOWS}
|
||||
function _InitPkg(Hinst: Longint; Reason: Integer; Resvd: Pointer): Longbool; stdcall;
|
||||
begin
|
||||
ModuleIsLib := True;
|
||||
ModuleIsPackage := True;
|
||||
Module.Instance := Hinst;
|
||||
Module.CodeInstance := 0;
|
||||
Module.DataInstance := 0;
|
||||
HInstance := Hinst;
|
||||
if @TlsLast <> nil then
|
||||
TlsProc[Reason];
|
||||
if Reason = DLL_PROCESS_ATTACH then
|
||||
InitializeModule
|
||||
else if Reason = DLL_PROCESS_DETACH then
|
||||
UninitializeModule;
|
||||
_InitPkg := True;
|
||||
end;
|
||||
{$ENDIF}
|
||||
{$IFDEF LINUX}
|
||||
function _InitPkg: LongBool;
|
||||
begin
|
||||
{$IFDEF DEBUG_STARTUP}
|
||||
asm
|
||||
INT 3
|
||||
end;
|
||||
{$ENDIF}
|
||||
{$IFDEF PC_MAPPED_EXCEPTIONS}
|
||||
RegisterPCMap;
|
||||
{$ENDIF}
|
||||
TlsIndex := -1;
|
||||
ModuleIsLib := True;
|
||||
ModuleIsPackage := True;
|
||||
Module.Instance := GetThisModuleHandle;
|
||||
Module.InstanceVar := @HInstance;
|
||||
Module.CodeInstance := 0;
|
||||
Module.DataInstance := 0;
|
||||
Module.GOT := LongWord(@_Global_Offset_Table_);
|
||||
Module.CodeSegStart := GetTextStart;
|
||||
Module.CodeSegEnd := GetTextEnd;
|
||||
HInstance := Module.Instance;
|
||||
InitializeModule;
|
||||
_InitPkg := True;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
procedure _PackageLoad(const Table: PackageInfo);
|
||||
begin
|
||||
System._PackageLoad(Table, @Module);
|
||||
end;
|
||||
|
||||
procedure _PackageUnload(const Table: PackageInfo);
|
||||
begin
|
||||
System._PackageUnload(Table, @Module);
|
||||
end;
|
||||
|
||||
{$IFDEF MSWINDOWS}
|
||||
procedure _InitLib;
|
||||
asm
|
||||
{ -> EAX Inittable }
|
||||
{ [EBP+8] Hinst }
|
||||
{ [EBP+12] Reason }
|
||||
{ [EBP+16] Resvd }
|
||||
|
||||
MOV EDX,offset Module
|
||||
CMP dword ptr [EBP+12],DLL_PROCESS_ATTACH
|
||||
JNE @@notInit
|
||||
|
||||
PUSH EAX
|
||||
PUSH EDX
|
||||
MOV ModuleIsLib,1
|
||||
MOV ECX,[EBP+8]
|
||||
MOV HInstance,ECX
|
||||
MOV [EDX].TLibModule.Instance,ECX
|
||||
MOV [EDX].TLibModule.CodeInstance,0
|
||||
MOV [EDX].TLibModule.DataInstance,0
|
||||
CALL InitializeModule
|
||||
POP EDX
|
||||
POP EAX
|
||||
|
||||
@@notInit:
|
||||
PUSH DllProc
|
||||
MOV ECX,offset TlsProc
|
||||
CALL _StartLib
|
||||
end;
|
||||
|
||||
// ExitLib is the same as InitLib in Windows.
|
||||
|
||||
{$ENDIF MSWINDOWS}
|
||||
{$IFDEF LINUX}
|
||||
procedure _InitLib(Context: PInitContext);
|
||||
begin
|
||||
{$IFDEF DEBUG_STARTUP}
|
||||
asm
|
||||
INT 3
|
||||
end;
|
||||
{$ENDIF}
|
||||
asm
|
||||
PUSH UNWINDFI_TOPOFSTACK
|
||||
end;
|
||||
Context.DLLInitState := DLL_PROCESS_ATTACH;
|
||||
TlsIndex := -1;
|
||||
ModuleIsLib := True;
|
||||
HInstance := GetThisModuleHandle;
|
||||
Module.Instance := HInstance;
|
||||
Module.InstanceVar := @HInstance;
|
||||
Module.CodeInstance := 0;
|
||||
Module.DataInstance := 0;
|
||||
Module.GOT := LongWord(@_Global_Offset_Table_);
|
||||
Module.CodeSegStart := GetTextStart;
|
||||
Module.CodeSegEnd := GetTextEnd;
|
||||
InitializeModule;
|
||||
RegisterPCMap;
|
||||
_StartLib(Context, @Module, DLLProcEx);
|
||||
asm
|
||||
ADD ESP, 4
|
||||
end;
|
||||
end;
|
||||
|
||||
// InnerExitLib provides GOT fixup and global var addressing
|
||||
function InnerExitLib(Context: PInitContext): Integer;
|
||||
begin
|
||||
Result := 0;
|
||||
if ModuleIsPackage then
|
||||
begin
|
||||
UninitializeModule;
|
||||
UnregisterPCMap;
|
||||
end
|
||||
else
|
||||
_StartLib(Context, @Module, DLLProcEx);
|
||||
end;
|
||||
|
||||
function _ExitLib: Integer; cdecl;
|
||||
asm
|
||||
{$IFDEF DEBUG_STARTUP}
|
||||
INT 3
|
||||
{$ENDIF}
|
||||
PUSH EBP
|
||||
MOV EBP,ESP
|
||||
PUSH UNWINDFI_TOPOFSTACK
|
||||
XOR EAX,EAX
|
||||
PUSH DLL_PROCESS_DETACH // InitContext.DLLInitState
|
||||
PUSH EDI
|
||||
PUSH ESI
|
||||
PUSH EBX
|
||||
PUSH EBP
|
||||
PUSH EAX // InitContext.Module
|
||||
PUSH EAX // InitContext.InitCount
|
||||
PUSH EAX // InitContext.InitTable (filled in later)
|
||||
PUSH EAX // InitContext.OuterContext
|
||||
MOV EAX,ESP
|
||||
CALL InnerExitLib;
|
||||
ADD ESP, 16
|
||||
POP EBP
|
||||
POP EBX
|
||||
POP ESI
|
||||
POP EDI
|
||||
MOV ESP,EBP
|
||||
POP EBP
|
||||
end;
|
||||
|
||||
procedure _GetCallerEIP;
|
||||
asm
|
||||
MOV EBX, [ESP]
|
||||
end;
|
||||
{$ENDIF LINUX}
|
||||
|
||||
{$IFDEF MSWINDOWS}
|
||||
procedure _InitExe(InitTable: Pointer);
|
||||
begin
|
||||
TlsIndex := 0;
|
||||
HInstance := GetModuleHandle(nil);
|
||||
Module.Instance := HInstance;
|
||||
Module.CodeInstance := 0;
|
||||
Module.DataInstance := 0;
|
||||
InitializeModule;
|
||||
_StartExe(InitTable, @Module);
|
||||
end;
|
||||
{$ENDIF MSWINDOWS}
|
||||
{$IFDEF LINUX}
|
||||
procedure InitVmtImports;
|
||||
var
|
||||
P: ^Integer;
|
||||
begin
|
||||
P := @TypeImportsTable;
|
||||
if P = nil then Exit;
|
||||
while P^ <> 0 do
|
||||
begin
|
||||
P^ := Integer(dlsym(0, PChar(P^)));
|
||||
Inc(P);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure _InitExe(InitTable: Pointer; Argc: Integer; Argp: Pointer); export;
|
||||
begin
|
||||
{$IFDEF DEBUG_STARTUP}
|
||||
asm
|
||||
INT 3
|
||||
end;
|
||||
{$ENDIF}
|
||||
HInstance := GetThisModuleHandle;
|
||||
Module.Instance := HInstance;
|
||||
Module.InstanceVar := @HInstance;
|
||||
Module.CodeInstance := 0;
|
||||
Module.DataInstance := 0;
|
||||
InitializeModule;
|
||||
InitThreadTLS;
|
||||
{$IFDEF PC_MAPPED_EXCEPTIONS}
|
||||
RegisterPCMap();
|
||||
{$ENDIF}
|
||||
InitVmtImports;
|
||||
_StartExe(InitTable, @Module, Argc, Argp);
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
|
||||
{$IFDEF LINUX}
|
||||
var
|
||||
InitAddr: Pointer;
|
||||
|
||||
function _main(argc: Integer; argv: Pointer; envp: Pointer): Integer; export cdecl;
|
||||
type
|
||||
TInitFunction = function (argc: Integer; argv, envp: Pointer): Integer; cdecl;
|
||||
TExternalInit = function (argc: Integer; argv, envp: Pointer; InitExe: TInitFunction): Integer; cdecl;
|
||||
var
|
||||
ExternalInit: TExternalInit;
|
||||
InitFunc: TInitFunction;
|
||||
begin
|
||||
@ExternalInit := dlsym(GetThisModuleHandle, 'ExternalInit');
|
||||
@InitFunc := InitAddr;
|
||||
System.envp := envp;
|
||||
if @ExternalInit <> nil then
|
||||
ExternalInit(argc, argv, envp, InitFunc);
|
||||
Result := InitFunc(argc, argv, envp);
|
||||
end;
|
||||
|
||||
function __libc_start_main (Main: Pointer; Argc: Integer; Argv: Pointer;
|
||||
Init, Fini, rtld_Fini: Pointer; StackEnd: Pointer)
|
||||
: Integer;
|
||||
cdecl;
|
||||
external libcmodulename name '__libc_start_main';
|
||||
|
||||
{ Program entry point }
|
||||
procedure _start;
|
||||
asm
|
||||
{$IFDEF DEBUG_STARTUP}
|
||||
INT 3
|
||||
{$ENDIF}
|
||||
{ Mark outermost frame, suggested by ELF i386 ABI. }
|
||||
xor ebp,ebp
|
||||
|
||||
{ Get data passed on stack }
|
||||
pop eax { argc }
|
||||
mov ecx,esp { argv }
|
||||
|
||||
{ Align stack }
|
||||
and esp,0fffffff8h
|
||||
{$IFDEF PC_MAPPED_EXCEPTIONS}
|
||||
{ Mark the top of the stack with a signature }
|
||||
push UNWINDFI_TOPOFSTACK
|
||||
{$ENDIF}
|
||||
push ebp { padding }
|
||||
push esp { crt1.o does this, don't know why }
|
||||
push edx { function to be registered with
|
||||
atexit(), passed by loader }
|
||||
push offset @@ret { _fini dummy }
|
||||
push offset @@ret { _init dummy }
|
||||
push ecx { argv }
|
||||
push eax { argc }
|
||||
{ We need a symbol for the Pascal entry point (main unit's
|
||||
body). An external symbol `main' fixed up by the linker
|
||||
would be fine. Alas, external declarations can't do that;
|
||||
they must be resolved either in the same file with a $L
|
||||
directive, or in a shared object. Hack: use a bogus,
|
||||
distinctive symbol to mark the fixup, find and patch it
|
||||
in the linker. }
|
||||
{$IFDEF PIC}
|
||||
call GetGOT
|
||||
mov ebx, eax
|
||||
add [esp+12],ebx
|
||||
add [esp+8],ebx
|
||||
// Linker will replace _GLOBAL_OFFSET_TABLE_ address with main program block
|
||||
mov eax, offset _GLOBAL_OFFSET_TABLE_
|
||||
add eax, ebx
|
||||
mov [ebx].InitAddr, eax
|
||||
mov eax, offset _main
|
||||
add eax, ebx
|
||||
push eax
|
||||
{$ELSE}
|
||||
// Linker will replace _GLOBAL_OFFSET_TABLE_ address with main program block
|
||||
push offset _GLOBAL_OFFSET_TABLE_
|
||||
pop InitAddr
|
||||
push offset _main
|
||||
{$ENDIF}
|
||||
call __libc_start_main
|
||||
hlt { they never come back }
|
||||
|
||||
@@ret:
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
{$IFDEF LINUX}
|
||||
{ Procedure body not generated on Windows currently }
|
||||
procedure OpenEdition;
|
||||
begin
|
||||
end;
|
||||
|
||||
procedure GPLInfected;
|
||||
begin
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
procedure Copyright;
|
||||
begin
|
||||
end;
|
||||
|
||||
const
|
||||
sOpenEdition = 'This application was built with Borland Kylix Open Edition(tm).';
|
||||
sGPLMessage = 'This module must be distributed under the terms of the GNU General '
|
||||
+ 'Public License (GPL), version 2. A copy of this license can be found at:'
|
||||
+ 'http://www.borland.com/kylix/gpl.html.';
|
||||
|
||||
exports
|
||||
{$IF Declared(GPL)}
|
||||
OpenEdition name sOpenEdition,
|
||||
GPLInfected name sGPLMessage,
|
||||
{$IFEND}
|
||||
|
||||
|
||||
|
||||
|
||||
Copyright name 'Portions Copyright (c) 1983,2002 Borland Software Corporation';
|
||||
|
||||
|
||||
{$IF Declared(GPL)}
|
||||
initialization
|
||||
if IsConsole and not ModuleIsLib then
|
||||
begin
|
||||
TTextRec(Output).Mode := fmClosed;
|
||||
writeln(sGPLMessage);
|
||||
end;
|
||||
{$IFEND}
|
||||
{$ENDIF}
|
||||
end.
|
||||
|
||||
|
22
System/D2006betaECM/SysSfIni.pas
Normal file
22
System/D2006betaECM/SysSfIni.pas
Normal file
@ -0,0 +1,22 @@
|
||||
unit SysSfIni;
|
||||
{X: this unit must be referenced in uses clause of dpr as earlier as possible,
|
||||
if You want to use try-execpt/raise protected initialization and finalization
|
||||
for your units. }
|
||||
|
||||
{$O+,H+,I-,S-}
|
||||
|
||||
interface
|
||||
|
||||
implementation
|
||||
|
||||
initialization
|
||||
|
||||
InitUnitsProc := InitUnitsHard;
|
||||
FInitUnitsProc := FInitUnitsHard;
|
||||
UnregisterModule := UnregisterModuleSafely;
|
||||
UnsetExceptionHandlerProc := UnsetExceptionHandler;
|
||||
SetExceptionHandler;
|
||||
|
||||
finalization
|
||||
|
||||
end.
|
18874
System/D2006betaECM/System.pas
Normal file
18874
System/D2006betaECM/System.pas
Normal file
File diff suppressed because it is too large
Load Diff
1541
System/D2006betaECM/getmem.inc
Normal file
1541
System/D2006betaECM/getmem.inc
Normal file
File diff suppressed because it is too large
Load Diff
43
System/D2006betaECM/makefile
Normal file
43
System/D2006betaECM/makefile
Normal file
@ -0,0 +1,43 @@
|
||||
# ******************************************************************
|
||||
# * *
|
||||
# * DELPHI7 KOL RTL Replacement *
|
||||
# * MAKE script *
|
||||
# * *
|
||||
# * (C) 2005 by ECM *
|
||||
# * *
|
||||
# ******************************************************************
|
||||
|
||||
# To build the runtime library without debug information (the default),
|
||||
# simply run MAKE.EXE from the directory containing this MAKEFILE. To
|
||||
# build a debug version of the runtime library, specify a -DDEBUG command
|
||||
# line parameter when running MAKE.EXE.
|
||||
|
||||
DCC = dcc32 -q
|
||||
|
||||
BIN = bin
|
||||
LIB = lib
|
||||
|
||||
!if $d(DEBUG)
|
||||
RTLDEBUG = -$$D+
|
||||
!else
|
||||
RTLDEBUG = -$$D-
|
||||
!endif
|
||||
|
||||
default: \
|
||||
system.dcu \
|
||||
SysConst.dcu \
|
||||
SysSfIni.dcu \
|
||||
SysWStr.dcu
|
||||
|
||||
|
||||
system.dcu: system.pas sysinit.pas getmem.inc
|
||||
$(DCC) system -m -y -z $(RTLDEBUG)
|
||||
|
||||
SysConst.dcu: SysConst.pas system.dcu
|
||||
$(DCC) SysConst -z $(RTLDEBUG)
|
||||
|
||||
SysSfIni.dcu: SysSfIni.pas
|
||||
$(DCC) SysSfIni -z $(RTLDEBUG)
|
||||
|
||||
SysWStr.dcu: SysWStr.pas
|
||||
$(DCC) SysWStr -z $(RTLDEBUG)
|
Reference in New Issue
Block a user