mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-19 13:59:29 +02:00
Merged revision(s) 31682, 31703-31704, 31719, 31761-31762, 32008, 32021-32024, 32033, 32035 from trunk (Android PIC support):
* arm-android: PIC compatible library startup code. ........ * ARM assembler routines are PIC compatible now. ........ * arm-android: Enable PIC by default. ........ * arm-android: Do not use register r4, since it must be preserved. Use r3 instead. ........ * i386-android: Library startup code is PIC compatible. ........ * Added a comment. ........ * android: Simply jump to the libc exit(). ........ * Enable PIC by default for i386-android. ........ * arm-android: Simplified _haltproc for dll. ........ * android: Generate PIC executables. It is required for Android 5.0+. ........ * arm-android: Use PIC in the program start-up code. ........ * android: Fixed crash when using writeln during shared library finalization on Android 4.4+. ........ * i386-android: Use PIC in the program start-up code. ........ git-svn-id: branches/fixes_3_0@33440 -
This commit is contained in:
parent
4d62e12dfe
commit
fccd5e534d
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -7972,6 +7972,7 @@ rtl/android/jvm/java_sysh_android.inc svneol=native#text/plain
|
||||
rtl/android/jvm/rtl.cfg svneol=native#text/plain
|
||||
rtl/android/mipsel/dllprt0.as svneol=native#text/plain
|
||||
rtl/android/mipsel/prt0.as svneol=native#text/plain
|
||||
rtl/android/sysandroid.inc svneol=native#text/plain
|
||||
rtl/arm/arm.inc svneol=native#text/plain
|
||||
rtl/arm/armdefines.inc svneol=native#text/plain
|
||||
rtl/arm/divide.inc svneol=native#text/plain
|
||||
|
@ -36,7 +36,8 @@ unit i_android;
|
||||
shortname : 'Android';
|
||||
flags : [tf_needs_symbol_size,tf_needs_symbol_type,tf_files_case_sensitive,
|
||||
tf_requires_proper_alignment, tf_safecall_exceptions,
|
||||
tf_smartlink_sections,tf_smartlink_library,tf_has_winlike_resources];
|
||||
tf_pic_uses_got, tf_pic_default,
|
||||
tf_smartlink_sections,tf_has_winlike_resources];
|
||||
cpu : cpu_arm;
|
||||
unit_env : 'ANDROIDUNITS';
|
||||
extradefines : 'UNIX;HASUNIX;CPUARMEL';
|
||||
@ -98,10 +99,10 @@ unit i_android;
|
||||
system : system_i386_ANDROID;
|
||||
name : 'Android for i386';
|
||||
shortname : 'Android';
|
||||
flags : [tf_needs_symbol_size,tf_pic_uses_got,tf_smartlink_sections,
|
||||
tf_needs_symbol_type,tf_files_case_sensitive,
|
||||
tf_smartlink_library,tf_needs_dwarf_cfi,tf_has_winlike_resources,
|
||||
tf_safecall_exceptions, tf_safecall_clearstack];
|
||||
flags : [tf_needs_symbol_size,tf_needs_symbol_type,tf_files_case_sensitive,
|
||||
tf_needs_dwarf_cfi,tf_has_winlike_resources,
|
||||
tf_pic_uses_got, tf_pic_default, tf_smartlink_sections,
|
||||
tf_safecall_exceptions];
|
||||
cpu : cpu_i386;
|
||||
unit_env : 'ANDROIDUNITS';
|
||||
extradefines : 'UNIX;HASUNIX';
|
||||
|
@ -328,6 +328,8 @@ begin
|
||||
Message1(exec_i_linking, outname);
|
||||
|
||||
opts:='';
|
||||
if not IsSharedLib and (cs_create_pic in current_settings.moduleswitches) then
|
||||
opts:=opts + ' --pic-executable';
|
||||
if (cs_link_strip in current_settings.globalswitches) and
|
||||
not (cs_link_separate_dbg_file in current_settings.globalswitches) then
|
||||
opts:=opts + ' -s';
|
||||
|
@ -3398,6 +3398,7 @@ endif
|
||||
.NOTPARALLEL:
|
||||
include $(INC)/makefile.inc
|
||||
SYSINCDEPS=$(addprefix $(INC)/,$(SYSINCNAMES))
|
||||
SYSINCDEPS:=$(SYSINCDEPS) sysandroid.inc
|
||||
include $(PROCINC)/makefile.cpu
|
||||
SYSCPUDEPS=$(addprefix $(PROCINC)/,$(CPUINCNAMES))
|
||||
SYSDEPS=$(SYSINCDEPS) $(SYSCPUDEPS)
|
||||
|
@ -83,6 +83,7 @@ OBJPASDIR=$(RTL)/objpas
|
||||
# SYSINCNAMES
|
||||
include $(INC)/makefile.inc
|
||||
SYSINCDEPS=$(addprefix $(INC)/,$(SYSINCNAMES))
|
||||
SYSINCDEPS:=$(SYSINCDEPS) sysandroid.inc
|
||||
|
||||
# Get the processor dependent include file names.
|
||||
# This will set the following variables :
|
||||
|
@ -24,27 +24,46 @@ FPC_SHARED_LIB_START:
|
||||
stmfd sp!,{fp, ip, lr, pc}
|
||||
sub fp, ip, #4
|
||||
|
||||
/* Get GOT */
|
||||
ldr r3,.L_GOT1
|
||||
.LPIC1:
|
||||
add r3,pc,r3
|
||||
|
||||
/* Save initial stackpointer */
|
||||
ldr ip,=__stkptr
|
||||
ldr ip,.L__stkptr
|
||||
ldr ip,[r3, ip]
|
||||
str sp,[ip]
|
||||
|
||||
/* Get environment info from libc */
|
||||
ldr ip,=environ
|
||||
ldr ip,.Lenviron
|
||||
ldr ip,[r3, ip]
|
||||
ldr r0,[ip]
|
||||
/* Check if environment is NULL */
|
||||
cmp r0,#0
|
||||
ldreq r0,=EmptyEnv
|
||||
ldr ip,=operatingsystem_parameter_envp
|
||||
ldreq r0,.LEmptyEnv
|
||||
ldreq r0,[r3, r0]
|
||||
ldr ip,.Loperatingsystem_parameter_envp
|
||||
ldr ip,[r3, ip]
|
||||
str r0,[ip]
|
||||
|
||||
/* Register exit handler. It is called only when the main process terminates */
|
||||
ldr r0,=FPC_LIB_EXIT
|
||||
blx atexit
|
||||
|
||||
/* call main and exit normally */
|
||||
/* Call main */
|
||||
blx PASCALMAIN
|
||||
/* Call library init */
|
||||
blx FPC_LIB_INIT_ANDROID
|
||||
|
||||
ldmea fp, {fp, sp, pc}
|
||||
|
||||
.L_GOT1:
|
||||
.long _GLOBAL_OFFSET_TABLE_-.LPIC1-8
|
||||
.L__stkptr:
|
||||
.word __stkptr(GOT)
|
||||
.Lenviron:
|
||||
.word environ(GOT)
|
||||
.LEmptyEnv:
|
||||
.word EmptyEnv(GOT)
|
||||
.Loperatingsystem_parameter_envp:
|
||||
.word operatingsystem_parameter_envp(GOT)
|
||||
|
||||
/* --------------------------------------------------------- */
|
||||
.globl _haltproc
|
||||
.type _haltproc,#function
|
||||
@ -52,11 +71,8 @@ _haltproc:
|
||||
.globl _haltproc_eabi
|
||||
.type _haltproc_eabi,#function
|
||||
_haltproc_eabi:
|
||||
ldr r0,=operatingsystem_result
|
||||
ldr r0,[r0]
|
||||
/* Go to libc exit() */
|
||||
ldr ip,=exit
|
||||
bx ip
|
||||
/* Simply call libc exit(). _haltproc has the same declaration as exit. */
|
||||
blx exit
|
||||
|
||||
/* --------------------------------------------------------- */
|
||||
.data
|
||||
|
@ -37,29 +37,52 @@
|
||||
.globl _fpc_start
|
||||
.type _fpc_start,#function
|
||||
_fpc_start:
|
||||
/* Get GOT */
|
||||
ldr r3,.L_GOT1
|
||||
.LPIC1:
|
||||
add r3,pc,r3
|
||||
|
||||
/* Clear the frame pointer since this is the outermost frame. */
|
||||
mov fp, #0
|
||||
/* Save initial stackpointer */
|
||||
ldr ip,=__stkptr
|
||||
ldr ip,.L__stkptr
|
||||
ldr ip,[r3, ip]
|
||||
str sp,[ip]
|
||||
mov r4,sp
|
||||
mov r0,sp
|
||||
/* Pop argc off the stack and save a pointer to argv */
|
||||
ldmia r4!, {r5}
|
||||
ldr ip,=operatingsystem_parameter_argc
|
||||
str r5,[ip]
|
||||
ldr ip,=operatingsystem_parameter_argv
|
||||
str r4,[ip]
|
||||
ldmia r0!, {r1}
|
||||
ldr ip,.Loperatingsystem_parameter_argc
|
||||
ldr ip,[r3, ip]
|
||||
str r1,[ip]
|
||||
ldr ip,.Loperatingsystem_parameter_argv
|
||||
ldr ip,[r3, ip]
|
||||
str r0,[ip]
|
||||
|
||||
/* calc envp */
|
||||
add r5,r5,#1
|
||||
add r5,r4,r5,LSL #2
|
||||
ldr ip,=operatingsystem_parameter_envp
|
||||
str r5,[ip]
|
||||
add r1,r1,#1
|
||||
add r1,r0,r1,LSL #2
|
||||
ldr ip,.Loperatingsystem_parameter_envp
|
||||
ldr ip,[r3, ip]
|
||||
str r1,[ip]
|
||||
|
||||
/* Finally go to libc startup code. It will call "PASCALMAIN" via alias "main" */
|
||||
ldr ip,=_start
|
||||
ldr ip,.L_start
|
||||
ldr ip,[r3, ip]
|
||||
bx ip
|
||||
|
||||
.L_GOT1:
|
||||
.long _GLOBAL_OFFSET_TABLE_-.LPIC1-8
|
||||
.L__stkptr:
|
||||
.word __stkptr(GOT)
|
||||
.L_start:
|
||||
.word _start(GOT)
|
||||
.Loperatingsystem_parameter_argc:
|
||||
.word operatingsystem_parameter_argc(GOT)
|
||||
.Loperatingsystem_parameter_argv:
|
||||
.word operatingsystem_parameter_argv(GOT)
|
||||
.Loperatingsystem_parameter_envp:
|
||||
.word operatingsystem_parameter_envp(GOT)
|
||||
|
||||
/* --------------------------------------------------------- */
|
||||
.globl _haltproc
|
||||
.type _haltproc,#function
|
||||
@ -67,11 +90,8 @@ _haltproc:
|
||||
.globl _haltproc_eabi
|
||||
.type _haltproc_eabi,#function
|
||||
_haltproc_eabi:
|
||||
ldr r0,=operatingsystem_result
|
||||
ldr r0,[r0]
|
||||
/* Go to libc exit() */
|
||||
ldr ip,=exit
|
||||
bx ip
|
||||
/* Simply call libc exit(). _haltproc has the same declaration as exit. */
|
||||
blx exit
|
||||
|
||||
/* --------------------------------------------------------- */
|
||||
.data
|
||||
|
@ -25,26 +25,36 @@ FPC_SHARED_LIB_START:
|
||||
/* Align the stack to a 16 byte boundary */
|
||||
andl $~15, %esp
|
||||
|
||||
/* Save ebx */
|
||||
pushl %ebx
|
||||
|
||||
/* GOT init */
|
||||
call fpc_geteipasebx
|
||||
addl $_GLOBAL_OFFSET_TABLE_,%ebx
|
||||
|
||||
/* Save initial stackpointer */
|
||||
movl %esp,__stkptr
|
||||
movl __stkptr@GOT(%ebx),%eax
|
||||
movl %esp,(%eax)
|
||||
|
||||
/* Get environment info from libc */
|
||||
movl environ,%eax
|
||||
movl environ@GOT(%ebx),%eax
|
||||
movl (%eax),%eax
|
||||
/* Check if environment is NULL */
|
||||
test %eax,%eax
|
||||
jne env_ok
|
||||
leal EmptyEnv,%eax
|
||||
movl EmptyEnv@GOT(%ebx),%eax
|
||||
env_ok:
|
||||
movl %eax,operatingsystem_parameter_envp
|
||||
movl operatingsystem_parameter_envp@GOT(%ebx),%edx
|
||||
movl %eax,(%edx)
|
||||
|
||||
/* Register exit handler. It is called only when the main process terminates */
|
||||
leal FPC_LIB_EXIT,%eax
|
||||
pushl %eax
|
||||
call atexit
|
||||
addl $4,%esp
|
||||
/* Restore ebx */
|
||||
popl %ebx
|
||||
|
||||
/* Call main */
|
||||
call PASCALMAIN@PLT
|
||||
/* Call library init */
|
||||
call FPC_LIB_INIT_ANDROID@PLT
|
||||
|
||||
/* call main and exit normally */
|
||||
call PASCALMAIN
|
||||
leave
|
||||
ret
|
||||
|
||||
@ -52,10 +62,11 @@ env_ok:
|
||||
.globl _haltproc
|
||||
.type _haltproc,@function
|
||||
_haltproc:
|
||||
movzwl operatingsystem_result,%ebx
|
||||
pushl %ebx
|
||||
/* Call libc exit() */
|
||||
call exit
|
||||
/* GOT init */
|
||||
call fpc_geteipasebx
|
||||
addl $_GLOBAL_OFFSET_TABLE_,%ebx
|
||||
/* Jump to libc exit(). _haltproc has the same declaration as exit. */
|
||||
jmp exit@PLT
|
||||
|
||||
/* --------------------------------------------------------- */
|
||||
.data
|
||||
|
@ -42,36 +42,45 @@
|
||||
.globl _fpc_start
|
||||
.type _fpc_start,@function
|
||||
_fpc_start:
|
||||
/* GOT init */
|
||||
call fpc_geteipasebx
|
||||
addl $_GLOBAL_OFFSET_TABLE_,%ebx
|
||||
/* Clear the frame pointer since this is the outermost frame. */
|
||||
xorl %ebp,%ebp
|
||||
/* Save initial stackpointer */
|
||||
movl %esp,__stkptr
|
||||
movl __stkptr@GOT(%ebx),%eax
|
||||
movl %esp,(%eax)
|
||||
/* First locate the start of the environment variables */
|
||||
/* Get argc in ecx */
|
||||
movl (%esp),%ecx
|
||||
/* Save argc */
|
||||
movl %ecx,operatingsystem_parameter_argc
|
||||
/* Get argv pointer in ebx */
|
||||
leal 4(%esp),%ebx
|
||||
movl operatingsystem_parameter_argc@GOT(%ebx),%eax
|
||||
movl %ecx,(%eax)
|
||||
/* Get argv pointer in edx */
|
||||
leal 4(%esp),%edx
|
||||
/* Save argv */
|
||||
movl %ebx,operatingsystem_parameter_argv
|
||||
movl operatingsystem_parameter_argv@GOT(%ebx),%eax
|
||||
movl %edx,(%eax)
|
||||
/* The start of the environment is: esp+ecx*4+12 */
|
||||
leal 12(%esp,%ecx,4),%eax
|
||||
leal 12(%esp,%ecx,4),%edx
|
||||
/* Save envp */
|
||||
movl %eax,operatingsystem_parameter_envp
|
||||
movl operatingsystem_parameter_envp@GOT(%ebx),%eax
|
||||
movl %edx,(%eax)
|
||||
|
||||
/* Finally go to libc startup code. It will call "PASCALMAIN" via alias "main" */
|
||||
/* Finally go to libc startup code. It will call "PASCALMAIN" via alias "main". */
|
||||
/* No need to align stack since it will aligned by libc. */
|
||||
jmp _start
|
||||
|
||||
/* --------------------------------------------------------- */
|
||||
.globl _haltproc
|
||||
.type _haltproc,@function
|
||||
_haltproc:
|
||||
movzwl operatingsystem_result,%ebx
|
||||
pushl %ebx
|
||||
/* Call libc exit() */
|
||||
call exit
|
||||
|
||||
/* GOT init */
|
||||
call fpc_geteipasebx
|
||||
addl $_GLOBAL_OFFSET_TABLE_,%ebx
|
||||
/* Jump to libc exit(). _haltproc has the same declaration as exit. */
|
||||
jmp exit@PLT
|
||||
|
||||
/* --------------------------------------------------------- */
|
||||
.data
|
||||
/* Define a symbol for the first piece of initialized data. */
|
||||
|
@ -43,14 +43,12 @@ GotEnv:
|
||||
la $t1, operatingsystem_parameter_envp
|
||||
sw $t0, ($t1)
|
||||
|
||||
/* Register exit handler */
|
||||
la $a0, FPC_LIB_EXIT
|
||||
jal atexit
|
||||
nop
|
||||
|
||||
/* Call main, exit */
|
||||
/* Call main */
|
||||
jal PASCALMAIN
|
||||
nop
|
||||
/* Call library init */
|
||||
jal FPC_LIB_INIT_ANDROID
|
||||
nop
|
||||
|
||||
/* restore registers, exit */
|
||||
lw $ra, 24($sp)
|
||||
|
60
rtl/android/sysandroid.inc
Normal file
60
rtl/android/sysandroid.inc
Normal file
@ -0,0 +1,60 @@
|
||||
{
|
||||
This file is part of the Free Pascal run time library.
|
||||
Copyright (c) 2015 by Yury Sidorov,
|
||||
member of the Free Pascal development team.
|
||||
|
||||
Android-specific part of the System unit.
|
||||
|
||||
See the file COPYING.FPC, included in this distribution,
|
||||
for details about the copyright.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**********************************************************************}
|
||||
|
||||
procedure atexit(p: pointer); cdecl; external;
|
||||
|
||||
var
|
||||
_SaveStdOut: THandle;
|
||||
_SaveStdErr: THandle;
|
||||
|
||||
procedure SysAndroidLibExit; cdecl;
|
||||
var
|
||||
ioclosed: boolean;
|
||||
begin
|
||||
// Check if stdio is closed now
|
||||
ioclosed:=do_syscall(syscall_nr_fcntl, TSysParam(1), 1 {F_GETFD}) = -1;
|
||||
// If stdio is closed, restore stdout and stderr
|
||||
if ioclosed then
|
||||
begin
|
||||
FpDup2(_SaveStdOut, 1);
|
||||
FpDup2(_SaveStdErr, 2);
|
||||
end;
|
||||
// Close saved handles
|
||||
FpClose(_SaveStdOut);
|
||||
FpClose(_SaveStdErr);
|
||||
// Finalize the library
|
||||
lib_exit;
|
||||
// Close stdout and stderr if stdio has been closed
|
||||
if ioclosed then
|
||||
begin
|
||||
FpClose(1);
|
||||
FpClose(2);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure SysInitAndroidLib; [public, alias:'FPC_LIB_INIT_ANDROID'];
|
||||
begin
|
||||
{ Starting from Android 4.4 stdio handles are closed by libc prior to calling
|
||||
finalization routines of shared libraries. This causes a error while trying to
|
||||
writeln during library finalization and finally a crash because the error can
|
||||
not be printer too.
|
||||
It is needed to save stdout and stderr handles by duplicating them and restore
|
||||
them before library finalization.
|
||||
}
|
||||
_SaveStdOut:=FpDup(1);
|
||||
_SaveStdErr:=FpDup(2);
|
||||
// Register the finalization routine
|
||||
atexit(@SysAndroidLibExit);
|
||||
end;
|
163
rtl/arm/arm.inc
163
rtl/arm/arm.inc
@ -321,15 +321,22 @@ asm
|
||||
end;
|
||||
|
||||
const
|
||||
moveproc : pointer = @move_blended;
|
||||
moveproc : procedure(const source;var dest;count:longint) = @move_blended;
|
||||
|
||||
procedure Move(const source;var dest;count:longint);[public, alias: 'FPC_MOVE'];assembler;nostackframe;
|
||||
procedure Move(const source;var dest;count:longint);[public, alias: 'FPC_MOVE']; {$ifndef FPC_PIC} assembler;nostackframe; {$endif FPC_PIC}
|
||||
{$ifdef FPC_PIC}
|
||||
begin
|
||||
moveproc(source,dest,count);
|
||||
end;
|
||||
{$else FPC_PIC}
|
||||
asm
|
||||
ldr ip,.Lmoveproc
|
||||
ldr pc,[ip]
|
||||
.Lmoveproc:
|
||||
.long moveproc
|
||||
end;
|
||||
{$endif FPC_PIC}
|
||||
|
||||
{$endif CPUARM_HAS_EDSP}
|
||||
|
||||
{$endif FPC_SYSTEM_HAS_MOVE}
|
||||
@ -541,10 +548,49 @@ asm
|
||||
// Jump without a link, so freemem directly returns to our caller
|
||||
b FPC_FREEMEM
|
||||
end;
|
||||
|
||||
{$define FPC_SYSTEM_HAS_ANSISTR_INCR_REF}
|
||||
Procedure fpc_ansistr_incr_ref (S : Pointer); [Public,Alias:'FPC_ANSISTR_INCR_REF'];assembler;nostackframe; compilerproc;
|
||||
asm
|
||||
// Null string?
|
||||
cmp r0, #0
|
||||
// Load reference counter
|
||||
ldrne r1, [r0, #-8]
|
||||
// pointer to counter, calculate here for delay slot utilization
|
||||
subne r0, r0, #8
|
||||
{$ifdef CPUARM_HAS_BX}
|
||||
bxeq lr
|
||||
{$else}
|
||||
moveq pc,lr
|
||||
{$endif}
|
||||
// Check for a constant string
|
||||
cmp r1, #0
|
||||
// Tailcall
|
||||
// Hopefully the linker will place InterLockedIncrement as layed out here
|
||||
bge InterLockedIncrement
|
||||
// Freepascal will generate a proper return here, save some cachespace
|
||||
end;
|
||||
{$endif not darwin}
|
||||
|
||||
var
|
||||
fpc_system_lock: longint; export name 'fpc_system_lock';
|
||||
// --- InterLocked functions begin
|
||||
|
||||
{$if not defined(CPUARM_HAS_LDREX) and not defined(SYSTEM_HAS_KUSER_CMPXCHG) }
|
||||
// Use generic interlock implementation
|
||||
|
||||
var
|
||||
fpc_system_lock: longint;
|
||||
|
||||
{$ifdef FPC_PIC}
|
||||
// Use generic interlock implementation with PIC
|
||||
|
||||
// A helper function to get a pointer to fpc_system_lock in the PIC compatible way.
|
||||
function get_fpc_system_lock_ptr: pointer;
|
||||
begin
|
||||
get_fpc_system_lock_ptr:=@fpc_system_lock;
|
||||
end;
|
||||
|
||||
{$endif FPC_PIC}
|
||||
{$endif}
|
||||
|
||||
function InterLockedDecrement (var Target: longint) : longint; assembler; nostackframe;
|
||||
asm
|
||||
@ -594,7 +640,18 @@ asm
|
||||
|
||||
{$else}
|
||||
// lock
|
||||
ldr r3, .Lfpc_system_lock
|
||||
{$ifdef FPC_PIC}
|
||||
push {r0,lr}
|
||||
{$ifdef CPUARM_HAS_BLX}
|
||||
blx get_fpc_system_lock_ptr
|
||||
{$else}
|
||||
bl get_fpc_system_lock_ptr
|
||||
{$endif CPUARM_HAS_BLX}
|
||||
mov r3,r0
|
||||
pop {r0,lr}
|
||||
{$else FPC_PIC}
|
||||
ldr r3, .Lfpc_system_lock
|
||||
{$endif FPC_PIC}
|
||||
mov r1, #1
|
||||
.Lloop:
|
||||
swp r2, r1, [r3]
|
||||
@ -613,38 +670,15 @@ asm
|
||||
mov pc,lr
|
||||
{$endif}
|
||||
|
||||
{$ifndef FPC_PIC}
|
||||
.Lfpc_system_lock:
|
||||
.long fpc_system_lock
|
||||
{$endif FPC_PIC}
|
||||
|
||||
{$endif}
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
|
||||
{$ifndef darwin}
|
||||
{$define FPC_SYSTEM_HAS_ANSISTR_INCR_REF}
|
||||
|
||||
Procedure fpc_ansistr_incr_ref (S : Pointer); [Public,Alias:'FPC_ANSISTR_INCR_REF'];assembler;nostackframe; compilerproc;
|
||||
asm
|
||||
// Null string?
|
||||
cmp r0, #0
|
||||
// Load reference counter
|
||||
ldrne r1, [r0, #-8]
|
||||
// pointer to counter, calculate here for delay slot utilization
|
||||
subne r0, r0, #8
|
||||
{$ifdef CPUARM_HAS_BX}
|
||||
bxeq lr
|
||||
{$else}
|
||||
moveq pc,lr
|
||||
{$endif}
|
||||
// Check for a constant string
|
||||
cmp r1, #0
|
||||
// Tailcall
|
||||
// Hopefully the linker will place InterLockedIncrement as layed out here
|
||||
bge InterLockedIncrement
|
||||
// Freepascal will generate a proper return here, save some cachespace
|
||||
end;
|
||||
{$endif not darwin}
|
||||
|
||||
function InterLockedIncrement (var Target: longint) : longint; assembler; nostackframe;
|
||||
asm
|
||||
{$ifdef CPUARM_HAS_LDREX}
|
||||
@ -691,7 +725,18 @@ asm
|
||||
|
||||
{$else}
|
||||
// lock
|
||||
ldr r3, .Lfpc_system_lock
|
||||
{$ifdef FPC_PIC}
|
||||
push {r0,lr}
|
||||
{$ifdef CPUARM_HAS_BLX}
|
||||
blx get_fpc_system_lock_ptr
|
||||
{$else}
|
||||
bl get_fpc_system_lock_ptr
|
||||
{$endif CPUARM_HAS_BLX}
|
||||
mov r3,r0
|
||||
pop {r0,lr}
|
||||
{$else FPC_PIC}
|
||||
ldr r3, .Lfpc_system_lock
|
||||
{$endif FPC_PIC}
|
||||
mov r1, #1
|
||||
.Lloop:
|
||||
swp r2, r1, [r3]
|
||||
@ -710,13 +755,15 @@ asm
|
||||
mov pc,lr
|
||||
{$endif}
|
||||
|
||||
{$ifndef FPC_PIC}
|
||||
.Lfpc_system_lock:
|
||||
.long fpc_system_lock
|
||||
{$endif FPC_PIC}
|
||||
|
||||
{$endif}
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
|
||||
function InterLockedExchange (var Target: longint;Source : longint) : longint; assembler; nostackframe;
|
||||
asm
|
||||
{$ifdef CPUARM_HAS_LDREX}
|
||||
@ -763,7 +810,18 @@ asm
|
||||
b .Latomic_add_loop // kuser_cmpxchg failed, loop back
|
||||
{$else}
|
||||
// lock
|
||||
ldr r3, .Lfpc_system_lock
|
||||
{$ifdef FPC_PIC}
|
||||
push {r0,r1,lr}
|
||||
{$ifdef CPUARM_HAS_BLX}
|
||||
blx get_fpc_system_lock_ptr
|
||||
{$else}
|
||||
bl get_fpc_system_lock_ptr
|
||||
{$endif CPUARM_HAS_BLX}
|
||||
mov r3,r0
|
||||
pop {r0,r1,lr}
|
||||
{$else FPC_PIC}
|
||||
ldr r3, .Lfpc_system_lock
|
||||
{$endif FPC_PIC}
|
||||
mov r2, #1
|
||||
.Lloop:
|
||||
swp r2, r2, [r3]
|
||||
@ -782,8 +840,11 @@ asm
|
||||
mov pc,lr
|
||||
{$endif}
|
||||
|
||||
{$ifndef FPC_PIC}
|
||||
.Lfpc_system_lock:
|
||||
.long fpc_system_lock
|
||||
{$endif FPC_PIC}
|
||||
|
||||
{$endif}
|
||||
{$endif}
|
||||
end;
|
||||
@ -839,7 +900,18 @@ asm
|
||||
|
||||
{$else}
|
||||
// lock
|
||||
ldr r3, .Lfpc_system_lock
|
||||
{$ifdef FPC_PIC}
|
||||
push {r0,r1,lr}
|
||||
{$ifdef CPUARM_HAS_BLX}
|
||||
blx get_fpc_system_lock_ptr
|
||||
{$else}
|
||||
bl get_fpc_system_lock_ptr
|
||||
{$endif CPUARM_HAS_BLX}
|
||||
mov r3,r0
|
||||
pop {r0,r1,lr}
|
||||
{$else FPC_PIC}
|
||||
ldr r3, .Lfpc_system_lock
|
||||
{$endif FPC_PIC}
|
||||
mov r2, #1
|
||||
.Lloop:
|
||||
swp r2, r2, [r3]
|
||||
@ -859,8 +931,11 @@ asm
|
||||
mov pc,lr
|
||||
{$endif}
|
||||
|
||||
{$ifndef FPC_PIC}
|
||||
.Lfpc_system_lock:
|
||||
.long fpc_system_lock
|
||||
{$endif FPC_PIC}
|
||||
|
||||
{$endif}
|
||||
{$endif}
|
||||
end;
|
||||
@ -918,7 +993,18 @@ asm
|
||||
|
||||
{$else}
|
||||
// lock
|
||||
ldr r12, .Lfpc_system_lock
|
||||
{$ifdef FPC_PIC}
|
||||
push {r0,r1,r2,lr}
|
||||
{$ifdef CPUARM_HAS_BLX}
|
||||
blx get_fpc_system_lock_ptr
|
||||
{$else}
|
||||
bl get_fpc_system_lock_ptr
|
||||
{$endif CPUARM_HAS_BLX}
|
||||
mov r12,r0
|
||||
pop {r0,r1,r2,lr}
|
||||
{$else FPC_PIC}
|
||||
ldr r12, .Lfpc_system_lock
|
||||
{$endif FPC_PIC}
|
||||
mov r3, #1
|
||||
.Lloop:
|
||||
swp r3, r3, [r12]
|
||||
@ -938,8 +1024,11 @@ asm
|
||||
mov pc,lr
|
||||
{$endif}
|
||||
|
||||
{$ifndef FPC_PIC}
|
||||
.Lfpc_system_lock:
|
||||
.long fpc_system_lock
|
||||
{$endif FPC_PIC}
|
||||
|
||||
{$endif}
|
||||
{$endif}
|
||||
end;
|
||||
@ -956,6 +1045,8 @@ begin
|
||||
InterLockedIncrement(l);
|
||||
end;
|
||||
|
||||
// --- InterLocked functions end
|
||||
|
||||
procedure fpc_cpucodeinit;
|
||||
begin
|
||||
{$ifdef FPC_SYSTEM_FPC_MOVE}
|
||||
|
@ -77,6 +77,10 @@ const calculated_cmdline:Pchar=nil;
|
||||
|
||||
{$I system.inc}
|
||||
|
||||
{$ifdef android}
|
||||
{$I sysandroid.inc}
|
||||
{$endif android}
|
||||
|
||||
{*****************************************************************************
|
||||
Misc. System Dependent Functions
|
||||
*****************************************************************************}
|
||||
|
Loading…
Reference in New Issue
Block a user