Browse Source

* merge Linux/AArch64 support

--- Merging r30724 into '.':
U    compiler/aarch64/cgcpu.pas
--- Merging r30846 into '.':
U    compiler/aarch64/cpubase.pas
--- Merging r30847 into '.':
U    compiler/aarch64/a64atts.inc
U    compiler/aarch64/a64att.inc
U    compiler/aarch64/a64tab.inc
U    compiler/aarch64/a64op.inc
U    compiler/utils/mka64ins.pp
--- Recording mergeinfo for merge of r30847 into '.':
 G   .
 --- Merging r30848 into '.':
 U    compiler/utils/Makefile
 U    compiler/utils/Makefile.fpc
 --- Merging r30875 into '.':
 U    rtl/linux/ptypes.inc
 U    rtl/linux/sysosh.inc
 A    rtl/linux/pmutext.inc
 --- Merging r30889 into '.':
 U    packages/fcl-res/src/elfsubwriter.inc
 U    packages/fcl-res/src/elfwriter.pp
 --- Merging r30890 into '.':
 U    packages/fpmkunit/src/fpmkunit.pp
 C    utils/fpcm/revision.inc
 U    utils/fpcm/fpcmmain.pp
 --- Merging r30893 into '.':
 U    compiler/aarch64/agcpugas.pas
 G    compiler/aarch64/cgcpu.pas
 U    compiler/aarch64/cputarg.pas
 U    compiler/utils/ppuutils/ppudump.pp
 U    compiler/systems/i_linux.pas
 U    compiler/systems/t_linux.pas
 U    compiler/systems.inc
 U    compiler/systems.pas
 --- Merging r30894 into '.':
 U    compiler/utils/fpc.pp
 --- Merging r30895 into '.':
 U    rtl/linux/ostypes.inc
 U    rtl/linux/pmutext.inc
 U    rtl/linux/bunxsysc.inc
 A    rtl/linux/aarch64
 A    rtl/linux/aarch64/syscall.inc
 A    rtl/linux/aarch64/dllprt0.as
 A    rtl/linux/aarch64/stat.inc
 A    rtl/linux/aarch64/bsyscall.inc
 A    rtl/linux/aarch64/sighnd.inc
 A    rtl/linux/aarch64/sysnr.inc
 A    rtl/linux/aarch64/prt0.as
 A    rtl/linux/aarch64/cprt0.as
 A    rtl/linux/aarch64/syscallh.inc
 A    rtl/linux/aarch64/sighndh.inc
 A    rtl/linux/aarch64/gprt0.as
 U    rtl/linux/ossysc.inc
 A    rtl/linux/sysnr-gen.inc
 U    rtl/linux/oldlinux.pp
 U    rtl/linux/linux.pp
 U    rtl/linux/termios.inc
 U    rtl/linux/osdefs.inc
 G    rtl/linux/ptypes.inc
 --- Merging r30896 into '.':
 G    packages/fcl-res/src/elfwriter.pp
 U    packages/fcl-res/src/elfdefaulttarget.inc
 C    packages/fcl-res/src/elfconsts.pp
 G    packages/fcl-res/src/elfsubwriter.inc
 U    packages/fcl-res/src/elfreader.pp
 U    utils/fpcres/fpcres.pas
 C    utils/fpcres/target.pas
 --- Merging r30897 into '.':
 U    packages/rtl-extra/src/linux/unixsock.inc
 U    packages/rtl-extra/src/unix/ipc.pp
 --- Merging r30898 into '.':
 U    tests/webtbs/tw11563.pp
 --- Merging r30900 into '.':
 G    compiler/aarch64/cgcpu.pas

git-svn-id: branches/fixes_3_0_ios@30962 -
Jonas Maebe 10 years ago
parent
commit
cd2514b46e
53 changed files with 1926 additions and 214 deletions
  1. 13 0
      .gitattributes
  2. 1 1
      compiler/aarch64/a64att.inc
  3. 1 1
      compiler/aarch64/a64atts.inc
  4. 1 1
      compiler/aarch64/a64op.inc
  5. 1 1
      compiler/aarch64/a64tab.inc
  6. 32 4
      compiler/aarch64/agcpugas.pas
  7. 52 61
      compiler/aarch64/cgcpu.pas
  8. 1 1
      compiler/aarch64/cpubase.pas
  9. 1 1
      compiler/aarch64/cputarg.pas
  10. 3 2
      compiler/systems.inc
  11. 2 3
      compiler/systems.pas
  12. 72 0
      compiler/systems/i_linux.pas
  13. 240 0
      compiler/systems/t_linux.pas
  14. 82 79
      compiler/utils/Makefile
  15. 1 1
      compiler/utils/Makefile.fpc
  16. 7 1
      compiler/utils/fpc.pp
  17. 2 2
      compiler/utils/mka64ins.pp
  18. 3 2
      compiler/utils/ppuutils/ppudump.pp
  19. 3 1
      packages/fcl-res/src/elfconsts.pp
  20. 3 0
      packages/fcl-res/src/elfdefaulttarget.inc
  21. 1 0
      packages/fcl-res/src/elfreader.pp
  22. 2 1
      packages/fcl-res/src/elfsubwriter.inc
  23. 2 1
      packages/fcl-res/src/elfwriter.pp
  24. 2 1
      packages/fpmkunit/src/fpmkunit.pp
  25. 1 1
      packages/rtl-extra/src/linux/unixsock.inc
  26. 1 1
      packages/rtl-extra/src/unix/ipc.pp
  27. 1 0
      rtl/linux/aarch64/bsyscall.inc
  28. 91 0
      rtl/linux/aarch64/cprt0.as
  29. 72 0
      rtl/linux/aarch64/dllprt0.as
  30. 10 0
      rtl/linux/aarch64/gprt0.as
  31. 77 0
      rtl/linux/aarch64/prt0.as
  32. 44 0
      rtl/linux/aarch64/sighnd.inc
  33. 47 0
      rtl/linux/aarch64/sighndh.inc
  34. 72 0
      rtl/linux/aarch64/stat.inc
  35. 127 0
      rtl/linux/aarch64/syscall.inc
  36. 35 0
      rtl/linux/aarch64/syscallh.inc
  37. 1 0
      rtl/linux/aarch64/sysnr.inc
  38. 73 3
      rtl/linux/bunxsysc.inc
  39. 15 0
      rtl/linux/linux.pp
  40. 30 0
      rtl/linux/oldlinux.pp
  41. 4 0
      rtl/linux/osdefs.inc
  42. 55 5
      rtl/linux/ossysc.inc
  43. 6 1
      rtl/linux/ostypes.inc
  44. 58 0
      rtl/linux/pmutext.inc
  45. 18 23
      rtl/linux/ptypes.inc
  46. 277 0
      rtl/linux/sysnr-gen.inc
  47. 5 11
      rtl/linux/sysosh.inc
  48. 265 0
      rtl/linux/termios.inc
  49. 8 0
      tests/webtbs/tw11563.pp
  50. 1 1
      utils/fpcm/fpcmmain.pp
  51. 1 1
      utils/fpcm/revision.inc
  52. 1 0
      utils/fpcres/fpcres.pas
  53. 2 2
      utils/fpcres/target.pas

+ 13 - 0
.gitattributes

@@ -8491,6 +8491,17 @@ rtl/jvm/setjump.inc svneol=native#text/plain
 rtl/jvm/setjumph.inc svneol=native#text/plain
 rtl/jvm/setjumph.inc svneol=native#text/plain
 rtl/linux/Makefile svneol=native#text/plain
 rtl/linux/Makefile svneol=native#text/plain
 rtl/linux/Makefile.fpc svneol=native#text/plain
 rtl/linux/Makefile.fpc svneol=native#text/plain
+rtl/linux/aarch64/bsyscall.inc svneol=native#text/plain
+rtl/linux/aarch64/cprt0.as svneol=native#text/plain
+rtl/linux/aarch64/dllprt0.as svneol=native#text/plain
+rtl/linux/aarch64/gprt0.as svneol=native#text/plain
+rtl/linux/aarch64/prt0.as svneol=native#text/plain
+rtl/linux/aarch64/sighnd.inc svneol=native#text/plain
+rtl/linux/aarch64/sighndh.inc svneol=native#text/plain
+rtl/linux/aarch64/stat.inc svneol=native#text/plain
+rtl/linux/aarch64/syscall.inc svneol=native#text/plain
+rtl/linux/aarch64/syscallh.inc svneol=native#text/plain
+rtl/linux/aarch64/sysnr.inc svneol=native#text/plain
 rtl/linux/arm/bsyscall.inc svneol=native#text/plain
 rtl/linux/arm/bsyscall.inc svneol=native#text/plain
 rtl/linux/arm/cprt0.as svneol=native#text/plain
 rtl/linux/arm/cprt0.as svneol=native#text/plain
 rtl/linux/arm/dllprt0.as svneol=native#text/plain
 rtl/linux/arm/dllprt0.as svneol=native#text/plain
@@ -8575,6 +8586,7 @@ rtl/linux/osdefs.inc svneol=native#text/plain
 rtl/linux/osmacro.inc svneol=native#text/plain
 rtl/linux/osmacro.inc svneol=native#text/plain
 rtl/linux/ossysc.inc svneol=native#text/plain
 rtl/linux/ossysc.inc svneol=native#text/plain
 rtl/linux/ostypes.inc svneol=native#text/plain
 rtl/linux/ostypes.inc svneol=native#text/plain
+rtl/linux/pmutext.inc svneol=native#text/plain
 rtl/linux/powerpc/bsyscall.inc svneol=native#text/plain
 rtl/linux/powerpc/bsyscall.inc svneol=native#text/plain
 rtl/linux/powerpc/cprt0.as svneol=native#text/plain
 rtl/linux/powerpc/cprt0.as svneol=native#text/plain
 rtl/linux/powerpc/dllprt0.as svneol=native#text/plain
 rtl/linux/powerpc/dllprt0.as svneol=native#text/plain
@@ -8621,6 +8633,7 @@ rtl/linux/sparc/syscall.inc svneol=native#text/plain
 rtl/linux/sparc/syscallh.inc svneol=native#text/plain
 rtl/linux/sparc/syscallh.inc svneol=native#text/plain
 rtl/linux/sparc/sysnr.inc svneol=native#text/plain
 rtl/linux/sparc/sysnr.inc svneol=native#text/plain
 rtl/linux/suuid.inc svneol=native#text/plain
 rtl/linux/suuid.inc svneol=native#text/plain
+rtl/linux/sysnr-gen.inc svneol=native#text/plain
 rtl/linux/sysos.inc svneol=native#text/plain
 rtl/linux/sysos.inc svneol=native#text/plain
 rtl/linux/sysosh.inc svneol=native#text/plain
 rtl/linux/sysosh.inc svneol=native#text/plain
 rtl/linux/system.pp svneol=native#text/plain
 rtl/linux/system.pp svneol=native#text/plain

+ 1 - 1
compiler/aarch64/a64att.inc

@@ -1,4 +1,4 @@
-{ don't edit, this file is generated from armins.dat }
+{ don't edit, this file is generated from a64ins.dat }
 (
 (
 'none',
 'none',
 'b',
 'b',

+ 1 - 1
compiler/aarch64/a64atts.inc

@@ -1,4 +1,4 @@
-{ don't edit, this file is generated from armins.dat }
+{ don't edit, this file is generated from a64ins.dat }
 (
 (
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,

+ 1 - 1
compiler/aarch64/a64op.inc

@@ -1,4 +1,4 @@
-{ don't edit, this file is generated from armins.dat }
+{ don't edit, this file is generated from a64ins.dat }
 (
 (
 A_NONE,
 A_NONE,
 A_B,
 A_B,

+ 1 - 1
compiler/aarch64/a64tab.inc

@@ -1,4 +1,4 @@
-{ don't edit, this file is generated from armins.dat }
+{ don't edit, this file is generated from a64ins.dat }
 (
 (
 
 
 );
 );

+ 32 - 4
compiler/aarch64/agcpugas.pas

@@ -39,6 +39,10 @@ unit agcpugas;
         procedure WriteInstruction(hp : tai);override;
         procedure WriteInstruction(hp : tai);override;
       end;
       end;
 
 
+      TAArch64Assembler=class(TGNUassembler)
+        constructor create(smart: boolean); override;
+      end;
+
       TAArch64AppleAssembler=class(TAppleGNUassembler)
       TAArch64AppleAssembler=class(TAppleGNUassembler)
         constructor create(smart: boolean); override;
         constructor create(smart: boolean); override;
         function MakeCmdLine: TCmdStr; override;
         function MakeCmdLine: TCmdStr; override;
@@ -68,6 +72,16 @@ unit agcpugas;
        cgbase,cgutils;
        cgbase,cgutils;
 
 
 
 
+{****************************************************************************}
+{                      AArch64 Assembler writer                              }
+{****************************************************************************}
+
+    constructor TAArch64Assembler.create(smart: boolean);
+      begin
+        inherited create(smart);
+        InstrWriter := TAArch64InstrWriter.create(self);
+      end;
+
 {****************************************************************************}
 {****************************************************************************}
 {                      Apple AArch64 Assembler writer                        }
 {                      Apple AArch64 Assembler writer                        }
 {****************************************************************************}
 {****************************************************************************}
@@ -99,6 +113,8 @@ unit agcpugas;
       const
       const
         darwin_addrpage2str: array[addr_page..addr_gotpageoffset] of string[11] =
         darwin_addrpage2str: array[addr_page..addr_gotpageoffset] of string[11] =
            ('@PAGE','@PAGEOFF','@GOTPAGE','@GOTPAGEOFF');
            ('@PAGE','@PAGEOFF','@GOTPAGE','@GOTPAGEOFF');
+        linux_addrpage2str: array[addr_page..addr_gotpageoffset] of string[10] =
+           ('',':lo12:',':got:',':got_lo12:');
       begin
       begin
         if ref.base=NR_NO then
         if ref.base=NR_NO then
           begin
           begin
@@ -117,8 +133,7 @@ unit agcpugas;
                   if target_asm.id=as_darwin then
                   if target_asm.id=as_darwin then
                     result:=ref.symbol.name+darwin_addrpage2str[ref.refaddr]
                     result:=ref.symbol.name+darwin_addrpage2str[ref.refaddr]
                   else
                   else
-                    { todo }
-                    internalerror(2014121502);
+                    result:=linux_addrpage2str[ref.refaddr]+ref.symbol.name
                 end
                 end
               else
               else
                 internalerror(2015022301);
                 internalerror(2015022301);
@@ -160,8 +175,7 @@ unit agcpugas;
                           if target_asm.id=as_darwin then
                           if target_asm.id=as_darwin then
                             result:=result+', '+ref.symbol.name+darwin_addrpage2str[ref.refaddr]
                             result:=result+', '+ref.symbol.name+darwin_addrpage2str[ref.refaddr]
                           else
                           else
-                            { todo }
-                            internalerror(2014122510);
+                            result:=result+', '+linux_addrpage2str[ref.refaddr]+ref.symbol.name
                         end
                         end
                       else
                       else
                         { todo: not yet generated/don't know syntax }
                         { todo: not yet generated/don't know syntax }
@@ -269,6 +283,19 @@ unit agcpugas;
 
 
 
 
     const
     const
+       as_aarch64_gas_info : tasminfo =
+          (
+            id     : as_gas;
+            idtxt  : 'AS';
+            asmbin : 'as';
+            asmcmd : '-o $OBJ $EXTRAOPT $ASM';
+            supported_targets : [system_aarch64_linux];
+            flags : [af_needar,af_smartlink_sections];
+            labelprefix : '.L';
+            comment : '// ';
+            dollarsign: '$';
+          );
+
        as_aarch64_gas_darwin_info : tasminfo =
        as_aarch64_gas_darwin_info : tasminfo =
           (
           (
             id     : as_darwin;
             id     : as_darwin;
@@ -284,5 +311,6 @@ unit agcpugas;
 
 
 
 
 begin
 begin
+  RegisterAssembler(as_aarch64_gas_info,TAArch64Assembler);
   RegisterAssembler(as_aarch64_gas_darwin_info,TAArch64AppleAssembler);
   RegisterAssembler(as_aarch64_gas_darwin_info,TAArch64AppleAssembler);
 end.
 end.

+ 52 - 61
compiler/aarch64/cgcpu.pas

@@ -166,66 +166,59 @@ implementation
             { no relative symbol support (needed) yet }
             { no relative symbol support (needed) yet }
             if assigned(ref.relsymbol) then
             if assigned(ref.relsymbol) then
               internalerror(2014111001);
               internalerror(2014111001);
-            { on Darwin: load the address from the GOT. There does not appear to
-              be a non-GOT variant. This consists of first loading the address
-              of the page containing the GOT entry for this variable, and then
-              the address of the entry itself from that page (can be relaxed by
-              the linker in case the variable itself can be stored directly in
-              the GOT) }
-            if target_info.system in systems_darwin then
+            { loading a symbol address (whether it's in the GOT or not) consists
+              of two parts: first load the page on which it is located, then
+              either the offset in the page or load the value at that offset in
+              the page. This final GOT-load can be relaxed by the linker in case
+              the variable itself can be stored directly in the GOT }
+            if (preferred_newbasereg=NR_NO) or
+               (ref.base=preferred_newbasereg) or
+               (ref.index=preferred_newbasereg) then
+              preferred_newbasereg:=getaddressregister(list);
+            { load the (GOT) page }
+            reference_reset_symbol(href,ref.symbol,0,8);
+            if ((ref.symbol.typ in [AT_FUNCTION,AT_LABEL]) and
+                (ref.symbol.bind in [AB_LOCAL,AB_GLOBAL])) or
+               ((ref.symbol.typ=AT_DATA) and
+                (ref.symbol.bind=AB_LOCAL)) then
+              href.refaddr:=addr_page
+            else
+              href.refaddr:=addr_gotpage;
+            list.concat(taicpu.op_reg_ref(A_ADRP,preferred_newbasereg,href));
+            { load the GOT entry (= address of the variable) }
+            reference_reset_base(href,preferred_newbasereg,0,sizeof(pint));
+            href.symbol:=ref.symbol;
+            { code symbols defined in the current compilation unit do not
+              have to be accessed via the GOT }
+            if ((ref.symbol.typ in [AT_FUNCTION,AT_LABEL]) and
+                (ref.symbol.bind in [AB_LOCAL,AB_GLOBAL])) or
+               ((ref.symbol.typ=AT_DATA) and
+                (ref.symbol.bind=AB_LOCAL)) then
               begin
               begin
-                if (preferred_newbasereg=NR_NO) or
-                   (ref.base=preferred_newbasereg) or
-                   (ref.index=preferred_newbasereg) then
-                  preferred_newbasereg:=getaddressregister(list);
-                { load the (GOT) page }
-                reference_reset_symbol(href,ref.symbol,0,8);
-                if ((ref.symbol.typ in [AT_FUNCTION,AT_LABEL]) and
-                    (ref.symbol.bind in [AB_LOCAL,AB_GLOBAL])) or
-                   ((ref.symbol.typ=AT_DATA) and
-                    (ref.symbol.bind=AB_LOCAL)) then
-                  href.refaddr:=addr_page
-                else
-                  href.refaddr:=addr_gotpage;
-                list.concat(taicpu.op_reg_ref(A_ADRP,preferred_newbasereg,href));
-                { load the GOT entry (= address of the variable) }
-                reference_reset_base(href,preferred_newbasereg,0,sizeof(pint));
-                href.symbol:=ref.symbol;
-                { code symbols defined in the current compilation unit do not
-                  have to be accessed via the GOT }
-                if ((ref.symbol.typ in [AT_FUNCTION,AT_LABEL]) and
-                    (ref.symbol.bind in [AB_LOCAL,AB_GLOBAL])) or
-                   ((ref.symbol.typ=AT_DATA) and
-                    (ref.symbol.bind=AB_LOCAL)) then
-                  begin
-                    href.base:=NR_NO;
-                    href.refaddr:=addr_pageoffset;
-                    list.concat(taicpu.op_reg_reg_ref(A_ADD,preferred_newbasereg,preferred_newbasereg,href));
-                  end
-                else
-                  begin
-                    href.refaddr:=addr_gotpageoffset;
-                    { use a_load_ref_reg() rather than directly encoding the LDR,
-                      so that we'll check the validity of the reference }
-                    a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,preferred_newbasereg);
-                  end;
-                { set as new base register }
-                if ref.base=NR_NO then
-                  ref.base:=preferred_newbasereg
-                else if ref.index=NR_NO then
-                  ref.index:=preferred_newbasereg
-                else
-                  begin
-                    { make sure it's valid in case ref.base is SP -> make it
-                      the second operand}
-                    a_op_reg_reg_reg(list,OP_ADD,OS_ADDR,preferred_newbasereg,ref.base,preferred_newbasereg);
-                    ref.base:=preferred_newbasereg
-                  end;
-                ref.symbol:=nil;
+                href.base:=NR_NO;
+                href.refaddr:=addr_pageoffset;
+                list.concat(taicpu.op_reg_reg_ref(A_ADD,preferred_newbasereg,preferred_newbasereg,href));
               end
               end
             else
             else
-              { todo }
-              internalerror(2014111003);
+              begin
+                href.refaddr:=addr_gotpageoffset;
+                { use a_load_ref_reg() rather than directly encoding the LDR,
+                  so that we'll check the validity of the reference }
+                a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,preferred_newbasereg);
+              end;
+            { set as new base register }
+            if ref.base=NR_NO then
+              ref.base:=preferred_newbasereg
+            else if ref.index=NR_NO then
+              ref.index:=preferred_newbasereg
+            else
+              begin
+                { make sure it's valid in case ref.base is SP -> make it
+                  the second operand}
+                a_op_reg_reg_reg(list,OP_ADD,OS_ADDR,preferred_newbasereg,ref.base,preferred_newbasereg);
+                ref.base:=preferred_newbasereg
+              end;
+            ref.symbol:=nil;
           end;
           end;
 
 
         { base & index }
         { base & index }
@@ -1111,7 +1104,7 @@ implementation
         list.Concat(taicpu.op_reg_reg_reg_cond(A_CSINV,dst,dst,makeregsize(NR_XZR,dstsize),C_NE));
         list.Concat(taicpu.op_reg_reg_reg_cond(A_CSINV,dst,dst,makeregsize(NR_XZR,dstsize),C_NE));
         { mask the -1 to 255 if src was 0 (anyone find a two-instruction
         { mask the -1 to 255 if src was 0 (anyone find a two-instruction
           branch-free version? All of mine are 3...) }
           branch-free version? All of mine are 3...) }
-        list.Concat(setoppostfix(taicpu.op_reg_reg(A_UXT,dst,dst),PF_B));
+        list.Concat(setoppostfix(taicpu.op_reg_reg(A_UXT,makeregsize(dst,OS_32),makeregsize(dst,OS_32)),PF_B));
       end;
       end;
 
 
 
 
@@ -1632,9 +1625,7 @@ implementation
 
 
     procedure tcgaarch64.g_maybe_got_init(list : TAsmList);
     procedure tcgaarch64.g_maybe_got_init(list : TAsmList);
       begin
       begin
-        { nothing to do on Darwin; check on ELF targets }
-        if not(target_info.system in systems_darwin) then
-          internalerror(2014112601);
+        { nothing to do on Darwin or Linux }
       end;
       end;
 
 
 
 

+ 1 - 1
compiler/aarch64/cpubase.pas

@@ -429,7 +429,7 @@ unit cpubase;
 
 
     function is_calljmp(o:tasmop):boolean;{$ifdef USEINLINE}inline;{$endif USEINLINE}
     function is_calljmp(o:tasmop):boolean;{$ifdef USEINLINE}inline;{$endif USEINLINE}
       begin
       begin
-        is_calljmp:=o in [A_B,A_BL,A_BLR,A_RET,A_CBNZ,A_CBZ];
+        is_calljmp:=o in [A_B,A_BL,A_BLR,A_RET,A_CBNZ,A_CBZ,A_TBNZ,A_TBZ];
       end;
       end;
 
 
 
 

+ 1 - 1
compiler/aarch64/cputarg.pas

@@ -36,7 +36,7 @@ implementation
 **************************************}
 **************************************}
 
 
     {$ifndef NOTARGETLINUX}
     {$ifndef NOTARGETLINUX}
-//      ,t_linux
+      ,t_linux
     {$endif}
     {$endif}
     {$ifndef NOTARGETBSD}
     {$ifndef NOTARGETBSD}
       ,t_bsd
       ,t_bsd

+ 3 - 2
compiler/systems.inc

@@ -167,8 +167,9 @@
              system_i386_aros,          { 83 }
              system_i386_aros,          { 83 }
              system_x86_64_aros,        { 84 }
              system_x86_64_aros,        { 84 }
              system_x86_64_dragonfly,   { 85 }
              system_x86_64_dragonfly,   { 85 }
-             system_aarch64_darwin,     { 85 }
-             system_x86_64_iphonesim    { 86 }
+             system_aarch64_darwin,     { 86 }
+             system_x86_64_iphonesim,   { 87 }
+             system_aarch64_linux       { 88 }
        );
        );
 
 
      type
      type

+ 2 - 3
compiler/systems.pas

@@ -216,7 +216,7 @@ interface
        systems_android = [system_arm_android, system_i386_android, system_mipsel_android];
        systems_android = [system_arm_android, system_i386_android, system_mipsel_android];
        systems_linux = [system_i386_linux,system_x86_64_linux,system_powerpc_linux,system_powerpc64_linux,
        systems_linux = [system_i386_linux,system_x86_64_linux,system_powerpc_linux,system_powerpc64_linux,
                        system_arm_linux,system_sparc_linux,system_alpha_linux,system_m68k_linux,
                        system_arm_linux,system_sparc_linux,system_alpha_linux,system_m68k_linux,
-                       system_x86_6432_linux,system_mipseb_linux,system_mipsel_linux];
+                       system_x86_6432_linux,system_mipseb_linux,system_mipsel_linux,system_aarch64_linux];
        systems_dragonfly = [system_x86_64_dragonfly];
        systems_dragonfly = [system_x86_64_dragonfly];
        systems_freebsd = [system_i386_freebsd,
        systems_freebsd = [system_i386_freebsd,
                           system_x86_64_freebsd];
                           system_x86_64_freebsd];
@@ -940,8 +940,7 @@ begin
       default_target(system_aarch64_darwin);
       default_target(system_aarch64_darwin);
     {$endif darwin}
     {$endif darwin}
     {$ifndef default_target_set}
     {$ifndef default_target_set}
-      { change to Linux once aarch64 Linux support has been implemented }
-      default_target(system_aarch64_darwin);
+      default_target(system_aarch64_linux);
       {$define default_target_set}
       {$define default_target_set}
     {$endif}
     {$endif}
   {$endif cpuaarch64}
   {$endif cpuaarch64}

+ 72 - 0
compiler/systems/i_linux.pas

@@ -811,6 +811,73 @@ unit i_linux;
 {$endif FPC_ARMEL}
 {$endif FPC_ARMEL}
 {$endif FPC_ARMHF}
 {$endif FPC_ARMHF}
 
 
+       system_aarch64_linux_info  : tsysteminfo =
+          (
+            system       : system_aarch64_linux;
+            name         : 'Linux for AArch64';
+            shortname    : 'Linux';
+            flags        : [tf_needs_symbol_size,
+                            tf_needs_symbol_type,
+                            tf_files_case_sensitive,
+                            tf_requires_proper_alignment,
+                            tf_smartlink_sections,tf_pic_uses_got,
+                            tf_has_winlike_resources];
+            cpu          : cpu_aarch64;
+            unit_env     : 'LINUXUNITS';
+            extradefines : 'UNIX;HASUNIX';
+            exeext       : '';
+            defext       : '.def';
+            scriptext    : '.sh';
+            smartext     : '.sl';
+            unitext      : '.ppu';
+            unitlibext   : '.ppl';
+            asmext       : '.s';
+            objext       : '.o';
+            resext       : '.res';
+            resobjext    : '.or';
+            sharedlibext : '.so';
+            staticlibext : '.a';
+            staticlibprefix : 'libp';
+            sharedlibprefix : 'lib';
+            sharedClibext : '.so';
+            staticClibext : '.a';
+            staticClibprefix : 'lib';
+            sharedClibprefix : 'lib';
+            importlibprefix : 'libimp';
+            importlibext : '.a';
+            Cprefix      : '';
+            newline      : #10;
+            dirsep       : '/';
+            assem        : as_gas;
+            assemextern  : as_gas;
+            link         : ld_none;
+            linkextern   : ld_linux;
+            ar           : ar_gnu_ar;
+            res          : res_elf;
+            dbg          : dbg_dwarf2;
+            script       : script_unix;
+            endian       : endian_little;
+            alignment    :
+              (
+                procalign       : 8;
+                loopalign       : 4;
+                jumpalign       : 0;
+                constalignmin   : 0;
+                constalignmax   : 8;
+                varalignmin     : 0;
+                varalignmax     : 16;
+                localalignmin   : 4;
+                localalignmax   : 16;
+                recordalignmin  : 0;
+                recordalignmax  : 16;
+                maxCrecordalign : 16
+              );
+            first_parm_offset : 16;
+            stacksize    : 8*1024*1024;
+            stackalign   : 16;
+            abi : abi_default;
+          );
+
        system_mipseb_linux_info : tsysteminfo =
        system_mipseb_linux_info : tsysteminfo =
           (
           (
             system       : system_mipseb_LINUX;
             system       : system_mipseb_LINUX;
@@ -987,6 +1054,11 @@ initialization
     set_source_info(system_arm_linux_info);
     set_source_info(system_arm_linux_info);
   {$endif linux}
   {$endif linux}
 {$endif CPUARM}
 {$endif CPUARM}
+{$ifdef cpuaarch64}
+  {$ifdef linux}
+    set_source_info(system_aarch64_linux_info);
+  {$endif linux}
+{$endif cpuaarch64}
 {$ifdef CPUMIPSEB}
 {$ifdef CPUMIPSEB}
   {$ifdef linux}
   {$ifdef linux}
     set_source_info(system_mipseb_linux_info);
     set_source_info(system_mipseb_linux_info);

+ 240 - 0
compiler/systems/t_linux.pas

@@ -187,6 +187,10 @@ end;
 {$endif FPC_ARMHF}
 {$endif FPC_ARMHF}
 {$endif arm}
 {$endif arm}
 
 
+{$ifdef aarch64}
+const defdynlinker='/lib/ld-linux-aarch64.so.1';
+{$endif aarch64}
+
 {$ifdef mips}
 {$ifdef mips}
   const defdynlinker='/lib/ld.so.1';
   const defdynlinker='/lib/ld.so.1';
 {$endif mips}
 {$endif mips}
@@ -277,6 +281,7 @@ const
 {$ifdef POWERPC64} platform_select='-b elf64-powerpc -m elf64ppc';{$endif}
 {$ifdef POWERPC64} platform_select='-b elf64-powerpc -m elf64ppc';{$endif}
 {$ifdef sparc}     platform_select='-b elf32-sparc -m elf32_sparc';{$endif}
 {$ifdef sparc}     platform_select='-b elf32-sparc -m elf32_sparc';{$endif}
 {$ifdef arm}       platform_select='';{$endif} {unknown :( }
 {$ifdef arm}       platform_select='';{$endif} {unknown :( }
+{$ifdef aarch64}   platform_select='';{$endif} {unknown :( }
 {$ifdef m68k}      platform_select='';{$endif} {unknown :( }
 {$ifdef m68k}      platform_select='';{$endif} {unknown :( }
 {$ifdef mips}
 {$ifdef mips}
   {$ifdef mipsel}  
   {$ifdef mipsel}  
@@ -701,6 +706,236 @@ begin
       add('}');
       add('}');
 {$endif x86_64}
 {$endif x86_64}
 
 
+{$ifdef AArch64}
+{$define LINKERSCRIPT_INCLUDED}
+      if isdll or (sysrootpath='') then begin
+        { On other architectures, supplying a complete linker script
+          without the -T option just results in:
+            warning: link.res contains output sections; did you forget -T?
+          However, with a recent aarch64 linker the result is:
+            /usr/bin/ld: internal error ../../ld/ldlang.c 5221
+          So in these cases, where -T will not be used, we supply a
+          minimal linker script with just the FPC-specific part: }
+        add('SECTIONS');
+        add('{');
+        add('  .data           :');
+        add('  {');
+        { extra by FPC }
+        add('    KEEP (*(.fpc .fpc.n_version .fpc.n_links))');
+        add('  }');
+        add('}');
+      end else begin
+        { Complete linker script for aarch64-linux: }
+        add('SECTIONS');
+        add('{');
+        add('  /* Read-only sections, merged into text segment: */');
+        add('  PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;');
+        add('  .interp         : { *(.interp) }');
+        add('  .note.gnu.build-id : { *(.note.gnu.build-id) }');
+        add('  .hash           : { *(.hash) }');
+        add('  .gnu.hash       : { *(.gnu.hash) }');
+        add('  .dynsym         : { *(.dynsym) }');
+        add('  .dynstr         : { *(.dynstr) }');
+        add('  .gnu.version    : { *(.gnu.version) }');
+        add('  .gnu.version_d  : { *(.gnu.version_d) }');
+        add('  .gnu.version_r  : { *(.gnu.version_r) }');
+        add('  .rela.dyn       :');
+        add('    {');
+        add('      *(.rela.init)');
+        add('      *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)');
+        add('      *(.rela.fini)');
+        add('      *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)');
+        add('      *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)');
+        add('      *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)');
+        add('      *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)');
+        add('      *(.rela.ctors)');
+        add('      *(.rela.dtors)');
+        add('      *(.rela.got)');
+        add('      *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)');
+        add('      *(.rela.ifunc)');
+        add('    }');
+        add('  .rela.plt       :');
+        add('    {');
+        add('      *(.rela.plt)');
+        add('      PROVIDE_HIDDEN (__rela_iplt_start = .);');
+        add('      *(.rela.iplt)');
+        add('      PROVIDE_HIDDEN (__rela_iplt_end = .);');
+        add('    }');
+        add('  .init           :');
+        add('  {');
+        add('    KEEP (*(SORT_NONE(.init)))');
+        add('  } =0');
+        add('  .plt            : ALIGN(16) { *(.plt) *(.iplt) }');
+        add('  .text           :');
+        add('  {');
+        add('    *(.text.unlikely .text.*_unlikely .text.unlikely.*)');
+        add('    *(.text.exit .text.exit.*)');
+        add('    *(.text.startup .text.startup.*)');
+        add('    *(.text.hot .text.hot.*)');
+        add('    *(.text .stub .text.* .gnu.linkonce.t.*)');
+        add('    /* .gnu.warning sections are handled specially by elf32.em.  */');
+        add('    *(.gnu.warning)');
+        add('  } =0');
+        add('  .fini           :');
+        add('  {');
+        add('    KEEP (*(SORT_NONE(.fini)))');
+        add('  } =0');
+        add('  PROVIDE (__etext = .);');
+        add('  PROVIDE (_etext = .);');
+        add('  PROVIDE (etext = .);');
+        add('  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }');
+        add('  .rodata1        : { *(.rodata1) }');
+        add('  .eh_frame_hdr : { *(.eh_frame_hdr) }');
+        add('  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) }');
+        add('  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table');
+        add('  .gcc_except_table.*) }');
+        add('  /* These sections are generated by the Sun/Oracle C++ compiler.  */');
+        add('  .exception_ranges   : ONLY_IF_RO { *(.exception_ranges');
+        add('  .exception_ranges*) }');
+        add('  /* Adjust the address for the data segment.  We want to adjust up to');
+        add('     the same address within the page on the next page up.  */');
+        add('  . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));');
+        add('  /* Exception handling  */');
+        add('  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) }');
+        add('  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }');
+        add('  .exception_ranges   : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }');
+        add('  /* Thread Local Storage sections  */');
+        add('  .tdata          : { *(.tdata .tdata.* .gnu.linkonce.td.*) }');
+        add('  .tbss           : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }');
+        add('  .preinit_array     :');
+        add('  {');
+        add('    PROVIDE_HIDDEN (__preinit_array_start = .);');
+        add('    KEEP (*(.preinit_array))');
+        add('    PROVIDE_HIDDEN (__preinit_array_end = .);');
+        add('  }');
+        add('  .init_array     :');
+        add('  {');
+        add('    PROVIDE_HIDDEN (__init_array_start = .);');
+        add('    KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))');
+        add('    KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))');
+        add('    PROVIDE_HIDDEN (__init_array_end = .);');
+        add('  }');
+        add('  .fini_array     :');
+        add('  {');
+        add('    PROVIDE_HIDDEN (__fini_array_start = .);');
+        add('    KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))');
+        add('    KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))');
+        add('    PROVIDE_HIDDEN (__fini_array_end = .);');
+        add('  }');
+        add('  .ctors          :');
+        add('  {');
+        add('    /* gcc uses crtbegin.o to find the start of');
+        add('       the constructors, so we make sure it is');
+        add('       first.  Because this is a wildcard, it');
+        add('       doesn''t matter if the user does not');
+        add('       actually link against crtbegin.o; the');
+        add('       linker won''t look for a file to match a');
+        add('       wildcard.  The wildcard also means that it');
+        add('       doesn''t matter which directory crtbegin.o');
+        add('       is in.  */');
+        add('    KEEP (*crtbegin.o(.ctors))');
+        add('    KEEP (*crtbegin?.o(.ctors))');
+        add('    /* We don''t want to include the .ctor section from');
+        add('       the crtend.o file until after the sorted ctors.');
+        add('       The .ctor section from the crtend file contains the');
+        add('       end of ctors marker and it must be last */');
+        add('    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))');
+        add('    KEEP (*(SORT(.ctors.*)))');
+        add('    KEEP (*(.ctors))');
+        add('  }');
+        add('  .dtors          :');
+        add('  {');
+        add('    KEEP (*crtbegin.o(.dtors))');
+        add('    KEEP (*crtbegin?.o(.dtors))');
+        add('    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))');
+        add('    KEEP (*(SORT(.dtors.*)))');
+        add('    KEEP (*(.dtors))');
+        add('  }');
+        add('  .jcr            : { KEEP (*(.jcr)) }');
+        add('  .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }');
+        add('  .dynamic        : { *(.dynamic) }');
+        add('  .got            : { *(.got) *(.igot) }');
+        add('  . = DATA_SEGMENT_RELRO_END (24, .);');
+        add('  .got.plt        : { *(.got.plt)  *(.igot.plt) }');
+        add('  .data           :');
+        add('  {');
+        add('    PROVIDE (__data_start = .);');
+
+        { extra by FPC }
+        add('    KEEP (*(.fpc .fpc.n_version .fpc.n_links))');
+
+        add('    *(.data .data.* .gnu.linkonce.d.*)');
+        add('    SORT(CONSTRUCTORS)');
+        add('  }');
+        add('  .data1          : { *(.data1) }');
+        add('  _edata = .; PROVIDE (edata = .);');
+        add('  . = .;');
+        add('  __bss_start = .;');
+        add('  __bss_start__ = .;');
+        add('  .bss            :');
+        add('  {');
+        add('   *(.dynbss)');
+        add('   *(.bss .bss.* .gnu.linkonce.b.*)');
+        add('   *(COMMON)');
+        add('   /* Align here to ensure that the .bss section occupies space up to');
+        add('      _end.  Align after .bss to ensure correct alignment even if the');
+        add('      .bss section disappears because there are no input sections.');
+        add('      FIXME: Why do we need it? When there is no .bss section, we don''t');
+        add('      pad the .data section.  */');
+        add('   . = ALIGN(. != 0 ? 64 / 8 : 1);');
+        add('  }');
+        add('  _bss_end__ = . ; __bss_end__ = . ;');
+        add('  . = ALIGN(64 / 8);');
+        add('  . = SEGMENT_START("ldata-segment", .);');
+        add('  . = ALIGN(64 / 8);');
+        add('  __end__ = . ;');
+        add('  _end = .; PROVIDE (end = .);');
+        add('  . = DATA_SEGMENT_END (.);');
+        add('  /* Stabs debugging sections.  */');
+        add('  .stab          0 : { *(.stab) }');
+        add('  .stabstr       0 : { *(.stabstr) }');
+        add('  .stab.excl     0 : { *(.stab.excl) }');
+        add('  .stab.exclstr  0 : { *(.stab.exclstr) }');
+        add('  .stab.index    0 : { *(.stab.index) }');
+        add('  .stab.indexstr 0 : { *(.stab.indexstr) }');
+        add('  .comment       0 : { *(.comment) }');
+        add('  /* DWARF debug sections.');
+        add('     Symbols in the DWARF debugging sections are relative to the beginning');
+        add('     of the section so we begin them at 0.  */');
+        add('  /* DWARF 1 */');
+        add('  .debug          0 : { *(.debug) }');
+        add('  .line           0 : { *(.line) }');
+        add('  /* GNU DWARF 1 extensions */');
+        add('  .debug_srcinfo  0 : { *(.debug_srcinfo) }');
+        add('  .debug_sfnames  0 : { *(.debug_sfnames) }');
+        add('  /* DWARF 1.1 and DWARF 2 */');
+        add('  .debug_aranges  0 : { *(.debug_aranges) }');
+        add('  .debug_pubnames 0 : { *(.debug_pubnames) }');
+        add('  /* DWARF 2 */');
+        add('  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }');
+        add('  .debug_abbrev   0 : { *(.debug_abbrev) }');
+        add('  .debug_line     0 : { *(.debug_line .debug_line.* .debug_line_end ) }');
+        add('  .debug_frame    0 : { *(.debug_frame) }');
+        add('  .debug_str      0 : { *(.debug_str) }');
+        add('  .debug_loc      0 : { *(.debug_loc) }');
+        add('  .debug_macinfo  0 : { *(.debug_macinfo) }');
+        add('  /* SGI/MIPS DWARF 2 extensions */');
+        add('  .debug_weaknames 0 : { *(.debug_weaknames) }');
+        add('  .debug_funcnames 0 : { *(.debug_funcnames) }');
+        add('  .debug_typenames 0 : { *(.debug_typenames) }');
+        add('  .debug_varnames  0 : { *(.debug_varnames) }');
+        add('  /* DWARF 3 */');
+        add('  .debug_pubtypes 0 : { *(.debug_pubtypes) }');
+        add('  .debug_ranges   0 : { *(.debug_ranges) }');
+        add('  /* DWARF Extension.  */');
+        add('  .debug_macro    0 : { *(.debug_macro) }');
+        add('  .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) }');
+        add('  .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }');
+        add('  /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }');
+        add('}');
+      end;
+{$endif AArch64}
+
 {$ifdef ARM}
 {$ifdef ARM}
       if target_info.abi=abi_eabi then
       if target_info.abi=abi_eabi then
         begin
         begin
@@ -1542,6 +1777,11 @@ initialization
   RegisterExport(system_arm_linux,texportliblinux);
   RegisterExport(system_arm_linux,texportliblinux);
   RegisterTarget(system_arm_linux_info);
   RegisterTarget(system_arm_linux_info);
 {$endif ARM}
 {$endif ARM}
+{$ifdef aarch64}
+  RegisterImport(system_aarch64_linux,timportliblinux);
+  RegisterExport(system_aarch64_linux,texportliblinux);
+  RegisterTarget(system_aarch64_linux_info);
+{$endif aarch64}
 {$ifdef MIPS}
 {$ifdef MIPS}
 {$ifdef MIPSEL}
 {$ifdef MIPSEL}
   RegisterImport(system_mipsel_linux,timportliblinux);
   RegisterImport(system_mipsel_linux,timportliblinux);

+ 82 - 79
compiler/utils/Makefile

@@ -326,241 +326,244 @@ FPCFPMAKE=$(FPC)
 endif
 endif
 endif
 endif
 ifeq ($(FULL_TARGET),i386-linux)
 ifeq ($(FULL_TARGET),i386-linux)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),i386-go32v2)
 ifeq ($(FULL_TARGET),i386-go32v2)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),i386-win32)
 ifeq ($(FULL_TARGET),i386-win32)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),i386-os2)
 ifeq ($(FULL_TARGET),i386-os2)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),i386-freebsd)
 ifeq ($(FULL_TARGET),i386-freebsd)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),i386-beos)
 ifeq ($(FULL_TARGET),i386-beos)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),i386-haiku)
 ifeq ($(FULL_TARGET),i386-haiku)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netbsd)
 ifeq ($(FULL_TARGET),i386-netbsd)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),i386-solaris)
 ifeq ($(FULL_TARGET),i386-solaris)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),i386-qnx)
 ifeq ($(FULL_TARGET),i386-qnx)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netware)
 ifeq ($(FULL_TARGET),i386-netware)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),i386-openbsd)
 ifeq ($(FULL_TARGET),i386-openbsd)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),i386-wdosx)
 ifeq ($(FULL_TARGET),i386-wdosx)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),i386-darwin)
 ifeq ($(FULL_TARGET),i386-darwin)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),i386-emx)
 ifeq ($(FULL_TARGET),i386-emx)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),i386-watcom)
 ifeq ($(FULL_TARGET),i386-watcom)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netwlibc)
 ifeq ($(FULL_TARGET),i386-netwlibc)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),i386-wince)
 ifeq ($(FULL_TARGET),i386-wince)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),i386-embedded)
 ifeq ($(FULL_TARGET),i386-embedded)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),i386-symbian)
 ifeq ($(FULL_TARGET),i386-symbian)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),i386-nativent)
 ifeq ($(FULL_TARGET),i386-nativent)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),i386-iphonesim)
 ifeq ($(FULL_TARGET),i386-iphonesim)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),i386-android)
 ifeq ($(FULL_TARGET),i386-android)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),i386-aros)
 ifeq ($(FULL_TARGET),i386-aros)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-linux)
 ifeq ($(FULL_TARGET),m68k-linux)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-freebsd)
 ifeq ($(FULL_TARGET),m68k-freebsd)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-netbsd)
 ifeq ($(FULL_TARGET),m68k-netbsd)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-amiga)
 ifeq ($(FULL_TARGET),m68k-amiga)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-atari)
 ifeq ($(FULL_TARGET),m68k-atari)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-openbsd)
 ifeq ($(FULL_TARGET),m68k-openbsd)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-palmos)
 ifeq ($(FULL_TARGET),m68k-palmos)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-embedded)
 ifeq ($(FULL_TARGET),m68k-embedded)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-linux)
 ifeq ($(FULL_TARGET),powerpc-linux)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-netbsd)
 ifeq ($(FULL_TARGET),powerpc-netbsd)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-amiga)
 ifeq ($(FULL_TARGET),powerpc-amiga)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-macos)
 ifeq ($(FULL_TARGET),powerpc-macos)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-darwin)
 ifeq ($(FULL_TARGET),powerpc-darwin)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-morphos)
 ifeq ($(FULL_TARGET),powerpc-morphos)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-embedded)
 ifeq ($(FULL_TARGET),powerpc-embedded)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-wii)
 ifeq ($(FULL_TARGET),powerpc-wii)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-aix)
 ifeq ($(FULL_TARGET),powerpc-aix)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-linux)
 ifeq ($(FULL_TARGET),sparc-linux)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-netbsd)
 ifeq ($(FULL_TARGET),sparc-netbsd)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-solaris)
 ifeq ($(FULL_TARGET),sparc-solaris)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-embedded)
 ifeq ($(FULL_TARGET),sparc-embedded)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-linux)
 ifeq ($(FULL_TARGET),x86_64-linux)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-freebsd)
 ifeq ($(FULL_TARGET),x86_64-freebsd)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-netbsd)
 ifeq ($(FULL_TARGET),x86_64-netbsd)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-solaris)
 ifeq ($(FULL_TARGET),x86_64-solaris)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-openbsd)
 ifeq ($(FULL_TARGET),x86_64-openbsd)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-darwin)
 ifeq ($(FULL_TARGET),x86_64-darwin)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-win64)
 ifeq ($(FULL_TARGET),x86_64-win64)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
 ifeq ($(FULL_TARGET),x86_64-embedded)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-iphonesim)
 ifeq ($(FULL_TARGET),x86_64-iphonesim)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-dragonfly)
 ifeq ($(FULL_TARGET),x86_64-dragonfly)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),arm-linux)
 ifeq ($(FULL_TARGET),arm-linux)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),arm-palmos)
 ifeq ($(FULL_TARGET),arm-palmos)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),arm-darwin)
 ifeq ($(FULL_TARGET),arm-darwin)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),arm-wince)
 ifeq ($(FULL_TARGET),arm-wince)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),arm-gba)
 ifeq ($(FULL_TARGET),arm-gba)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),arm-nds)
 ifeq ($(FULL_TARGET),arm-nds)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),arm-embedded)
 ifeq ($(FULL_TARGET),arm-embedded)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),arm-symbian)
 ifeq ($(FULL_TARGET),arm-symbian)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),arm-android)
 ifeq ($(FULL_TARGET),arm-android)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
 ifeq ($(FULL_TARGET),powerpc64-linux)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-darwin)
 ifeq ($(FULL_TARGET),powerpc64-darwin)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-embedded)
 ifeq ($(FULL_TARGET),powerpc64-embedded)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-aix)
 ifeq ($(FULL_TARGET),powerpc64-aix)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),avr-embedded)
 ifeq ($(FULL_TARGET),avr-embedded)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),armeb-linux)
 ifeq ($(FULL_TARGET),armeb-linux)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),armeb-embedded)
 ifeq ($(FULL_TARGET),armeb-embedded)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),mips-linux)
 ifeq ($(FULL_TARGET),mips-linux)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),mipsel-linux)
 ifeq ($(FULL_TARGET),mipsel-linux)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),mipsel-embedded)
 ifeq ($(FULL_TARGET),mipsel-embedded)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),mipsel-android)
 ifeq ($(FULL_TARGET),mipsel-android)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),jvm-java)
 ifeq ($(FULL_TARGET),jvm-java)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),jvm-android)
 ifeq ($(FULL_TARGET),jvm-android)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),i8086-msdos)
 ifeq ($(FULL_TARGET),i8086-msdos)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
+endif
+ifeq ($(FULL_TARGET),aarch64-linux)
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),aarch64-darwin)
 ifeq ($(FULL_TARGET),aarch64-darwin)
-override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 endif
 endif
 ifeq ($(FULL_TARGET),i386-linux)
 ifeq ($(FULL_TARGET),i386-linux)
 override CLEAN_UNITS+=ppu crc
 override CLEAN_UNITS+=ppu crc

+ 1 - 1
compiler/utils/Makefile.fpc

@@ -3,7 +3,7 @@
 #
 #
 
 
 [target]
 [target]
-programs=fpc ppufiles ppudump ppumove mkarmins mkx86ins
+programs=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins
 rst=fpcsubst
 rst=fpcsubst
 
 
 [clean]
 [clean]

+ 7 - 1
compiler/utils/fpc.pp

@@ -143,6 +143,10 @@ program fpc;
      ppcbin:='ppcarm';
      ppcbin:='ppcarm';
      processorname:='arm';
      processorname:='arm';
 {$endif arm}
 {$endif arm}
+{$ifdef aarch64}
+     ppcbin:='ppca64';
+     processorname:='aarch64';
+{$endif arm}
 {$ifdef sparc}
 {$ifdef sparc}
      ppcbin:='ppcsparc';
      ppcbin:='ppcsparc';
      processorname:='sparc';
      processorname:='sparc';
@@ -202,7 +206,9 @@ program fpc;
                      else
                      else
                        if processorstr <> processorname then
                        if processorstr <> processorname then
                          begin
                          begin
-                           if processorstr='arm' then
+                           if processorstr='aarch64' then
+                             cpusuffix:='a64'
+                           else if processorstr='arm' then
                              cpusuffix:='arm'
                              cpusuffix:='arm'
                            else if processorstr='i386' then
                            else if processorstr='i386' then
                              cpusuffix:='386'
                              cpusuffix:='386'

+ 2 - 2
compiler/utils/mka64ins.pp

@@ -14,7 +14,7 @@
  **********************************************************************}
  **********************************************************************}
 {$mode objfpc}
 {$mode objfpc}
 
 
-program mkarmins;
+program mka64ins;
 
 
 const
 const
   Version = '0.9';
   Version = '0.9';
@@ -153,7 +153,7 @@ begin
   writeln('creating ',fn);
   writeln('creating ',fn);
   assign(f,fn);
   assign(f,fn);
   rewrite(f);
   rewrite(f);
-  writeln(f,'{ don''t edit, this file is generated from armins.dat }');
+  writeln(f,'{ don''t edit, this file is generated from a64ins.dat }');
   writeln(f,'(');
   writeln(f,'(');
 end;
 end;
 
 

+ 3 - 2
compiler/utils/ppuutils/ppudump.pp

@@ -169,8 +169,9 @@ const
   { 83 }  'AROS-i386',
   { 83 }  'AROS-i386',
   { 84 }  'AROS-x86-64',
   { 84 }  'AROS-x86-64',
   { 85 }  'DragonFly-x86-64',
   { 85 }  'DragonFly-x86-64',
-  { 85 }  'Darwin-AArch64',
-  { 86 }  'iPhoneSim-x86-64'
+  { 86 }  'Darwin-AArch64',
+  { 87 }  'iPhoneSim-x86-64',
+  { 88 }  'Linux-AArch64'
   );
   );
 
 
 const
 const

+ 3 - 1
packages/fcl-res/src/elfconsts.pp

@@ -22,7 +22,7 @@ interface
 type
 type
   TElfMachineType = (emtnone, emtsparc, emti386, emtm68k, emtppc, emtppc64,
   TElfMachineType = (emtnone, emtsparc, emti386, emtm68k, emtppc, emtppc64,
                      emtarm, emtarmeb, emtia64, emtx86_64, emtalpha,
                      emtarm, emtarmeb, emtia64, emtx86_64, emtalpha,
-                     emtmips, emtmipsel);
+                     emtmips, emtmipsel, emtaarch64);
 const
 const
   ELFMAGIC     = chr($7f)+'ELF';
   ELFMAGIC     = chr($7f)+'ELF';
 
 
@@ -71,6 +71,7 @@ const
   EM_IA_64       = 50;
   EM_IA_64       = 50;
   EM_MIPS_X      = 51; // GNU readelf returns machine name "Stanford MIPS-X"
   EM_MIPS_X      = 51; // GNU readelf returns machine name "Stanford MIPS-X"
   EM_X86_64      = 62;
   EM_X86_64      = 62;
+  EM_AARCH64     = 183;
   EM_ALPHA       = $9026; //unofficial, but used by gnu toolchain
   EM_ALPHA       = $9026; //unofficial, but used by gnu toolchain
   
   
   //machine-specific flags
   //machine-specific flags
@@ -130,6 +131,7 @@ const
   R_PPC_ADDR32    =   1;
   R_PPC_ADDR32    =   1;
   R_PPC64_ADDR64  =  38;
   R_PPC64_ADDR64  =  38;
   R_ARM_ABS32     =   2;
   R_ARM_ABS32     =   2;
+  R_AARCH64_ABS64 = 257;
   R_68K_32        =   1;
   R_68K_32        =   1;
   R_SPARC_32      =   3;
   R_SPARC_32      =   3;
   R_ALPHA_REFQUAD =   2;
   R_ALPHA_REFQUAD =   2;

+ 3 - 0
packages/fcl-res/src/elfdefaulttarget.inc

@@ -33,6 +33,9 @@
     fMachineType:=emtarmeb;
     fMachineType:=emtarmeb;
     {$ENDIF}
     {$ENDIF}
   {$ENDIF}
   {$ENDIF}
+  {$IFDEF CPUAARCH64}
+  fMachineType:=emtaarch64;
+  {$ENDIF}
   {$IFDEF CPU68K}
   {$IFDEF CPU68K}
   fMachineType:=emtm68k;
   fMachineType:=emtm68k;
   {$ENDIF}
   {$ENDIF}

+ 1 - 0
packages/fcl-res/src/elfreader.pp

@@ -282,6 +282,7 @@ begin
                     fMachineType:=emtarm
                     fMachineType:=emtarm
                   else
                   else
                     fMachineType:=emtarmeb;
                     fMachineType:=emtarmeb;
+      EM_AARCH64: fMachineType:=emtaarch64;
       EM_ALPHA  : fMachineType:=emtalpha;
       EM_ALPHA  : fMachineType:=emtalpha;
       EM_IA_64  : fMachineType:=emtia64;
       EM_IA_64  : fMachineType:=emtia64;
       EM_X86_64 : fMachineType:=emtx86_64;
       EM_X86_64 : fMachineType:=emtx86_64;

+ 2 - 1
packages/fcl-res/src/elfsubwriter.inc

@@ -27,7 +27,7 @@ type
   _TElfRelocTable_= class
   _TElfRelocTable_= class
   private
   private
     fList : TFPList;
     fList : TFPList;
-    fRelocType : byte;
+    fRelocType : longword;
     fEntrySize : integer;
     fEntrySize : integer;
     fSectionType : integer;
     fSectionType : integer;
     fSectionName : string;
     fSectionName : string;
@@ -418,6 +418,7 @@ begin
       EM_386    : begin RelocType:=R_386_32;        SectionType:=SHT_REL;  end;
       EM_386    : begin RelocType:=R_386_32;        SectionType:=SHT_REL;  end;
       EM_PPC    : begin RelocType:=R_PPC_ADDR32;    SectionType:=SHT_RELA; end;
       EM_PPC    : begin RelocType:=R_PPC_ADDR32;    SectionType:=SHT_RELA; end;
       EM_ARM    : begin RelocType:=R_ARM_ABS32;     SectionType:=SHT_REL;  end;
       EM_ARM    : begin RelocType:=R_ARM_ABS32;     SectionType:=SHT_REL;  end;
+      EM_AARCH64: begin RelocType:=R_AARCH64_ABS64; SectionType:=SHT_RELA; end;
       EM_68K    : begin RelocType:=R_68K_32;        SectionType:=SHT_RELA; end;
       EM_68K    : begin RelocType:=R_68K_32;        SectionType:=SHT_RELA; end;
       EM_SPARC  : begin RelocType:=R_SPARC_32;      SectionType:=SHT_RELA; end;
       EM_SPARC  : begin RelocType:=R_SPARC_32;      SectionType:=SHT_RELA; end;
       EM_X86_64 : begin RelocType:=R_x86_64_64;     SectionType:=SHT_RELA; end;
       EM_X86_64 : begin RelocType:=R_x86_64_64;     SectionType:=SHT_RELA; end;

+ 2 - 1
packages/fcl-res/src/elfwriter.pp

@@ -155,7 +155,7 @@ type
 
 
 type
 type
   TElfRelocInfo = record
   TElfRelocInfo = record
-    RelocType : byte;
+    RelocType : longword;
     SectionType : integer;
     SectionType : integer;
   end;
   end;
 (*
 (*
@@ -551,6 +551,7 @@ begin
     emtppc64  : begin fMachineTypeInt:=EM_PPC64; fBits:=ELFCLASS64; fOrder:=ELFDATA2MSB; end;
     emtppc64  : begin fMachineTypeInt:=EM_PPC64; fBits:=ELFCLASS64; fOrder:=ELFDATA2MSB; end;
     emtarm    : begin fMachineTypeInt:=EM_ARM; fBits:=ELFCLASS32; fOrder:=ELFDATA2LSB; end;
     emtarm    : begin fMachineTypeInt:=EM_ARM; fBits:=ELFCLASS32; fOrder:=ELFDATA2LSB; end;
     emtarmeb  : begin fMachineTypeInt:=EM_ARM; fBits:=ELFCLASS32; fOrder:=ELFDATA2MSB; end;
     emtarmeb  : begin fMachineTypeInt:=EM_ARM; fBits:=ELFCLASS32; fOrder:=ELFDATA2MSB; end;
+    emtaarch64: begin fMachineTypeInt:=EM_AARCH64; fBits:=ELFCLASS64; fOrder:=ELFDATA2LSB; end;
     emtalpha  : begin fMachineTypeInt:=EM_ALPHA; fBits:=ELFCLASS64; fOrder:=ELFDATA2LSB; end;
     emtalpha  : begin fMachineTypeInt:=EM_ALPHA; fBits:=ELFCLASS64; fOrder:=ELFDATA2LSB; end;
     emtia64   : begin fMachineTypeInt:=EM_IA_64; fBits:=ELFCLASS64; fOrder:=ELFDATA2LSB; end;
     emtia64   : begin fMachineTypeInt:=EM_IA_64; fBits:=ELFCLASS64; fOrder:=ELFDATA2LSB; end;
     emtx86_64 : begin fMachineTypeInt:=EM_X86_64; fBits:=ELFCLASS64; fOrder:=ELFDATA2LSB; end;
     emtx86_64 : begin fMachineTypeInt:=EM_X86_64; fBits:=ELFCLASS64; fOrder:=ELFDATA2LSB; end;

+ 2 - 1
packages/fpmkunit/src/fpmkunit.pp

@@ -180,7 +180,7 @@ Const
   OSCPUSupported : array[TOS,TCpu] of boolean = (
   OSCPUSupported : array[TOS,TCpu] of boolean = (
     { os          none   i386    m68k  ppc    sparc  x86_64 arm    ppc64  avr    armeb  mips   mipsel jvm    i8086  aarch64 }
     { os          none   i386    m68k  ppc    sparc  x86_64 arm    ppc64  avr    armeb  mips   mipsel jvm    i8086  aarch64 }
     { none }    ( false, false, false, false, false, false, false, false, false, false, false, false, false, false, false),
     { none }    ( false, false, false, false, false, false, false, false, false, false, false, false, false, false, false),
-    { linux }   ( false, true,  true,  true,  true,  true,  true,  true,  false, true , true , true , false, false, false),
+    { linux }   ( false, true,  true,  true,  true,  true,  true,  true,  false, true , true , true , false, false, true ),
     { go32v2 }  ( false, true,  false, false, false, false, false, false, false, false, false, false, false, false, false),
     { go32v2 }  ( false, true,  false, false, false, false, false, false, false, false, false, false, false, false, false),
     { win32 }   ( false, true,  false, false, false, false, false, false, false, false, false, false, false, false, false),
     { win32 }   ( false, true,  false, false, false, false, false, false, false, false, false, false, false, false, false),
     { os2 }     ( false, true,  false, false, false, false, false, false, false, false, false, false, false, false, false),
     { os2 }     ( false, true,  false, false, false, false, false, false, false, false, false, false, false, false, false),
@@ -2615,6 +2615,7 @@ begin
       x86_64:   result := GetGccDirArch('cpux86_64','-m64');
       x86_64:   result := GetGccDirArch('cpux86_64','-m64');
       powerpc:  result := GetGccDirArch('cpupowerpc','-m32');
       powerpc:  result := GetGccDirArch('cpupowerpc','-m32');
       powerpc64:result := GetGccDirArch('cpupowerpc64','-m64');
       powerpc64:result := GetGccDirArch('cpupowerpc64','-m64');
+      aarch64:  result := GetGccDirArch('cpuaarch64','');
     end {case}
     end {case}
   else if OS = darwin then
   else if OS = darwin then
     case CPU of
     case CPU of

+ 1 - 1
packages/rtl-extra/src/linux/unixsock.inc

@@ -13,7 +13,7 @@
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 }
 }
 
 
-{$if not defined(cpux86_64) and not defined(NO_SYSCALL_SOCKETCALL)}
+{$if not defined(cpux86_64) and not defined(cpuaarch64) and not defined(NO_SYSCALL_SOCKETCALL)}
   {$define NEED_SOCKETCALL}
   {$define NEED_SOCKETCALL}
 {$endif}
 {$endif}
 
 

+ 1 - 1
packages/rtl-extra/src/unix/ipc.pp

@@ -860,7 +860,7 @@ uses Syscall;
 
 
 {$ifndef FPC_USE_LIBC}
 {$ifndef FPC_USE_LIBC}
  {$if defined(Linux)}
  {$if defined(Linux)}
-  {$if defined(cpux86_64) or defined(NO_SYSCALL_IPC)}
+  {$if defined(cpux86_64) or defined(cpuaarch64) or defined(NO_SYSCALL_IPC)}
     {$i ipcsys.inc}
     {$i ipcsys.inc}
   {$else}
   {$else}
     {$i ipccall.inc}
     {$i ipccall.inc}

+ 1 - 0
rtl/linux/aarch64/bsyscall.inc

@@ -0,0 +1 @@
+{ nothing }

+ 91 - 0
rtl/linux/aarch64/cprt0.as

@@ -0,0 +1,91 @@
+/*
+   Start-up code for Free Pascal Compiler when linking with C library.
+
+   Written by Edmund Grimley Evans in 2015 and released into the public domain.
+*/
+
+	.text
+	.align 2
+
+	.globl _start
+	.type  _start,#function
+_start:
+	/* Initialise FP to zero */
+	mov	x29,#0
+
+	/* This is rtld_fini */
+	mov	x5,x0
+
+	/* Get argc, argv, envp */
+	ldr	x1,[sp]
+	add	x2,sp,#8
+	add	x11,x1,#1
+	add	x11,x2,x11,lsl #3
+
+	/* Save argc, argv, envp, and initial stack pointer */
+	adrp	x10,:got:operatingsystem_parameter_argc
+	ldr	x10,[x10,#:got_lo12:operatingsystem_parameter_argc]
+	str	x1,[x10]
+	adrp	x10,:got:operatingsystem_parameter_argv
+	ldr	x10,[x10,#:got_lo12:operatingsystem_parameter_argv]
+	str	x2,[x10]
+	adrp	x10,:got:operatingsystem_parameter_envp
+	ldr	x10,[x10,#:got_lo12:operatingsystem_parameter_envp]
+	str	x11,[x10]
+	adrp	x10,:got:__stkptr
+	ldr	x10,[x10,#:got_lo12:__stkptr]
+	mov	x6,sp
+	str	x6,[x10]
+
+	/* __libc_start_main(main, argc, argv,
+	                     init, fini, rtld_fini, stack_end) */
+	adrp	x0,:got:PASCALMAIN
+	ldr	x0,[x0,#:got_lo12:PASCALMAIN]
+	adrp	x3,:got:__libc_csu_init
+	ldr	x3,[x3,#:got_lo12:__libc_csu_init]
+	adrp	x4,:got:__libc_csu_fini
+	ldr	x4,[x4,#:got_lo12:__libc_csu_fini]
+	bl	__libc_start_main
+
+	/* This should never happen */
+	b	abort
+
+	.globl	_init
+	.type	_init,#function
+_init:
+	ret
+
+	.globl	_fini
+	.type	_fini,#function
+_fini:
+	ret
+
+	.globl	_haltproc
+	.type	_haltproc,#function
+_haltproc:
+	adrp	x0,:got:operatingsystem_result
+	ldr	x0,[x0,#:got_lo12:operatingsystem_result]
+	ldr	w0,[x0]
+	mov	w8,#94 // syscall_nr_exit_group
+	svc	#0
+	b	_haltproc
+
+	/* Define a symbol for the first piece of initialized data. */
+	.data
+	.align 3
+	.globl __data_start
+__data_start:
+	.long 0
+	.weak data_start
+	data_start = __data_start
+
+	.bss
+	.align 3
+
+	.comm __stkptr,8
+
+	.comm operatingsystem_parameter_envp,8
+	.comm operatingsystem_parameter_argc,8
+	.comm operatingsystem_parameter_argv,8
+
+	.section .note.GNU-stack,"",%progbits

+ 72 - 0
rtl/linux/aarch64/dllprt0.as

@@ -0,0 +1,72 @@
+/*
+   Start-up code for Free Pascal Compiler in a shared library,
+   not linking with C library.
+
+   Written by Edmund Grimley Evans in 2015 and released into the public domain.
+*/
+
+	.text
+	.align 2
+
+	.globl	_startlib
+	.type	_startlib,#function
+_startlib:
+	.globl	FPC_SHARED_LIB_START
+	.type	FPC_SHARED_LIB_START,#function
+FPC_SHARED_LIB_START:
+	stp	x29,x30,[sp,#-16]!
+
+	/* Save argc, argv and envp */
+	adrp	x9,:got:operatingsystem_parameter_argc
+	ldr	x9,[x9,#:got_lo12:operatingsystem_parameter_argc]
+	str	x0,[x9]
+	adrp	x9,:got:operatingsystem_parameter_argv
+	ldr	x9,[x9,#:got_lo12:operatingsystem_parameter_argv]
+	str	x1,[x9]
+	adrp	x9,:got:operatingsystem_parameter_envp
+	ldr	x9,[x9,#:got_lo12:operatingsystem_parameter_envp]
+	str	x2,[x9]
+
+	/* Save initial stackpointer */
+	adrp	x9,:got:__stkptr
+	ldr	x9,[x9,#:got_lo12:__stkptr]
+	mov	x10,sp
+	str	x10,[x9]
+
+	/* Call main */
+	bl	PASCALMAIN
+
+	/* Return */
+	ldp	x29,x30,[sp],#16
+	ret
+
+	.globl	_haltproc
+	.type	_haltproc,#function
+_haltproc:
+	adrp	x0,:got:operatingsystem_result
+	ldr	x0,[x0,#:got_lo12:operatingsystem_result]
+	ldr	w0,[x0]
+	mov	w8,#94 // syscall_nr_exit_group
+	svc	#0
+	b	_haltproc
+
+	/* Define a symbol for the first piece of initialized data. */
+	.data
+	.align 3
+	.globl __data_start
+__data_start:
+	.long 0
+	.weak data_start
+	data_start = __data_start
+
+	.bss
+	.align 3
+
+	.comm __dl_fini,8
+	.comm __stkptr,8
+
+	.comm operatingsystem_parameter_envp,8
+	.comm operatingsystem_parameter_argc,8
+	.comm operatingsystem_parameter_argv,8
+
+	.section .note.GNU-stack,"",%progbits

+ 10 - 0
rtl/linux/aarch64/gprt0.as

@@ -0,0 +1,10 @@
+/*
+   Start-up code for Free Pascal Compiler when linking with C library
+   with profiling support.
+
+   Written by Edmund Grimley Evans in 2015 and released into the public domain.
+*/
+
+	.text
+	.align 2
+	b	xx_aarch64_gprt0_unimplemented

+ 77 - 0
rtl/linux/aarch64/prt0.as

@@ -0,0 +1,77 @@
+/*
+   Start-up code for Free Pascal Compiler, not in a shared library,
+   not linking with C library.
+
+   Written by Edmund Grimley Evans in 2015 and released into the public domain.
+*/
+
+	.text
+	.align 2
+
+	.globl _dynamic_start
+	.type  _dynamic_start,#function
+_dynamic_start:
+	ldr	x10,=__dl_fini
+	str	x0,[x10]
+	b	_start
+
+	.globl	_start
+	.type	_start,#function
+_start:
+	/* Initialise FP to zero */
+	mov	x29,#0
+
+	/* Get argc, argv, envp */
+	ldr	x1,[sp]
+	add	x2,sp,#8
+	add	x11,x1,#1
+	add	x11,x2,x11,lsl #3
+
+	/* Save argc, argv, envp, and initial stack pointer */
+	ldr	x10,=operatingsystem_parameter_argc
+	str	x1,[x10]
+	ldr	x10,=operatingsystem_parameter_argv
+	str	x2,[x10]
+	ldr	x10,=operatingsystem_parameter_envp
+	str	x11,[x10]
+	ldr	x10,=__stkptr
+	mov	x6,sp
+	str	x6,[x10]
+
+	/* Call main */
+	bl	PASCALMAIN
+
+	.globl	_haltproc
+	.type	_haltproc,#function
+_haltproc:
+	ldr	x10,=__dl_fini
+	ldr	x0,[x10]
+	cbz	x0,.Lexit
+	blr	x0
+.Lexit:
+	ldr	x10,=operatingsystem_result
+	ldr	w0,[x10]
+	mov	w8,#94 // syscall_nr_exit_group
+	svc	#0
+	b	_haltproc
+
+	/* Define a symbol for the first piece of initialized data. */
+	.data
+	.align 3
+	.globl __data_start
+__data_start:
+	.long 0
+	.weak data_start
+	data_start = __data_start
+
+	.bss
+	.align 3
+
+	.comm __dl_fini,8
+	.comm __stkptr,8
+
+	.comm operatingsystem_parameter_envp,8
+	.comm operatingsystem_parameter_argc,8
+	.comm operatingsystem_parameter_argv,8
+
+	.section .note.GNU-stack,"",%progbits

+ 44 - 0
rtl/linux/aarch64/sighnd.inc

@@ -0,0 +1,44 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 1999-2000 by Michael Van Canneyt,
+    member of the Free Pascal development team.
+
+    Signal handler is arch dependant due to processor to language
+    exception conversion.
+
+    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 SignalToRunerror(Sig: longint; SigInfo: PSigInfo; UContext: PUContext); public name '_FPC_DEFAULTSIGHANDLER'; cdecl;
+
+var
+  res : word;
+begin
+  res:=0;
+  case sig of
+    SIGFPE:
+        res:=207;
+    SIGILL:
+        res:=216;
+    SIGSEGV :
+        res:=216;
+    SIGBUS:
+        res:=214;
+    SIGINT:
+        res:=217;
+    SIGQUIT:
+        res:=233;
+  end;
+  reenable_signal(sig);
+  { give runtime error at the position where the signal was raised }
+  if res<>0 then
+    HandleErrorAddrFrame(res,
+      pointer(uContext^.uc_mcontext.pc),
+      pointer(uContext^.uc_mcontext.regs[29]));
+end;

+ 47 - 0
rtl/linux/aarch64/sighndh.inc

@@ -0,0 +1,47 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 1999-2000 by Jonas Maebe,
+    member of the Free Pascal development team.
+
+    TSigContext and associated structures.
+
+    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.
+
+ **********************************************************************}
+
+{$packrecords C}
+
+type
+  PSigContext = ^TSigContext;
+  TSigContext = record
+    fault_address : cULong;
+    regs : array[0..30] of cULong;
+    sp : cULong;
+    pc : cULong;
+    pstate : cULong;
+    __pad : cULong;
+    { The following field should be 16-byte-aligned. Currently the
+      directive for specifying alignment is buggy, so the preceding
+      field was added so that the record has the right size. }
+    __reserved : array[0..4095] of cUChar;
+  end;
+
+  stack_t = record
+    ss_sp : pointer;
+    ss_flags : cInt;
+    ss_size : size_t;
+  end;
+
+  PUContext = ^TUContext;
+  TUContext = record
+    uc_flags : cULong;
+    uc_link : PUContext;
+    uc_stack : stack_t;
+    uc_mcontext : TSigContext;
+    uc_sigmask : sigset_t;
+  end;

+ 72 - 0
rtl/linux/aarch64/stat.inc

@@ -0,0 +1,72 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 1999-2000 by Jonas Maebe, (c) 2005 Thomas Schatzl,
+    members of the Free Pascal development team.
+
+    Contains the definition of the stat type for the PowerPC64 platform.
+
+    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.
+
+ **********************************************************************}
+
+{ This structure was adapted from
+
+    include/uapi/asm-generic/stat.h
+
+  in Linux 4.0. Note that the stat record is the same for direct
+  syscalls as for when linking to libc.
+}
+
+{$PACKRECORDS C}
+  stat = record
+    case integer of
+    0 : (
+      st_dev        : cULong;
+      st_ino        : cULong;
+      st_mode       : cUInt;
+      st_nlink      : cUInt;
+      st_uid        : cUInt;
+      st_gid        : cUInt;
+      st_rdev       : cULong;
+      __pad1a       : cULong;
+      st_size       : cLong;
+      st_blksize    : cInt;
+      __pad2a       : cInt;
+      st_blocks     : cLong;
+      st_atime      : cLong;
+      st_atime_nsec : cULong;
+      st_mtime      : cLong;
+      st_mtime_nsec : cULong;
+      st_ctime      : cLong;
+      st_ctime_nsec : cULong;
+      __unused4a    : cUInt;
+      __unused5a    : cUInt;
+      );
+    1 : (
+      dev           : cULong deprecated;
+      ino           : cULong deprecated;
+      mode          : cUInt deprecated;
+      nlink         : cUInt deprecated;
+      uid           : cUInt deprecated;
+      gid           : cUInt deprecated;
+      rdev          : cULong deprecated;
+      __pad1b       : cULong deprecated;
+      size          : cLong deprecated;
+      blksize       : cInt deprecated;
+      __pad2b       : cInt deprecated;
+      blocks        : cLong deprecated;
+      atime         : cLong deprecated;
+      atime_nsec    : cULong deprecated;
+      mtime         : cLong deprecated;
+      mtime_nsec    : cULong deprecated;
+      ctime         : cLong deprecated;
+      ctime_nsec    : cULong deprecated;
+      __unused4b    : cUInt deprecated;
+      __unused5b    : cUInt deprecated;
+      );
+  end;

+ 127 - 0
rtl/linux/aarch64/syscall.inc

@@ -0,0 +1,127 @@
+{
+  This file is part of the Free Pascal run time library.
+
+  Perform syscall with 0..6 arguments.
+  If syscall return value is negative, negate it, set errno, and return -1.
+
+  Written by Edmund Grimley Evans in 2015 and released into the public domain.
+}
+
+function FpSysCall(sysnr:TSysParam):TSysResult;
+assembler; nostackframe; [public,alias:'FPC_SYSCALL0'];
+asm
+  mov w8,w0
+  svc #0
+  tbz x0,#63,.Ldone
+  str x30,[sp,#-16]!
+  neg x0,x0
+  bl seterrno
+  ldr x30,[sp],#16
+  mov x0,#-1
+.Ldone:
+end;
+
+function FpSysCall(sysnr,param1:TSysParam):TSysResult;
+assembler; nostackframe; [public,alias:'FPC_SYSCALL1'];
+asm
+  mov w8,w0
+  mov x0,x1
+  svc #0
+  tbz x0,#63,.Ldone
+  str x30,[sp,#-16]!
+  neg x0,x0
+  bl seterrno
+  ldr x30,[sp],#16
+  mov x0,#-1
+.Ldone:
+end;
+
+function FpSysCall(sysnr,param1,param2:TSysParam):TSysResult;
+assembler; nostackframe; [public,alias:'FPC_SYSCALL2'];
+asm
+  mov w8,w0
+  mov x0,x1
+  mov x1,x2
+  svc #0
+  tbz x0,#63,.Ldone
+  str x30,[sp,#-16]!
+  neg x0,x0
+  bl seterrno
+  ldr x30,[sp],#16
+  mov x0,#-1
+.Ldone:
+end;
+
+function FpSysCall(sysnr,param1,param2,param3:TSysParam):TSysResult;
+assembler; nostackframe; [public,alias:'FPC_SYSCALL3'];
+asm
+  mov w8,w0
+  mov x0,x1
+  mov x1,x2
+  mov x2,x3
+  svc #0
+  tbz x0,#63,.Ldone
+  str x30,[sp,#-16]!
+  neg x0,x0
+  bl seterrno
+  ldr x30,[sp],#16
+  mov x0,#-1
+.Ldone:
+end;
+
+function FpSysCall(sysnr,param1,param2,param3,param4:TSysParam):TSysResult;
+assembler; nostackframe; [public,alias:'FPC_SYSCALL4'];
+asm
+  mov w8,w0
+  mov x0,x1
+  mov x1,x2
+  mov x2,x3
+  mov x3,x4
+  svc #0
+  tbz x0,#63,.Ldone
+  str x30,[sp,#-16]!
+  neg x0,x0
+  bl seterrno
+  ldr x30,[sp],#16
+  mov x0,#-1
+.Ldone:
+end;
+
+function FpSysCall(sysnr,param1,param2,param3,param4,param5:TSysParam):TSysResult;
+assembler; nostackframe; [public,alias:'FPC_SYSCALL5'];
+asm
+  mov w8,w0
+  mov x0,x1
+  mov x1,x2
+  mov x2,x3
+  mov x3,x4
+  mov x4,x5
+  svc #0
+  tbz x0,#63,.Ldone
+  str x30,[sp,#-16]!
+  neg x0,x0
+  bl seterrno
+  ldr x30,[sp],#16
+  mov x0,#-1
+.Ldone:
+end;
+
+function FpSysCall(sysnr,param1,param2,param3,param4,param5,param6:TSysParam):TSysResult;
+assembler; nostackframe; [public,alias:'FPC_SYSCALL6'];
+asm
+  mov w8,w0
+  mov x0,x1
+  mov x1,x2
+  mov x2,x3
+  mov x3,x4
+  mov x4,x5
+  mov x5,x6
+  svc #0
+  tbz x0,#63,.Ldone
+  str x30,[sp,#-16]!
+  neg x0,x0
+  bl seterrno
+  ldr x30,[sp],#16
+  mov x0,#-1
+.Ldone:
+end;

+ 35 - 0
rtl/linux/aarch64/syscallh.inc

@@ -0,0 +1,35 @@
+{
+    Copyright (c) 2002 by Marco van de Voort
+
+    Header for syscalls in system unit.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    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.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+    MA 02110-1301, USA.
+
+ ****************************************************************************
+
+}
+
+Type
+  TSysResult = Int64;
+  TSysParam  = Int64;
+
+function Do_SysCall(sysnr:TSysParam):TSysResult; external name 'FPC_SYSCALL0';
+function Do_SysCall(sysnr,param1:TSysParam):TSysResult; external name 'FPC_SYSCALL1';
+function Do_SysCall(sysnr,param1,param2:TSysParam):TSysResult; external name 'FPC_SYSCALL2';
+function Do_SysCall(sysnr,param1,param2,param3:TSysParam):TSysResult; external name 'FPC_SYSCALL3';
+function Do_SysCall(sysnr,param1,param2,param3,param4:TSysParam):TSysResult; external name 'FPC_SYSCALL4';
+function Do_SysCall(sysnr,param1,param2,param3,param4,param5:TSysParam):TSysResult; external name 'FPC_SYSCALL5';
+function Do_SysCall(sysnr,param1,param2,param3,param4,param5,param6:TSysParam):TSysResult; external name 'FPC_SYSCALL6';

+ 1 - 0
rtl/linux/aarch64/sysnr.inc

@@ -0,0 +1 @@
+{$i ../sysnr-gen.inc}

+ 73 - 3
rtl/linux/bunxsysc.inc

@@ -297,7 +297,11 @@ end;
 function fpgetpgrp : pid_t;
 function fpgetpgrp : pid_t;
 
 
 begin
 begin
+{$if defined(generic_linux_syscalls)}
+ fpgetpgrp:=do_syscall(syscall_nr_getpgid,0);
+{$else}
  fpgetpgrp:=do_syscall(syscall_nr_getpgrp);
  fpgetpgrp:=do_syscall(syscall_nr_getpgrp);
+{$endif}
 end;
 end;
 
 
 function fpsetsid : pid_t;
 function fpsetsid : pid_t;
@@ -327,29 +331,59 @@ Function fplink(existing:pchar;newone:pchar):cint;
   In effect, new will be the same file as old.
   In effect, new will be the same file as old.
 }
 }
 begin
 begin
+{$if defined(generic_linux_syscalls)}
+  fpLink:=Do_Syscall(syscall_nr_linkat,AT_FDCWD,TSysParam(existing),AT_FDCWD,TSysParam(newone),0);
+{$else}
   fpLink:=Do_Syscall(syscall_nr_link,TSysParam(existing),TSysParam(newone));
   fpLink:=Do_Syscall(syscall_nr_link,TSysParam(existing),TSysParam(newone));
+{$endif}
 end;
 end;
 
 
 Function fpmkfifo(path:pchar;mode:mode_t):cint;
 Function fpmkfifo(path:pchar;mode:mode_t):cint;
 
 
 begin
 begin
 
 
+{$if defined(generic_linux_syscalls)}
+fpmkfifo:=do_syscall(syscall_nr_mknodat,AT_FDCWD,TSysParam(path),TSysParam(mode or S_IFIFO),TSysParam(0));
+{$else}
 fpmkfifo:=do_syscall(syscall_nr_mknod,TSysParam(path),TSysParam(mode or S_IFIFO),TSysParam(0));
 fpmkfifo:=do_syscall(syscall_nr_mknod,TSysParam(path),TSysParam(mode or S_IFIFO),TSysParam(0));
+{$endif}
 end;
 end;
 
 
 Function fpchmod(path:pchar;mode:mode_t):cint;
 Function fpchmod(path:pchar;mode:mode_t):cint;
 
 
 begin
 begin
+{$if defined(generic_linux_syscalls)}
+  fpchmod:=do_syscall(syscall_nr_fchmodat,AT_FDCWD,TSysParam(path),TSysParam(mode),0);
+{$else}
   fpchmod:=do_syscall(syscall_nr_chmod,TSysParam(path),TSysParam(mode));
   fpchmod:=do_syscall(syscall_nr_chmod,TSysParam(path),TSysParam(mode));
+{$endif}
 end;
 end;
 
 
 Function fpchown(path:pchar;owner:uid_t;group:gid_t):cint;
 Function fpchown(path:pchar;owner:uid_t;group:gid_t):cint;
 
 
 begin
 begin
+{$if defined(generic_linux_syscalls)}
+  fpChOwn:=do_syscall(syscall_nr_fchownat,AT_FDCWD,TSysParam(path),TSysParam(owner),TSysParam(group),0);
+{$else}
   fpChOwn:=do_syscall(syscall_nr_chown,TSysParam(path),TSysParam(owner),TSysParam(group));
   fpChOwn:=do_syscall(syscall_nr_chown,TSysParam(path),TSysParam(owner),TSysParam(group));
+{$endif}
 end;
 end;
 
 
-{$ifndef NO_SYSCALL_UTIME}
+{$if defined(generic_linux_syscalls)}
+
+Function fpUtime(path:pchar;times:putimbuf):cint;
+var
+  tsa: Array[0..1] of timespec;
+begin
+  tsa[0].tv_sec := times^.actime;
+  tsa[0].tv_nsec := 0;
+  tsa[1].tv_sec := times^.modtime;
+  tsa[1].tv_nsec := 0;
+  fputime:=do_syscall(syscall_nr_utimensat,AT_FDCWD,TSysParam(path),
+                      TSysParam(@tsa),0);
+end;
+
+{$elseif not defined(NO_SYSCALL_UTIME)}
 
 
 Function fpUtime(path:pchar;times:putimbuf):cint;
 Function fpUtime(path:pchar;times:putimbuf):cint;
 
 
@@ -377,7 +411,11 @@ end;
 Function fppipe(var fildes : tfildes):cint;
 Function fppipe(var fildes : tfildes):cint;
 
 
 begin
 begin
+{$if defined(generic_linux_syscalls)}
+ fppipe:=do_syscall(syscall_nr_pipe2,TSysParam(@fildes),0);
+{$else}
  fppipe:=do_syscall(syscall_nr_pipe,TSysParam(@fildes));
  fppipe:=do_syscall(syscall_nr_pipe,TSysParam(@fildes));
+{$endif}
 end;
 end;
 {$endif FPC_BASEUNIX_HAS_FPPIPE}
 {$endif FPC_BASEUNIX_HAS_FPPIPE}
 
 
@@ -422,6 +460,18 @@ Function fpSelect(N:cint;readfds,writefds,exceptfds:pfdSet;TimeOut:PTimeVal):cin
   Select checks whether the file descriptor sets in readfs/writefs/exceptfs
   Select checks whether the file descriptor sets in readfs/writefs/exceptfs
   have changed.
   have changed.
 }
 }
+{$if defined(generic_linux_syscalls)}
+
+var ts : timespec;
+begin
+  ts.tv_sec := timeout^.tv_sec;
+  ts.tv_nsec := timeout^.tv_usec * 1000;
+  fpSelect:=do_syscall(syscall_nr_pselect6,n,
+                       tsysparam(readfds),tsysparam(writefds),
+                       tsysparam(exceptfds),tsysparam(@ts),0);
+end;
+
+{$else}
 
 
 begin
 begin
 {$ifdef cpux86_64}
 {$ifdef cpux86_64}
@@ -436,10 +486,22 @@ begin
 {$endif bunxfunc_fpselect_implemented}
 {$endif bunxfunc_fpselect_implemented}
 end;
 end;
 
 
+{$endif}
+
 function fpPoll(fds: ppollfd; nfds: cuint; timeout: clong): cint;
 function fpPoll(fds: ppollfd; nfds: cuint; timeout: clong): cint;
+{$if defined(generic_linux_syscalls)}
+var ts : timespec;
+begin
+  ts.tv_sec := timeout div 1000;
+  ts.tv_nsec := (timeout mod 1000) * 1000000;
+  fpPoll:=do_syscall(syscall_nr_ppoll,tsysparam(fds),tsysparam(nfds),
+                     tsysparam(@ts),0);
+end;
+{$else}
 begin
 begin
   fpPoll:=do_syscall(syscall_nr_poll,tsysparam(fds),tsysparam(nfds),tsysparam(timeout));
   fpPoll:=do_syscall(syscall_nr_poll,tsysparam(fds),tsysparam(nfds),tsysparam(timeout));
 end;
 end;
+{$endif}
 
 
 Function fpLstat(path:pchar;Info:pstat):cint;
 Function fpLstat(path:pchar;Info:pstat):cint;
 {
 {
@@ -447,6 +509,9 @@ Function fpLstat(path:pchar;Info:pstat):cint;
 }
 }
 
 
 begin
 begin
+{$if defined(generic_linux_syscalls)}
+ fpLStat:=do_syscall(syscall_nr_fstatat,AT_FDCWD,TSysParam(path),TSysParam(info),0)
+{$else}
  fpLStat:=do_syscall(
  fpLStat:=do_syscall(
 {$ifdef cpu64}
 {$ifdef cpu64}
     syscall_nr_lstat,
     syscall_nr_lstat,
@@ -454,6 +519,7 @@ begin
     syscall_nr_lstat64,
     syscall_nr_lstat64,
 {$endif}
 {$endif}
     TSysParam(path),TSysParam(info));
     TSysParam(path),TSysParam(info));
+{$endif}
 end;
 end;
 
 
 
 
@@ -465,12 +531,12 @@ function fpNice(N:cint):cint;
 Doesn't exist in BSD. Linux emu uses setpriority in a construct as below:
 Doesn't exist in BSD. Linux emu uses setpriority in a construct as below:
 }
 }
 
 
-{$ifdef cpux86_64}
+{$if defined(generic_linux_syscalls) or defined(cpux86_64)}
 var
 var
   oldprio : cint;
   oldprio : cint;
 {$endif}
 {$endif}
 begin
 begin
-{$ifdef cpux86_64}
+{$if defined(generic_linux_syscalls) or defined(cpux86_64)}
   oldprio:=fpGetPriority(Prio_Process,0);
   oldprio:=fpGetPriority(Prio_Process,0);
   fpNice:=fpSetPriority(Prio_Process,0,oldprio+N);
   fpNice:=fpSetPriority(Prio_Process,0,oldprio+N);
   if fpNice=0 then
   if fpNice=0 then
@@ -536,7 +602,11 @@ Function fpSymlink(oldname,newname:pchar):cint;
 }
 }
 
 
 begin
 begin
+{$if defined(generic_linux_syscalls)}
+  fpsymlink:=do_syscall(syscall_nr_symlinkat,TSysParam(oldname),AT_FDCWD,TSysParam(newname));
+{$else}
   fpsymlink:=do_syscall(syscall_nr_symlink,TSysParam(oldname),TSysParam(newname));
   fpsymlink:=do_syscall(syscall_nr_symlink,TSysParam(oldname),TSysParam(newname));
+{$endif}
 end;
 end;
 
 
 function Fppread(fd: cint; buf: pchar; nbytes : size_t; offset:Toff): ssize_t; [public, alias : 'FPC_SYSC_PREAD'];
 function Fppread(fd: cint; buf: pchar; nbytes : size_t; offset:Toff): ssize_t; [public, alias : 'FPC_SYSC_PREAD'];

+ 15 - 0
rtl/linux/linux.pp

@@ -17,6 +17,8 @@
 **********************************************************************}
 **********************************************************************}
 unit Linux;
 unit Linux;
 
 
+{$i osdefs.inc}
+
 {$packrecords c}
 {$packrecords c}
 {$ifdef FPC_USE_LIBC} 
 {$ifdef FPC_USE_LIBC} 
  {$linklib rt} // for clock* functions
  {$linklib rt} // for clock* functions
@@ -525,7 +527,11 @@ end;
 
 
 function epoll_create(size: cint): cint;
 function epoll_create(size: cint): cint;
 begin
 begin
+{$if defined(generic_linux_syscalls)}
+  epoll_create := do_syscall(syscall_nr_epoll_create1,0)
+{$else}
   epoll_create := do_syscall(syscall_nr_epoll_create,tsysparam(size));
   epoll_create := do_syscall(syscall_nr_epoll_create,tsysparam(size));
+{$endif}
 end;
 end;
 
 
 function epoll_ctl(epfd, op, fd: cint; event: pepoll_event): cint;
 function epoll_ctl(epfd, op, fd: cint; event: pepoll_event): cint;
@@ -536,8 +542,13 @@ end;
 
 
 function epoll_wait(epfd: cint; events: pepoll_event; maxevents, timeout: cint): cint;
 function epoll_wait(epfd: cint; events: pepoll_event; maxevents, timeout: cint): cint;
 begin
 begin
+{$if defined(generic_linux_syscalls)}
+  epoll_wait := do_syscall(syscall_nr_epoll_pwait, tsysparam(epfd),
+    tsysparam(events), tsysparam(maxevents), tsysparam(timeout),0);
+{$else}
   epoll_wait := do_syscall(syscall_nr_epoll_wait, tsysparam(epfd),
   epoll_wait := do_syscall(syscall_nr_epoll_wait, tsysparam(epfd),
     tsysparam(events), tsysparam(maxevents), tsysparam(timeout));
     tsysparam(events), tsysparam(maxevents), tsysparam(timeout));
+{$endif}
 end;
 end;
 
 
 function capget(header:Puser_cap_header;data:Puser_cap_data):cint;
 function capget(header:Puser_cap_header;data:Puser_cap_data):cint;
@@ -693,7 +704,11 @@ end;
 function inotify_init1(flags:cint):cint;
 function inotify_init1(flags:cint):cint;
 
 
 begin
 begin
+{$if defined(generic_linux_syscalls)}
+  inotify_init1:=do_SysCall(syscall_nr_inotify_init1,tsysparam(flags));
+{$else}
   inotify_init1:=do_SysCall(syscall_nr_inotify_init,tsysparam(flags));
   inotify_init1:=do_SysCall(syscall_nr_inotify_init,tsysparam(flags));
+{$endif}
 end;
 end;
 
 
 function inotify_add_watch(fd:cint; name:Pchar; mask:cuint32):cint;
 function inotify_add_watch(fd:cint; name:Pchar; mask:cuint32):cint;

+ 30 - 0
rtl/linux/oldlinux.pp

@@ -1924,9 +1924,16 @@ Function Sys_Mkdir(Filename:pchar;mode:longint):longint;
 var
 var
   regs : SysCallregs;
   regs : SysCallregs;
 begin
 begin
+{$if defined(generic_linux_syscalls)}
+  regs.reg2:=AT_FDCWD;
+  regs.reg3:=longint(filename);
+  regs.reg4:=mode;
+  Sys_MkDir:=SysCall(SysCall_nr_mkdirat,regs);
+{$else}
   regs.reg2:=longint(filename);
   regs.reg2:=longint(filename);
   regs.reg3:=mode;
   regs.reg3:=mode;
   Sys_MkDir:=SysCall(SysCall_nr_mkdir,regs);
   Sys_MkDir:=SysCall(SysCall_nr_mkdir,regs);
+{$endif}
 end;
 end;
 
 
 
 
@@ -1935,8 +1942,15 @@ Function Sys_Rmdir(Filename:pchar):longint;
 var
 var
   regs : SysCallregs;
   regs : SysCallregs;
 begin
 begin
+{$if defined(generic_linux_syscalls)}
+  regs.reg2:=AT_FDCWD;
+  regs.reg3:=longint(filename);
+  regs.reg4:=AT_REMOVEDIR;
+  Sys_Rmdir:=SysCall(SysCall_nr_unlinkat,regs);
+{$else}
   regs.reg2:=longint(filename);
   regs.reg2:=longint(filename);
   Sys_Rmdir:=SysCall(SysCall_nr_rmdir,regs);
   Sys_Rmdir:=SysCall(SysCall_nr_rmdir,regs);
+{$endif}
 end;
 end;
 
 
 
 
@@ -2744,7 +2758,18 @@ var
 begin
 begin
   sr.reg2:=oldfile;
   sr.reg2:=oldfile;
   sr.reg3:=newfile;
   sr.reg3:=newfile;
+{$if defined(generic_linux_syscalls)}
+  sr.reg4:=0;
+  if oldfile<>newfile then
+    SysCall(Syscall_nr_dup3,sr)
+  else
+    begin
+      sr.reg3:=F_GetFd;
+      SysCall(Syscall_nr_fcntl,sr);
+    end;
+{$else}
   SysCall(Syscall_nr_dup2,sr);
   SysCall(Syscall_nr_dup2,sr);
+{$endif}
   linuxerror:=errno;
   linuxerror:=errno;
   Dup2:=(LinuxError=0);
   Dup2:=(LinuxError=0);
 end;
 end;
@@ -2782,7 +2807,12 @@ var
   regs : SysCallregs;
   regs : SysCallregs;
 begin
 begin
   regs.reg2:=longint(@pip);
   regs.reg2:=longint(@pip);
+{$if defined(generic_linux_syscalls)}
+  regs.reg3:=0;
+  SysCall(SysCall_nr_pipe2,regs);
+{$else}
   SysCall(SysCall_nr_pipe,regs);
   SysCall(SysCall_nr_pipe,regs);
+{$endif}
   pipe_in:=pip[1];
   pipe_in:=pip[1];
   pipe_out:=pip[2];
   pipe_out:=pip[2];
   linuxerror:=errno;
   linuxerror:=errno;

+ 4 - 0
rtl/linux/osdefs.inc

@@ -85,3 +85,7 @@
   {$endif FPC_ABI_EABI}
   {$endif FPC_ABI_EABI}
 {$endif cpuarm}
 {$endif cpuarm}
 
 
+{$ifdef cpuaarch64}
+  {$define generic_linux_syscalls}
+  {$undef usestime}
+{$endif cpuaarch64}

+ 55 - 5
rtl/linux/ossysc.inc

@@ -20,7 +20,7 @@
 *****************************************************************************}
 *****************************************************************************}
 
 
 function Fptime(tloc:pTime_t): Time_t; [public, alias : 'FPC_SYSC_TIME'];
 function Fptime(tloc:pTime_t): Time_t; [public, alias : 'FPC_SYSC_TIME'];
-{$ifdef FPC_USEGETTIMEOFDAY}
+{$if defined(generic_linux_syscalls) or defined(FPC_USEGETTIMEOFDAY)}
 VAR tv     : timeval;
 VAR tv     : timeval;
     tz     : timezone;
     tz     : timezone;
     retval : longint;
     retval : longint;
@@ -49,7 +49,11 @@ end;
 function Fpopen(path: pchar; flags : cint; mode: mode_t):cint; [public, alias : 'FPC_SYSC_OPEN'];
 function Fpopen(path: pchar; flags : cint; mode: mode_t):cint; [public, alias : 'FPC_SYSC_OPEN'];
 
 
 Begin
 Begin
+{$if defined(generic_linux_syscalls)}
+ Fpopen:=do_syscall(syscall_nr_openat,AT_FDCWD,TSysParam(path),TSysParam(flags or O_LARGEFILE),TSysParam(mode));
+{$else}
  Fpopen:=do_syscall(syscall_nr_open,TSysParam(path),TSysParam(flags or O_LARGEFILE),TSysParam(mode));
  Fpopen:=do_syscall(syscall_nr_open,TSysParam(path),TSysParam(flags or O_LARGEFILE),TSysParam(mode));
+{$endif}
 End;
 End;
 
 
 function Fpclose(fd : cint): cint; [public, alias : 'FPC_SYSC_CLOSE'];
 function Fpclose(fd : cint): cint; [public, alias : 'FPC_SYSC_CLOSE'];
@@ -98,20 +102,32 @@ end;
 function Fpunlink(path: pchar): cint; [public, alias : 'FPC_SYSC_UNLINK'];
 function Fpunlink(path: pchar): cint; [public, alias : 'FPC_SYSC_UNLINK'];
 
 
 begin
 begin
+{$if defined(generic_linux_syscalls)}
+  Fpunlink:=do_syscall(syscall_nr_unlinkat,AT_FDCWD,TSysParam(path),0);
+{$else}
   Fpunlink:=do_syscall(syscall_nr_unlink,TSysParam(path));
   Fpunlink:=do_syscall(syscall_nr_unlink,TSysParam(path));
+{$endif}
 end;
 end;
 
 
 function Fprename(old : pchar; newpath: pchar): cint; [public, alias : 'FPC_SYSC_RENAME'];
 function Fprename(old : pchar; newpath: pchar): cint; [public, alias : 'FPC_SYSC_RENAME'];
 
 
 begin
 begin
+{$if defined(generic_linux_syscalls)}
+  Fprename:=do_syscall(syscall_nr_renameat,AT_FDCWD,TSysParam(old),AT_FDCWD,TSysParam(newpath));
+{$else}
   Fprename:=do_syscall(syscall_nr_rename,TSysParam(old),TSysParam(newpath));
   Fprename:=do_syscall(syscall_nr_rename,TSysParam(old),TSysParam(newpath));
+{$endif}
 end;
 end;
 
 
 function Fpstat(path: pchar; var buf: stat):cint; [public, alias : 'FPC_SYSC_STAT'];
 function Fpstat(path: pchar; var buf: stat):cint; [public, alias : 'FPC_SYSC_STAT'];
 
 
 begin
 begin
 {$if defined(cpu64)}
 {$if defined(cpu64)}
-  Fpstat:=do_syscall(syscall_nr_stat,TSysParam(path),TSysParam(@buf));
+  {$if defined(generic_linux_syscalls)}
+    Fpstat:=do_syscall(syscall_nr_fstatat,AT_FDCWD,TSysParam(path),TSysParam(@buf),0);
+  {$else}
+    Fpstat:=do_syscall(syscall_nr_stat,TSysParam(path),TSysParam(@buf));
+  {$endif}
 {$else}
 {$else}
   Fpstat:=do_syscall(syscall_nr_stat64,TSysParam(path),TSysParam(@buf));
   Fpstat:=do_syscall(syscall_nr_stat64,TSysParam(path),TSysParam(@buf));
 {$endif}
 {$endif}
@@ -130,13 +146,21 @@ end;
 function Fpmkdir(path : pchar; mode: mode_t):cint; [public, alias : 'FPC_SYSC_MKDIR'];
 function Fpmkdir(path : pchar; mode: mode_t):cint; [public, alias : 'FPC_SYSC_MKDIR'];
 
 
 begin
 begin
+{$if defined(generic_linux_syscalls)}
+  Fpmkdir:=do_syscall(syscall_nr_mkdirat,AT_FDCWD,TSysParam(path),TSysParam(mode));
+{$else}
   Fpmkdir:=do_syscall(syscall_nr_mkdir,TSysParam(path),TSysParam(mode));
   Fpmkdir:=do_syscall(syscall_nr_mkdir,TSysParam(path),TSysParam(mode));
+{$endif}
 end;
 end;
 
 
 function Fprmdir(path : pchar): cint;  [public, alias : 'FPC_SYSC_RMDIR'];
 function Fprmdir(path : pchar): cint;  [public, alias : 'FPC_SYSC_RMDIR'];
 
 
 begin
 begin
+{$if defined(generic_linux_syscalls)}
+ Fprmdir:=do_syscall(syscall_nr_unlinkat,AT_FDCWD,TSysParam(path),AT_REMOVEDIR);
+{$else}
  Fprmdir:=do_syscall(syscall_nr_rmdir,TSysParam(path));
  Fprmdir:=do_syscall(syscall_nr_rmdir,TSysParam(path));
+{$endif}
 end;
 end;
 
 
 function Fpopendir(dirname : pchar): pdir;  [public, alias : 'FPC_SYSC_OPENDIR'];
 function Fpopendir(dirname : pchar): pdir;  [public, alias : 'FPC_SYSC_OPENDIR'];
@@ -363,7 +387,11 @@ function Fpfstat(fd : cint; var sb : stat): cint;  [public, alias : 'FPC_SYSC_FS
 
 
 begin
 begin
 {$if defined(cpu64)}
 {$if defined(cpu64)}
-  FpFStat:=do_SysCall(syscall_nr_fstat,TSysParam(fd),TSysParam(@sb));
+  {$if defined(generic_linux_syscalls)}
+    FpFStat:=do_SysCall(syscall_nr_fstat,TSysParam(fd),TSysParam(@sb));
+  {$else}
+    FpFStat:=do_SysCall(syscall_nr_fstat,TSysParam(fd),TSysParam(@sb));
+  {$endif}
 {$else}
 {$else}
   FpFStat:=do_SysCall(syscall_nr_fstat64,TSysParam(fd),TSysParam(@sb));
   FpFStat:=do_SysCall(syscall_nr_fstat64,TSysParam(fd),TSysParam(@sb));
 {$endif}
 {$endif}
@@ -380,9 +408,14 @@ function Fpfork : pid_t;  [public, alias : 'FPC_SYSC_FORK'];
   A negative value indicates that an error has occurred, the error is returned in
   A negative value indicates that an error has occurred, the error is returned in
   LinuxError.
   LinuxError.
 }
 }
-
+var
+  pid : Int64;
 Begin
 Begin
+{$if defined(generic_linux_syscalls)}
+ Fpfork:=Do_syscall(syscall_nr_clone,clone_flags_fork,0,0,0,TSysParam(@pid));
+{$else}
  Fpfork:=Do_syscall(SysCall_nr_fork);
  Fpfork:=Do_syscall(SysCall_nr_fork);
+{$endif}
 End;
 End;
 {$endif FPC_SYSTEM_HAS_FPFORK}
 {$endif FPC_SYSTEM_HAS_FPFORK}
 
 
@@ -425,7 +458,7 @@ function Fpwaitpid(pid : pid_t; stat_loc : pcint; options: cint): pid_t; [public
 }
 }
 
 
 begin
 begin
-{$ifdef WAIT4}
+{$if defined(generic_linux_syscalls) or defined(WAIT4)}
  FpWaitPID:=do_syscall(syscall_nr_Wait4,PID,TSysParam(Stat_loc),options,0);
  FpWaitPID:=do_syscall(syscall_nr_Wait4,PID,TSysParam(Stat_loc),options,0);
 {$else WAIT4}
 {$else WAIT4}
  FpWaitPID:=do_syscall(syscall_nr_WaitPID,PID,TSysParam(Stat_loc),options);
  FpWaitPID:=do_syscall(syscall_nr_WaitPID,PID,TSysParam(Stat_loc),options);
@@ -447,7 +480,11 @@ function Fpaccess(pathname : pchar; amode : cint): cint; [public, alias : 'FPC_S
 }
 }
 
 
 begin
 begin
+{$if defined(generic_linux_syscalls)}
+ FpAccess:=do_syscall(syscall_nr_faccessat,AT_FDCWD,TSysParam(pathname),amode,0);
+{$else}
  FpAccess:=do_syscall(syscall_nr_access,TSysParam(pathname),amode);
  FpAccess:=do_syscall(syscall_nr_access,TSysParam(pathname),amode);
+{$endif}
 end;
 end;
 
 
 (* overloaded
 (* overloaded
@@ -481,7 +518,16 @@ end;
 Function FpDup2(fildes,fildes2:cint):cint; [public, alias : 'FPC_SYSC_DUP2'];
 Function FpDup2(fildes,fildes2:cint):cint; [public, alias : 'FPC_SYSC_DUP2'];
 
 
 begin
 begin
+{$if defined(generic_linux_syscalls)}
+ if fildes<>fildes2 then
+   Fpdup2:=do_syscall(syscall_nr_dup3,TSysParam(fildes),TSysParam(fildes2),0)
+ else if do_syscall(syscall_nr_fcntl,TSysParam(fildes),1)<>-1 then
+   Fpdup2:=fildes2
+ else
+   Fpdup2:=-1;
+{$else}
  Fpdup2:=do_syscall(syscall_nr_dup2,TSysParam(fildes),TSysParam(fildes2));
  Fpdup2:=do_syscall(syscall_nr_dup2,TSysParam(fildes),TSysParam(fildes2));
+{$endif}
 end;
 end;
 
 
 
 
@@ -572,7 +618,11 @@ end;
 Function FpReadLink(name,linkname:pchar;maxlen:size_t):cint;  [public, alias : 'FPC_SYSC_READLINK'];
 Function FpReadLink(name,linkname:pchar;maxlen:size_t):cint;  [public, alias : 'FPC_SYSC_READLINK'];
 
 
 begin
 begin
+{$if defined(generic_linux_syscalls)}
+  Fpreadlink:=do_syscall(syscall_nr_readlinkat,AT_FDCWD,TSysParam(name),TSysParam(linkname),maxlen);
+{$else}
   Fpreadlink:=do_syscall(syscall_nr_readlink, TSysParam(name),TSysParam(linkname),maxlen);
   Fpreadlink:=do_syscall(syscall_nr_readlink, TSysParam(name),TSysParam(linkname),maxlen);
+{$endif}
 end;
 end;
 
 
 
 

+ 6 - 1
rtl/linux/ostypes.inc

@@ -290,7 +290,12 @@ CONST
 {$endif not cpumips}
 {$endif not cpumips}
 {$endif not cpusparc}
 {$endif not cpusparc}
 
 
-{$if defined(cpuarm) or defined(cpualpha) or defined(cpublackfin) or defined(cpum68k)}
+    AT_FDCWD = -100;
+    AT_REMOVEDIR = $200;
+    clone_flags_fork = $01200011;
+      { SIGCHLD | CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID }
+
+{$if defined(cpuarm) or defined(cpualpha) or defined(cpublackfin) or defined(cpum68k) or defined(aarch64)}
     O_LARGEFILE =   $20000;
     O_LARGEFILE =   $20000;
 {$endif}
 {$endif}
 {$if defined(cpusparc) or defined(cpusparc64)}
 {$if defined(cpusparc) or defined(cpusparc64)}

+ 58 - 0
rtl/linux/pmutext.inc

@@ -0,0 +1,58 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 1999-2000 by Peter Vreman
+    member of the Free Pascal development team.
+
+    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.
+
+ **********************************************************************}
+
+{ definition of pthread_mutex_t, because needed in both ptypes.inc and }
+{ in sysosh.inc                                                        }
+
+{ use a macro rather than a constant, so this name doesn't get exported
+  from the system unit interface; macro's have to be on at this point
+  because they're use to propagate the MUTEXTYPENAME here }
+
+{$if defined(CPUMIPS) or defined(cpuaarch64)}
+{$define USE_PTHREAD_SIZEOF}
+
+{$if defined(cpuaarch64)}
+  {$define __SIZEOF_PTHREAD_MUTEX_T := 48}
+{$elseif defined(CPU64)}
+  {$define __SIZEOF_PTHREAD_MUTEX_T := 40}
+{$else CPU64}
+  {$define __SIZEOF_PTHREAD_MUTEX_T := 24}
+{$endif CPU64}
+
+{$endif MIPS}
+
+  MUTEXTYPENAME = record
+    case byte of
+{$ifdef USE_PTHREAD_SIZEOF}
+      0 : (
+        __size : array[0..__SIZEOF_PTHREAD_MUTEX_T-1] of char;
+        __align : sizeint;
+      );
+{$endif}
+      1 : (
+        __m_reserved: longint;
+        __m_count: longint;
+        __m_owner: pointer;
+        __m_kind:  longint;
+        __m_lock:  record
+           __status: sizeint;
+          __spinlock: longint;
+        end;
+       );
+  end;
+
+{$ifdef __SIZEOF_PTHREAD_MUTEX_T}
+{$undef __SIZEOF_PTHREAD_MUTEX_T}
+{$endif __SIZEOF_PTHREAD_MUTEX_T}
+{$macro off}

+ 18 - 23
rtl/linux/ptypes.inc

@@ -30,12 +30,21 @@ and all three 32-bit systems returned completely identical types too
 introduction)
 introduction)
 }
 }
 
 
-{$ifdef CPUMIPS}
+{$if defined(CPUMIPS) or defined(cpuaarch64)}
 {$define USE_PTHREAD_SIZEOF}
 {$define USE_PTHREAD_SIZEOF}
-{$ifdef CPU64}
+{$if defined(cpuaarch64)}
+const
+  __SIZEOF_PTHREAD_ATTR_T = 64;
+  __SIZEOF_PTHREAD_MUTEXATTR_T = 8;
+  __SIZEOF_PTHREAD_COND_T = 48;
+  __SIZEOF_PTHREAD_CONDATTR_T = 8;
+  __SIZEOF_PTHREAD_RWLOCK_T = 56;
+  __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
+  __SIZEOF_PTHREAD_BARRIER_T = 32;
+  __SIZEOF_PTHREAD_BARRIERATTR_T = 8;
+{$elseif defined(CPU64)}
 const
 const
   __SIZEOF_PTHREAD_ATTR_T = 56;
   __SIZEOF_PTHREAD_ATTR_T = 56;
-  __SIZEOF_PTHREAD_MUTEX_T = 40;
   __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
   __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
   __SIZEOF_PTHREAD_COND_T = 48;
   __SIZEOF_PTHREAD_COND_T = 48;
   __SIZEOF_PTHREAD_CONDATTR_T = 4;
   __SIZEOF_PTHREAD_CONDATTR_T = 4;
@@ -46,7 +55,6 @@ const
 {$else : not CPU64, i.e. CPU32}
 {$else : not CPU64, i.e. CPU32}
 const
 const
   __SIZEOF_PTHREAD_ATTR_T = 36;
   __SIZEOF_PTHREAD_ATTR_T = 36;
-  __SIZEOF_PTHREAD_MUTEX_T = 24;
   __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
   __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
   __SIZEOF_PTHREAD_COND_T = 48;
   __SIZEOF_PTHREAD_COND_T = 48;
   __SIZEOF_PTHREAD_CONDATTR_T = 4;
   __SIZEOF_PTHREAD_CONDATTR_T = 4;
@@ -55,7 +63,7 @@ const
   __SIZEOF_PTHREAD_BARRIER_T = 20;
   __SIZEOF_PTHREAD_BARRIER_T = 20;
   __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
   __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
 {$endif CPU32}
 {$endif CPU32}
-{$endif MIPS}
+{$endif}
 
 
 {$I ctypes.inc}
 {$I ctypes.inc}
 {$packrecords c}
 {$packrecords c}
@@ -256,24 +264,11 @@ Type
     __spinlock: cint;
     __spinlock: cint;
   end;
   end;
 
 
-  pthread_mutex_t = record
-  {$ifdef USE_PTHREAD_SIZEOF}
-  case byte of
-   0 : (
-    	 __size : array[0..__SIZEOF_PTHREAD_MUTEX_T-1] of char;
-    	 __align : clong;
-       );
-  1 : (
-  {$endif}    	
-    __m_reserved: cint;
-    __m_count: cint;
-    __m_owner: pointer;
-    __m_kind:  cint;
-    __m_lock: _pthread_fastlock;
-  {$ifdef USE_PTHREAD_SIZEOF}
-       );
-  {$endif}    	
-  end;
+{$macro on}
+{$define MUTEXTYPENAME := pthread_mutex_t}
+{$i pmutext.inc}
+{$undef MUTEXTYPENAME}
+{$macro off}
 
 
   pthread_mutexattr_t = record
   pthread_mutexattr_t = record
   {$ifdef USE_PTHREAD_SIZEOF}
   {$ifdef USE_PTHREAD_SIZEOF}

+ 277 - 0
rtl/linux/sysnr-gen.inc

@@ -0,0 +1,277 @@
+
+{
+  System call numbers taken from include/uapi/asm-generic/unistd.h
+  in a 4.0 Linux kernel. They are therefore architecture-independent,
+  though only the newest architectures use this generic list.
+}
+
+Const
+        syscall_nr_io_setup                     = 0;
+        syscall_nr_io_destroy                   = 1;
+        syscall_nr_io_submit                    = 2;
+        syscall_nr_io_cancel                    = 3;
+        syscall_nr_io_getevents                 = 4;
+        syscall_nr_setxattr                     = 5;
+        syscall_nr_lsetxattr                    = 6;
+        syscall_nr_fsetxattr                    = 7;
+        syscall_nr_getxattr                     = 8;
+        syscall_nr_lgetxattr                    = 9;
+        syscall_nr_fgetxattr                    = 10;
+        syscall_nr_listxattr                    = 11;
+        syscall_nr_llistxattr                   = 12;
+        syscall_nr_flistxattr                   = 13;
+        syscall_nr_removexattr                  = 14;
+        syscall_nr_lremovexattr                 = 15;
+        syscall_nr_fremovexattr                 = 16;
+        syscall_nr_getcwd                       = 17;
+        syscall_nr_lookup_dcookie               = 18;
+        syscall_nr_eventfd2                     = 19;
+        syscall_nr_epoll_create1                = 20;
+        syscall_nr_epoll_ctl                    = 21;
+        syscall_nr_epoll_pwait                  = 22;
+        syscall_nr_dup                          = 23;
+        syscall_nr_dup3                         = 24;
+        syscall_nr_fcntl                        = 25;
+        syscall_nr_inotify_init1                = 26;
+        syscall_nr_inotify_add_watch            = 27;
+        syscall_nr_inotify_rm_watch             = 28;
+        syscall_nr_ioctl                        = 29;
+        syscall_nr_ioprio_set                   = 30;
+        syscall_nr_ioprio_get                   = 31;
+        syscall_nr_flock                        = 32;
+        syscall_nr_mknodat                      = 33;
+        syscall_nr_mkdirat                      = 34;
+        syscall_nr_unlinkat                     = 35;
+        syscall_nr_symlinkat                    = 36;
+        syscall_nr_linkat                       = 37;
+        syscall_nr_renameat                     = 38;
+        syscall_nr_umount2                      = 39;
+        syscall_nr_mount                        = 40;
+        syscall_nr_pivot_root                   = 41;
+        syscall_nr_nfsservctl                   = 42;
+        syscall_nr_statfs                       = 43;
+        syscall_nr_fstatfs                      = 44;
+        syscall_nr_truncate                     = 45;
+        syscall_nr_ftruncate                    = 46;
+        syscall_nr_fallocate                    = 47;
+        syscall_nr_faccessat                    = 48;
+        syscall_nr_chdir                        = 49;
+        syscall_nr_fchdir                       = 50;
+        syscall_nr_chroot                       = 51;
+        syscall_nr_fchmod                       = 52;
+        syscall_nr_fchmodat                     = 53;
+        syscall_nr_fchownat                     = 54;
+        syscall_nr_fchown                       = 55;
+        syscall_nr_openat                       = 56;
+        syscall_nr_close                        = 57;
+        syscall_nr_vhangup                      = 58;
+        syscall_nr_pipe2                        = 59;
+        syscall_nr_quotactl                     = 60;
+        syscall_nr_getdents64                   = 61;
+        syscall_nr_lseek                        = 62;
+        syscall_nr_read                         = 63;
+        syscall_nr_write                        = 64;
+        syscall_nr_readv                        = 65;
+        syscall_nr_writev                       = 66;
+        syscall_nr_pread64                      = 67;
+        syscall_nr_pwrite64                     = 68;
+        syscall_nr_preadv                       = 69;
+        syscall_nr_pwritev                      = 70;
+        syscall_nr_sendfile                     = 71;
+        syscall_nr_pselect6                     = 72;
+        syscall_nr_ppoll                        = 73;
+        syscall_nr_signalfd4                    = 74;
+        syscall_nr_vmsplice                     = 75;
+        syscall_nr_splice                       = 76;
+        syscall_nr_tee                          = 77;
+        syscall_nr_readlinkat                   = 78;
+        syscall_nr_fstatat                      = 79;
+        syscall_nr_fstat                        = 80;
+        syscall_nr_sync                         = 81;
+        syscall_nr_fsync                        = 82;
+        syscall_nr_fdatasync                    = 83;
+        syscall_nr_sync_file_range              = 84;
+        syscall_nr_timerfd_create               = 85;
+        syscall_nr_timerfd_settime              = 86;
+        syscall_nr_timerfd_gettime              = 87;
+        syscall_nr_utimensat                    = 88;
+        syscall_nr_acct                         = 89;
+        syscall_nr_capget                       = 90;
+        syscall_nr_capset                       = 91;
+        syscall_nr_personality                  = 92;
+        syscall_nr_exit                         = 93;
+        syscall_nr_exit_group                   = 94;
+        syscall_nr_waitid                       = 95;
+        syscall_nr_set_tid_address              = 96;
+        syscall_nr_unshare                      = 97;
+        syscall_nr_futex                        = 98;
+        syscall_nr_set_robust_list              = 99;
+        syscall_nr_get_robust_list              = 100;
+        syscall_nr_nanosleep                    = 101;
+        syscall_nr_getitimer                    = 102;
+        syscall_nr_setitimer                    = 103;
+        syscall_nr_kexec_load                   = 104;
+        syscall_nr_init_module                  = 105;
+        syscall_nr_delete_module                = 106;
+        syscall_nr_timer_create                 = 107;
+        syscall_nr_timer_gettime                = 108;
+        syscall_nr_timer_getoverrun             = 109;
+        syscall_nr_timer_settime                = 110;
+        syscall_nr_timer_delete                 = 111;
+        syscall_nr_clock_settime                = 112;
+        syscall_nr_clock_gettime                = 113;
+        syscall_nr_clock_getres                 = 114;
+        syscall_nr_clock_nanosleep              = 115;
+        syscall_nr_syslog                       = 116;
+        syscall_nr_ptrace                       = 117;
+        syscall_nr_sched_setparam               = 118;
+        syscall_nr_sched_setscheduler           = 119;
+        syscall_nr_sched_getscheduler           = 120;
+        syscall_nr_sched_getparam               = 121;
+        syscall_nr_sched_setaffinity            = 122;
+        syscall_nr_sched_getaffinity            = 123;
+        syscall_nr_sched_yield                  = 124;
+        syscall_nr_sched_get_priority_max       = 125;
+        syscall_nr_sched_get_priority_min       = 126;
+        syscall_nr_sched_rr_get_interval        = 127;
+        syscall_nr_restart_syscall              = 128;
+        syscall_nr_kill                         = 129;
+        syscall_nr_tkill                        = 130;
+        syscall_nr_tgkill                       = 131;
+        syscall_nr_sigaltstack                  = 132;
+        syscall_nr_rt_sigsuspend                = 133;
+        syscall_nr_rt_sigaction                 = 134;
+        syscall_nr_rt_sigprocmask               = 135;
+        syscall_nr_rt_sigpending                = 136;
+        syscall_nr_rt_sigtimedwait              = 137;
+        syscall_nr_rt_sigqueueinfo              = 138;
+        syscall_nr_rt_sigreturn                 = 139;
+        syscall_nr_setpriority                  = 140;
+        syscall_nr_getpriority                  = 141;
+        syscall_nr_reboot                       = 142;
+        syscall_nr_setregid                     = 143;
+        syscall_nr_setgid                       = 144;
+        syscall_nr_setreuid                     = 145;
+        syscall_nr_setuid                       = 146;
+        syscall_nr_setresuid                    = 147;
+        syscall_nr_getresuid                    = 148;
+        syscall_nr_setresgid                    = 149;
+        syscall_nr_getresgid                    = 150;
+        syscall_nr_setfsuid                     = 151;
+        syscall_nr_setfsgid                     = 152;
+        syscall_nr_times                        = 153;
+        syscall_nr_setpgid                      = 154;
+        syscall_nr_getpgid                      = 155;
+        syscall_nr_getsid                       = 156;
+        syscall_nr_setsid                       = 157;
+        syscall_nr_getgroups                    = 158;
+        syscall_nr_setgroups                    = 159;
+        syscall_nr_uname                        = 160;
+        syscall_nr_sethostname                  = 161;
+        syscall_nr_setdomainname                = 162;
+        syscall_nr_getrlimit                    = 163;
+        syscall_nr_setrlimit                    = 164;
+        syscall_nr_getrusage                    = 165;
+        syscall_nr_umask                        = 166;
+        syscall_nr_prctl                        = 167;
+        syscall_nr_getcpu                       = 168;
+        syscall_nr_gettimeofday                 = 169;
+        syscall_nr_settimeofday                 = 170;
+        syscall_nr_adjtimex                     = 171;
+        syscall_nr_getpid                       = 172;
+        syscall_nr_getppid                      = 173;
+        syscall_nr_getuid                       = 174;
+        syscall_nr_geteuid                      = 175;
+        syscall_nr_getgid                       = 176;
+        syscall_nr_getegid                      = 177;
+        syscall_nr_gettid                       = 178;
+        syscall_nr_sysinfo                      = 179;
+        syscall_nr_mq_open                      = 180;
+        syscall_nr_mq_unlink                    = 181;
+        syscall_nr_mq_timedsend                 = 182;
+        syscall_nr_mq_timedreceive              = 183;
+        syscall_nr_mq_notify                    = 184;
+        syscall_nr_mq_getsetattr                = 185;
+        syscall_nr_msgget                       = 186;
+        syscall_nr_msgctl                       = 187;
+        syscall_nr_msgrcv                       = 188;
+        syscall_nr_msgsnd                       = 189;
+        syscall_nr_semget                       = 190;
+        syscall_nr_semctl                       = 191;
+        syscall_nr_semtimedop                   = 192;
+        syscall_nr_semop                        = 193;
+        syscall_nr_shmget                       = 194;
+        syscall_nr_shmctl                       = 195;
+        syscall_nr_shmat                        = 196;
+        syscall_nr_shmdt                        = 197;
+        syscall_nr_socket                       = 198;
+        syscall_nr_socketpair                   = 199;
+        syscall_nr_bind                         = 200;
+        syscall_nr_listen                       = 201;
+        syscall_nr_accept                       = 202;
+        syscall_nr_connect                      = 203;
+        syscall_nr_getsockname                  = 204;
+        syscall_nr_getpeername                  = 205;
+        syscall_nr_sendto                       = 206;
+        syscall_nr_recvfrom                     = 207;
+        syscall_nr_setsockopt                   = 208;
+        syscall_nr_getsockopt                   = 209;
+        syscall_nr_shutdown                     = 210;
+        syscall_nr_sendmsg                      = 211;
+        syscall_nr_recvmsg                      = 212;
+        syscall_nr_readahead                    = 213;
+        syscall_nr_brk                          = 214;
+        syscall_nr_munmap                       = 215;
+        syscall_nr_mremap                       = 216;
+        syscall_nr_add_key                      = 217;
+        syscall_nr_request_key                  = 218;
+        syscall_nr_keyctl                       = 219;
+        syscall_nr_clone                        = 220;
+        syscall_nr_execve                       = 221;
+        syscall_nr_mmap                         = 222;
+        syscall_nr_fadvise64                    = 223;
+        syscall_nr_swapon                       = 224;
+        syscall_nr_swapoff                      = 225;
+        syscall_nr_mprotect                     = 226;
+        syscall_nr_msync                        = 227;
+        syscall_nr_mlock                        = 228;
+        syscall_nr_munlock                      = 229;
+        syscall_nr_mlockall                     = 230;
+        syscall_nr_munlockall                   = 231;
+        syscall_nr_mincore                      = 232;
+        syscall_nr_madvise                      = 233;
+        syscall_nr_remap_file_pages             = 234;
+        syscall_nr_mbind                        = 235;
+        syscall_nr_get_mempolicy                = 236;
+        syscall_nr_set_mempolicy                = 237;
+        syscall_nr_migrate_pages                = 238;
+        syscall_nr_move_pages                   = 239;
+        syscall_nr_rt_tgsigqueueinfo            = 240;
+        syscall_nr_perf_event_open              = 241;
+        syscall_nr_accept4                      = 242;
+        syscall_nr_recvmmsg                     = 243;
+        syscall_nr_arch_specific_syscall        = 244;
+
+        syscall_nr_wait4                        = 260;
+        syscall_nr_prlimit64                    = 261;
+        syscall_nr_fanotify_init                = 262;
+        syscall_nr_fanotify_mark                = 263;
+        syscall_nr_name_to_handle_at            = 264;
+        syscall_nr_open_by_handle_at            = 265;
+        syscall_nr_clock_adjtime                = 266;
+        syscall_nr_syncfs                       = 267;
+        syscall_nr_setns                        = 268;
+        syscall_nr_sendmmsg                     = 269;
+        syscall_nr_process_vm_readv             = 270;
+        syscall_nr_process_vm_writev            = 271;
+        syscall_nr_kcmp                         = 272;
+        syscall_nr_finit_module                 = 273;
+        syscall_nr_sched_setattr                = 274;
+        syscall_nr_sched_getattr                = 275;
+        syscall_nr_renameat2                    = 276;
+        syscall_nr_seccomp                      = 277;
+        syscall_nr_getrandom                    = 278;
+        syscall_nr_memfd_create                 = 279;
+        syscall_nr_bpf                          = 280;
+        syscall_nr_execveat                     = 281;
+        syscall_nr_syscalls                     = 282;

+ 5 - 11
rtl/linux/sysosh.inc

@@ -23,18 +23,12 @@ type
   { pthread_t is defined as an "unsigned long" }
   { pthread_t is defined as an "unsigned long" }
   TThreadID = PtrUInt;
   TThreadID = PtrUInt;
 
 
-  { pthread_mutex_t }
   PRTLCriticalSection = ^TRTLCriticalSection;
   PRTLCriticalSection = ^TRTLCriticalSection;
-  TRTLCriticalSection = record
-    __m_reserved: longint;
-    __m_count: longint;
-    __m_owner: pointer;
-    __m_kind:  longint;
-    __m_lock:  record
-       __status: sizeint;
-      __spinlock: longint;
-    end;
-  end;
+{$macro on}
+{$define MUTEXTYPENAME := TRTLCriticalSection}
+{$i pmutext.inc}
+{$undef MUTEXTYPENAME}
+{$macro off}
 
 
 
 
 
 

+ 265 - 0
rtl/linux/termios.inc

@@ -22,6 +22,271 @@ Const
   NCCS = 32;
   NCCS = 32;
   NCC = 8;
   NCC = 8;
 
 
+{$ifdef cpuaarch64}
+
+{ from Linux 4.0, include/uapi/asm-generic/ioctls.h }
+
+  { For Terminal handling }
+  TCGETS          = $5401;
+  TCSETS          = $5402;
+  TCSETSW         = $5403;
+  TCSETSF         = $5404;
+  TCGETA          = $5405;
+  TCSETA          = $5406;
+  TCSETAW         = $5407;
+  TCSETAF         = $5408;
+  TCSBRK          = $5409;
+  TCXONC          = $540A;
+  TCFLSH          = $540B;
+  TIOCEXCL        = $540C;
+  TIOCNXCL        = $540D;
+  TIOCSCTTY       = $540E;
+  TIOCGPGRP       = $540F;
+  TIOCSPGRP       = $5410;
+  TIOCOUTQ        = $5411;
+  TIOCSTI         = $5412;
+  TIOCGWINSZ      = $5413;
+  TIOCSWINSZ      = $5414;
+  TIOCMGET        = $5415;
+  TIOCMBIS        = $5416;
+  TIOCMBIC        = $5417;
+  TIOCMSET        = $5418;
+  TIOCGSOFTCAR    = $5419;
+  TIOCSSOFTCAR    = $541A;
+  FIONREAD        = $541B;
+  TIOCINQ         = FIONREAD;
+  TIOCLINUX       = $541C;
+  TIOCCONS        = $541D;
+  TIOCGSERIAL     = $541E;
+  TIOCSSERIAL     = $541F;
+  TIOCPKT         = $5420;
+  FIONBIO         = $5421;
+  TIOCNOTTY       = $5422;
+  TIOCSETD        = $5423;
+  TIOCGETD        = $5424;
+  TCSBRKP         = $5425;
+
+  TIOCSBRK        = $5427;
+  TIOCCBRK        = $5428;
+  TIOCGSID        = $5429;
+
+  TIOCGRS485      = $542E;
+  TIOCSRS485      = $542F;
+
+  TCGETX          = $5432;
+  TCSETX          = $5433;
+  TCSETXF         = $5434;
+  TCSETXW         = $5435;
+  TIOCVHANGUP     = $5437;
+
+  FIONCLEX        = $5450;
+  FIOCLEX         = $5451;
+  FIOASYNC        = $5452;
+  TIOCSERCONFIG   = $5453;
+  TIOCSERGWILD    = $5454;
+  TIOCSERSWILD    = $5455;
+  TIOCGLCKTRMIOS  = $5456;
+  TIOCSLCKTRMIOS  = $5457;
+  TIOCSERGSTRUCT  = $5458;
+  TIOCSERGETLSR   = $5459;
+  TIOCSERGETMULTI = $545A;
+  TIOCSERSETMULTI = $545B;
+  TIOCMIWAIT      = $545C;
+  TIOCGICOUNT     = $545D;
+
+  FIOQSIZE        = $5460;
+
+  TIOCPKT_DATA       = 0;
+  TIOCPKT_FLUSHREAD  = 1;
+  TIOCPKT_FLUSHWRITE = 2;
+  TIOCPKT_STOP       = 4;
+  TIOCPKT_START      = 8;
+  TIOCPKT_NOSTOP     = 16;
+  TIOCPKT_DOSTOP     = 32;
+  TIOCPKT_IOCTL      = 64;
+
+  TIOCSER_TEMT       = $01;
+
+{ from Linux 4.0, include/uapi/asm-generic/termbits.h }
+
+  { c_cc characters }
+  VINTR    = 0;
+  VQUIT    = 1;
+  VERASE   = 2;
+  VKILL    = 3;
+  VEOF     = 4;
+  VTIME    = 5;
+  VMIN     = 6;
+  VSWTC    = 7;
+  VSTART   = 8;
+  VSTOP    = 9;
+  VSUSP    = 10;
+  VEOL     = 11;
+  VREPRINT = 12;
+  VDISCARD = 13;
+  VWERASE  = 14;
+  VLNEXT   = 15;
+  VEOL2    = 16;
+
+  { c_iflag bits }
+  IGNBRK  = &0000001;
+  BRKINT  = &0000002;
+  IGNPAR  = &0000004;
+  PARMRK  = &0000010;
+  INPCK   = &0000020;
+  ISTRIP  = &0000040;
+  INLCR   = &0000100;
+  IGNCR   = &0000200;
+  ICRNL   = &0000400;
+  IUCLC   = &0001000;
+  IXON    = &0002000;
+  IXANY   = &0004000;
+  IXOFF   = &0010000;
+  IMAXBEL = &0020000;
+  IUTF8   = &0040000;
+
+  { c_oflag bits }
+  OPOST  = &0000001;
+  OLCUC  = &0000002;
+  ONLCR  = &0000004;
+  OCRNL  = &0000010;
+  ONOCR  = &0000020;
+  ONLRET = &0000040;
+  OFILL  = &0000100;
+  OFDEL  = &0000200;
+  NLDLY  = &0000400;
+  NL0    = &0000000;
+  NL1    = &0000400;
+  CRDLY  = &0003000;
+  CR0    = &0000000;
+  CR1    = &0001000;
+  CR2    = &0002000;
+  CR3    = &0003000;
+  TABDLY = &0014000;
+  TAB0   = &0000000;
+  TAB1   = &0004000;
+  TAB2   = &0010000;
+  TAB3   = &0014000;
+  XTABS  = &0014000;
+  BSDLY  = &0020000;
+  BS0    = &0000000;
+  BS1    = &0020000;
+  VTDLY  = &0040000;
+  VT0    = &0000000;
+  VT1    = &0040000;
+  FFDLY  = &0100000;
+  FF0    = &0000000;
+  FF1    = &0100000;
+
+  { c_cflag bits }
+  CBAUD    = &0010017;
+  B0       = &0000000;
+  B50      = &0000001;
+  B75      = &0000002;
+  B110     = &0000003;
+  B134     = &0000004;
+  B150     = &0000005;
+  B200     = &0000006;
+  B300     = &0000007;
+  B600     = &0000010;
+  B1200    = &0000011;
+  B1800    = &0000012;
+  B2400    = &0000013;
+  B4800    = &0000014;
+  B9600    = &0000015;
+  B19200   = &0000016;
+  B38400   = &0000017;
+  EXTA     = B19200;
+  EXTB     = B38400;
+  CSIZE    = &0000060;
+  CS5      = &0000000;
+  CS6      = &0000020;
+  CS7      = &0000040;
+  CS8      = &0000060;
+  CSTOPB   = &0000100;
+  CREAD    = &0000200;
+  PARENB   = &0000400;
+  PARODD   = &0001000;
+  HUPCL    = &0002000;
+  CLOCAL   = &0004000;
+  CBAUDEX  = &0010000;
+  BOTHER   = &0010000;
+  B57600   = &0010001;
+  B115200  = &0010002;
+  B230400  = &0010003;
+  B460800  = &0010004;
+  B500000  = &0010005;
+  B576000  = &0010006;
+  B921600  = &0010007;
+  B1000000 = &0010010;
+  B1152000 = &0010011;
+  B1500000 = &0010012;
+  B2000000 = &0010013;
+  B2500000 = &0010014;
+  B3000000 = &0010015;
+  B3500000 = &0010016;
+  B4000000 = &0010017;
+
+  CIBAUD   = &002003600000;
+  CMSPAR   = &010000000000;
+  CRTSCTS  = &020000000000;
+
+  IBSHIFT  = 16;
+
+  { c_lflag bits }
+  ISIG    = &0000001;
+  ICANON  = &0000002;
+  XCASE   = &0000004;
+  ECHO    = &0000010;
+  ECHOE   = &0000020;
+  ECHOK   = &0000040;
+  ECHONL  = &0000100;
+  NOFLSH  = &0000200;
+  TOSTOP  = &0000400;
+  ECHOCTL = &0001000;
+  ECHOPRT = &0002000;
+  ECHOKE  = &0004000;
+  FLUSHO  = &0010000;
+  PENDIN  = &0040000;
+  IEXTEN  = &0100000;
+  EXTPROC = &0200000;
+
+  { TCFlow }
+  TCOOFF = 0;
+  TCOON  = 1;
+  TCIOFF = 2;
+  TCION  = 3;
+
+  { TCFlush }
+  TCIFLUSH  = 0;
+  TCOFLUSH  = 1;
+  TCIOFLUSH = 2;
+
+  { TCSetAttr }
+  TCSANOW   = 0;
+  TCSADRAIN = 1;
+  TCSAFLUSH = 2;
+
+{ from Linux 4.0, include/uapi/asm-generic/termios.h }
+
+  { c_line bits }
+  TIOCM_LE   = $001;
+  TIOCM_DTR  = $002;
+  TIOCM_RTS  = $004;
+  TIOCM_ST   = $008;
+  TIOCM_SR   = $010;
+  TIOCM_CTS  = $020;
+  TIOCM_CAR  = $040;
+  TIOCM_RNG  = $080;
+  TIOCM_DSR  = $100;
+  TIOCM_CD   = TIOCM_CAR;
+  TIOCM_RI   = TIOCM_RNG;
+  TIOCM_OUT1 = $2000;
+  TIOCM_OUT2 = $4000;
+  TIOCM_LOOP = $8000;
+
+{$endif cpuaarch64}
+
 {$ifdef cpupowerpc}
 {$ifdef cpupowerpc}
   TCGETS            = $402c7413;
   TCGETS            = $402c7413;
   TCSETS            = $802c7414;
   TCSETS            = $802c7414;

+ 8 - 0
tests/webtbs/tw11563.pp

@@ -9,6 +9,9 @@ program ExecStack;
 {$if defined(cpupowerpc) or defined(cpupowerpc64)}
 {$if defined(cpupowerpc) or defined(cpupowerpc64)}
     ret: longint;
     ret: longint;
 {$endif}
 {$endif}
+{$if defined(cpuaarch64)}
+    ret: longint;
+{$endif}
 {$if defined(cpui386) or defined(cpux86_64)}
 {$if defined(cpui386) or defined(cpux86_64)}
     ret: Byte;
     ret: Byte;
 {$endif}
 {$endif}
@@ -40,6 +43,11 @@ program ExecStack;
     DoNothing;
     DoNothing;
 {$endif}
 {$endif}
 {$endif}
 {$endif}
+{$if defined(cpuaarch64)}
+    ret := $d65f03c0;
+    DoNothing := proc(@ret);
+    DoNothing;
+{$endif}
 {$if defined(cpui386) or defined(cpux86_64)}
 {$if defined(cpui386) or defined(cpux86_64)}
     ret := $C3;
     ret := $C3;
     DoNothing := proc(@ret);
     DoNothing := proc(@ret);

+ 1 - 1
utils/fpcm/fpcmmain.pp

@@ -114,7 +114,7 @@ interface
       { This table is kept OS,Cpu because it is easier to maintain (PFV) }
       { This table is kept OS,Cpu because it is easier to maintain (PFV) }
       OSCpuPossible : array[TOS,TCpu] of boolean = (
       OSCpuPossible : array[TOS,TCpu] of boolean = (
         { os          i386    m68k  ppc    sparc  x86_64 arm    ppc64  avr    armeb  armel  mips   mipsel mips64 misp64el jvm    i8086  aarch64}
         { os          i386    m68k  ppc    sparc  x86_64 arm    ppc64  avr    armeb  armel  mips   mipsel mips64 misp64el jvm    i8086  aarch64}
-        { linux }   ( true,  true,  true,  true,  true,  true,  true,  false, true,  false, true,  true,  false, false,   false, false, false),
+        { linux }   ( true,  true,  true,  true,  true,  true,  true,  false, true,  false, true,  true,  false, false,   false, false, true ),
         { go32v2 }  ( true,  false, false, false, false, false, false, false, false, false, false, false, false, false,   false, false, false),
         { go32v2 }  ( true,  false, false, false, false, false, false, false, false, false, false, false, false, false,   false, false, false),
         { win32 }   ( true,  false, false, false, false, false, false, false, false, false, false, false, false, false,   false, false, false),
         { win32 }   ( true,  false, false, false, false, false, false, false, false, false, false, false, false, false,   false, false, false),
         { os2 }     ( true,  false, false, false, false, false, false, false, false, false, false, false, false, false,   false, false, false),
         { os2 }     ( true,  false, false, false, false, false, false, false, false, false, false, false, false, false,   false, false, false),

+ 1 - 1
utils/fpcm/revision.inc

@@ -1 +1 @@
-'2015-01-05 rev 29416'
+'2015-05-31 rev 30962'

+ 1 - 0
utils/fpcres/fpcres.pas

@@ -252,6 +252,7 @@ begin
     mtia64 : Result.MachineType:=emtia64;
     mtia64 : Result.MachineType:=emtia64;
     mtmips : Result.MachineType:=emtmips;
     mtmips : Result.MachineType:=emtmips;
     mtmipsel : Result.MachineType:=emtmipsel;
     mtmipsel : Result.MachineType:=emtmipsel;
+    mtaarch64 : Result.MachineType:=emtaarch64;
   end;
   end;
 end;
 end;
 
 

+ 2 - 2
utils/fpcres/target.pas

@@ -83,7 +83,7 @@ var
     (name : 'ia64';         formats : [ofElf]),                   //mtia64
     (name : 'ia64';         formats : [ofElf]),                   //mtia64
     (name : 'mips';         formats : [ofElf]; alias : 'mipseb'), //mtmips
     (name : 'mips';         formats : [ofElf]; alias : 'mipseb'), //mtmips
     (name : 'mipsel';       formats : [ofElf]),                   //mtmipsel
     (name : 'mipsel';       formats : [ofElf]),                   //mtmipsel
-    (name : 'aarch64';      formats : [ofMachO]),                 //mtaarch64
+    (name : 'aarch64';      formats : [ofElf, ofMachO]),          //mtaarch64
     (name : 'bigendian';    formats : [ofExt]),                   //mtBigEndian
     (name : 'bigendian';    formats : [ofExt]),                   //mtBigEndian
     (name : 'littleendian'; formats : [ofExt])                    //mtLittleEndian
     (name : 'littleendian'; formats : [ofExt])                    //mtLittleEndian
   );
   );
@@ -100,7 +100,7 @@ var
     (name : 'elf';      ext : '.or';     machines : [mti386,mtx86_64,mtppc,
     (name : 'elf';      ext : '.or';     machines : [mti386,mtx86_64,mtppc,
                                                      mtppc64,mtarm,mtarmeb,
                                                      mtppc64,mtarm,mtarmeb,
                                                      mtm68k,mtsparc,mtalpha,
                                                      mtm68k,mtsparc,mtalpha,
-                                                     mtia64,mtmips,mtmipsel]),
+                                                     mtaarch64]),
     (name : 'coff';     ext : '.o';      machines : [mti386,mtx86_64,mtarm,
     (name : 'coff';     ext : '.o';      machines : [mti386,mtx86_64,mtarm,
                                                      mtppc,mtppc64]),
                                                      mtppc,mtppc64]),
     (name : 'xcoff';    ext : '.o';      machines : [mtppc{,mtppc64}]),
     (name : 'xcoff';    ext : '.o';      machines : [mtppc{,mtppc64}]),