浏览代码

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 -

yury 9 年之前
父节点
当前提交
fccd5e534d

+ 1 - 0
.gitattributes

@@ -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

+ 6 - 5
compiler/systems/i_android.pas

@@ -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';

+ 2 - 0
compiler/systems/t_android.pas

@@ -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';

+ 1 - 0
rtl/android/Makefile

@@ -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)

+ 1 - 0
rtl/android/Makefile.fpc

@@ -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 :

+ 30 - 14
rtl/android/arm/dllprt0.as

@@ -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 - 17
rtl/android/arm/prt0.as

@@ -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

+ 26 - 15
rtl/android/i386/dllprt0.as

@@ -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

+ 22 - 13
rtl/android/i386/prt0.as

@@ -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.  */

+ 4 - 6
rtl/android/mipsel/dllprt0.as

@@ -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 - 0
rtl/android/sysandroid.inc

@@ -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;

+ 127 - 36
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,37 +670,14 @@ asm
   mov pc,lr
 {$endif}
 
+{$ifndef FPC_PIC}
 .Lfpc_system_lock:
   .long fpc_system_lock
-{$endif}
-{$endif}
-end;
-
-
-{$ifndef darwin}
-{$define FPC_SYSTEM_HAS_ANSISTR_INCR_REF}
+{$endif FPC_PIC}
 
-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
+{$endif}
 end;
-{$endif not darwin}
 
 function InterLockedIncrement (var Target: longint) : longint; assembler; nostackframe;
 asm
@@ -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}

+ 4 - 0
rtl/linux/system.pp

@@ -77,6 +77,10 @@ const calculated_cmdline:Pchar=nil;
 
 {$I system.inc}
 
+{$ifdef android}
+{$I sysandroid.inc}
+{$endif android}
+
 {*****************************************************************************
                        Misc. System Dependent Functions
 *****************************************************************************}