Browse Source

+ support for generating non-pic darwin/arm call stubs
+ write the header for non-pic darwin/arm call stubs properly in aggas
* r9 is not available for general use on darwin/arm according to the llvm
code generator

git-svn-id: trunk@11862 -

Jonas Maebe 17 năm trước cách đây
mục cha
commit
5347e536c2
2 tập tin đã thay đổi với 61 bổ sung6 xóa
  1. 5 2
      compiler/aggas.pas
  2. 56 4
      compiler/arm/cgcpu.pas

+ 5 - 2
compiler/aggas.pas

@@ -390,9 +390,12 @@ implementation
                     AsmWriteln('__TEXT,__symbol_stub1,symbol_stubs,pure_instructions,16');
                 system_i386_darwin:
                   AsmWriteln('__IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5');
-                { darwin/x86-64 uses RIP-based GOT addressing }
                 system_arm_darwin:
-                  AsmWriteln('.section __TEXT,__picsymbolstub4,symbol_stubs,none,16');
+                  if (cs_create_pic in current_settings.moduleswitches) then
+                    AsmWriteln('.section __TEXT,__picsymbolstub4,symbol_stubs,none,16')
+                  else
+                    AsmWriteln('.section __TEXT,__symbol_stub4,symbol_stubs,none,12')
+                { darwin/x86-64 uses RIP-based GOT addressing, no symbol stubs }
                 else
                   internalerror(2006031101);
               end;

+ 56 - 4
compiler/arm/cgcpu.pas

@@ -112,6 +112,7 @@ unit cgcpu;
         { clear out potential overflow bits from 8 or 16 bit operations  }
         { the upper 24/16 bits of a register after an operation          }
         procedure maybeadjustresult(list: TAsmList; op: TOpCg; size: tcgsize; dst: tregister);
+        function get_darwin_call_stub(const s: string): tasmsymbol;
       end;
 
       tcg64farm = class(tcg64f32)
@@ -167,9 +168,15 @@ unit cgcpu;
       begin
         inherited init_register_allocators;
         { currently, we save R14 always, so we can use it }
-        rg[R_INTREGISTER]:=trgintcpu.create(R_INTREGISTER,R_SUBWHOLE,
-            [RS_R0,RS_R1,RS_R2,RS_R3,RS_R4,RS_R5,RS_R6,RS_R7,RS_R8,
-             RS_R9,RS_R10,RS_R12,RS_R14],first_int_imreg,[]);
+        if (target_info.system<>system_arm_darwin) then
+          rg[R_INTREGISTER]:=trgintcpu.create(R_INTREGISTER,R_SUBWHOLE,
+              [RS_R0,RS_R1,RS_R2,RS_R3,RS_R4,RS_R5,RS_R6,RS_R7,RS_R8,
+               RS_R9,RS_R10,RS_R12,RS_R14],first_int_imreg,[])
+        else
+          { r9 is not available on Darwin according to the llvm code generator }
+          rg[R_INTREGISTER]:=trgintcpu.create(R_INTREGISTER,R_SUBWHOLE,
+              [RS_R0,RS_R1,RS_R2,RS_R3,RS_R4,RS_R5,RS_R6,RS_R7,RS_R8,
+               RS_R10,RS_R12,RS_R14],first_int_imreg,[]);
         rg[R_FPUREGISTER]:=trgcpu.create(R_FPUREGISTER,R_SUBNONE,
             [RS_F0,RS_F1,RS_F2,RS_F3,RS_F4,RS_F5,RS_F6,RS_F7],first_fpu_imreg,[]);
         rg[R_MMREGISTER]:=trgcpu.create(R_MMREGISTER,R_SUBNONE,
@@ -281,7 +288,10 @@ unit cgcpu;
 
     procedure tcgarm.a_call_name(list : TAsmList;const s : string);
       begin
-        list.concat(taicpu.op_sym(A_BL,current_asmdata.RefAsmSymbol(s)));
+        if target_info.system<>system_arm_darwin then
+          list.concat(taicpu.op_sym(A_BL,current_asmdata.RefAsmSymbol(s)))
+        else
+          list.concat(taicpu.op_sym(A_BL,get_darwin_call_stub(s)));
 {
         the compiler does not properly set this flag anymore in pass 1, and
         for now we only need it after pass 2 (I hope) (JM)
@@ -2100,6 +2110,48 @@ unit cgcpu;
       end;
 
 
+    function tcgarm.get_darwin_call_stub(const s: string): tasmsymbol;
+      var
+        stubname: string;
+        l1: tasmsymbol;
+        href: treference;
+      begin
+        stubname := 'L'+s+'$stub';
+        result := current_asmdata.getasmsymbol(stubname);
+        if assigned(result) then
+          exit;
+
+        if current_asmdata.asmlists[al_imports]=nil then
+          current_asmdata.asmlists[al_imports]:=TAsmList.create;
+
+        current_asmdata.asmlists[al_imports].concat(Tai_section.create(sec_stub,'',0));
+        current_asmdata.asmlists[al_imports].concat(Tai_align.Create(4));
+        result := current_asmdata.RefAsmSymbol(stubname);
+        current_asmdata.asmlists[al_imports].concat(Tai_symbol.Create(result,0));
+        current_asmdata.asmlists[al_imports].concat(tai_directive.create(asd_indirect_symbol,s));
+        
+        if not(cs_create_pic in current_settings.moduleswitches) then
+          begin
+            l1 := current_asmdata.RefAsmSymbol('L'+s+'$slp');
+            reference_reset_symbol(href,l1,0);
+            href.refaddr:=addr_full;
+            current_asmdata.asmlists[al_imports].concat(taicpu.op_reg_ref(A_LDR,NR_R12,href));
+            reference_reset_base(href,NR_R12,0);
+            current_asmdata.asmlists[al_imports].concat(taicpu.op_reg_ref(A_LDR,NR_R15,href));
+            current_asmdata.asmlists[al_imports].concat(Tai_symbol.Create(l1,0));
+            l1 := current_asmdata.RefAsmSymbol('L'+s+'$lazy_ptr');
+            current_asmdata.asmlists[al_imports].concat(tai_const.create_sym(l1));
+          end
+        else
+          internalerror(2008100401);
+        
+        current_asmdata.asmlists[al_imports].concat(tai_directive.create(asd_lazy_symbol_pointer,''));
+        current_asmdata.asmlists[al_imports].concat(Tai_symbol.Create(l1,0));
+        current_asmdata.asmlists[al_imports].concat(tai_directive.create(asd_indirect_symbol,s));
+        current_asmdata.asmlists[al_imports].concat(tai_const.createname('dyld_stub_binding_helper',0));
+      end;
+
+
     procedure tcg64farm.a_op64_reg_reg(list : TAsmList;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64);
       begin
         case op of