فهرست منبع

* fixed GOT loading for i386 in stubs for external procedures whose external
name is (re)defined in the implementation (mantis #14221)

git-svn-id: trunk@13469 -

Jonas Maebe 16 سال پیش
والد
کامیت
f265fbe343
5فایلهای تغییر یافته به همراه37 افزوده شده و 14 حذف شده
  1. 3 2
      compiler/cgobj.pas
  2. 10 5
      compiler/i386/cgcpu.pas
  3. 7 3
      compiler/ppcgen/cgppc.pas
  4. 1 1
      compiler/psub.pas
  5. 16 3
      compiler/x86/cgx86.pas

+ 3 - 2
compiler/cgobj.pas

@@ -484,7 +484,7 @@ unit cgobj;
           procedure g_external_wrapper(list : TAsmList; procdef: tprocdef; const externalname: string); virtual;
 
           { initialize the pic/got register }
-          procedure g_maybe_got_init(list: TAsmList); virtual;
+          function g_maybe_got_init(list: TAsmList; force: boolean): tregister; virtual;
         protected
           procedure get_subsetref_load_info(const sref: tsubsetreference; out loadsize: tcgsize; out extra_load: boolean);
           procedure a_load_subsetref_regs_noindex(list: TAsmList; subsetsize: tcgsize; loadbitsize: byte; const sref: tsubsetreference; valuereg, extra_value_reg: tregister); virtual;
@@ -3832,8 +3832,9 @@ implementation
         end;
 
 
-    procedure tcg.g_maybe_got_init(list: TAsmList);
+    function tcg.g_maybe_got_init(list: TAsmList; force: boolean): tregister;
       begin
+        result:=NR_NO;
       end;
 
 

+ 10 - 5
compiler/i386/cgcpu.pas

@@ -52,7 +52,7 @@ unit cgcpu;
         procedure g_exception_reason_save_const(list : TAsmList; const href : treference; a: aint);override;
         procedure g_exception_reason_load(list : TAsmList; const href : treference);override;
         procedure g_intf_wrapper(list: TAsmList; procdef: tprocdef; const labelname: string; ioffset: longint);override;
-        procedure g_maybe_got_init(list: TAsmList); override;
+        function g_maybe_got_init(list: TAsmList; force: boolean): tregister; override;
      end;
 
       tcg64f386 = class(tcg64f32)
@@ -494,12 +494,13 @@ unit cgcpu;
       end;
 
 
-    procedure tcg386.g_maybe_got_init(list: TAsmList);
+    function tcg386.g_maybe_got_init(list: TAsmList; force: boolean): tregister;
       begin
         { allocate PIC register }
         if (cs_create_pic in current_settings.moduleswitches) and
            (tf_pic_uses_got in target_info.flags) and
-           (pi_needs_got in current_procinfo.flags) then
+           (force or
+            (pi_needs_got in current_procinfo.flags)) then
           begin
             if (target_info.system<>system_i386_darwin) then
               begin
@@ -507,11 +508,14 @@ unit cgcpu;
                 cg.a_call_name_static(list,'fpc_geteipasebx');
                 list.concat(taicpu.op_sym_ofs_reg(A_ADD,S_L,current_asmdata.RefAsmSymbol('_GLOBAL_OFFSET_TABLE_'),0,NR_PIC_OFFSET_REG));
                 list.concat(tai_regalloc.alloc(NR_PIC_OFFSET_REG,nil));
-                { ecx could be used in leaf procedures }
-                current_procinfo.got:=NR_EBX;
+                { ecx could be used for a parameter register }
+                result:=NR_EBX;
               end
             else
               begin
+                { is not called for darwin/i386 for external stubs }
+                if not assigned(current_procinfo) then
+                  internalerror(2009072801);
                 { can't use ecx, since that one may overwrite a parameter }
                 current_module.requires_ebx_pic_helper:=true;
                 cg.a_call_name_static(list,'fpc_geteipasebx');
@@ -520,6 +524,7 @@ unit cgcpu;
                 { got is already set by ti386procinfo.allocate_got_register }
                 list.concat(tai_regalloc.dealloc(NR_EBX,nil));
                 a_load_reg_reg(list,OS_ADDR,OS_ADDR,NR_EBX,current_procinfo.got);
+                result:=current_procinfo.got;
               end;
           end;
       end;

+ 7 - 3
compiler/ppcgen/cgppc.pas

@@ -62,7 +62,7 @@ unit cgppc;
 
         procedure g_intf_wrapper(list: TAsmList; procdef: tprocdef; const labelname: string; ioffset: longint);override;
 
-        procedure g_maybe_got_init(list: TAsmList); override;
+        function  g_maybe_got_init(list: TAsmList; force: boolean): tregister; override;
        protected
         function  get_darwin_call_stub(const s: string; weak: boolean): tasmsymbol;
         procedure a_load_subsetref_regs_noindex(list: TAsmList; subsetsize: tcgsize; loadbitsize: byte; const sref: tsubsetreference; valuereg, extra_value_reg: tregister); override;
@@ -204,16 +204,19 @@ unit cgppc;
       end;
 
 
-    procedure tcgppcgen.g_maybe_got_init(list: TAsmList);
+    function tcgppcgen.g_maybe_got_init(list: TAsmList; force: boolean): tregister;
       var
          instr: taicpu;
          cond: tasmcond;
         savedlr: boolean;
       begin
+        if not assigned(current_procinfo) then
+          internalerror(2009072802);
         if not(po_assembler in current_procinfo.procdef.procoptions) then
           begin
             if (cs_create_pic in current_settings.moduleswitches) and
-               (pi_needs_got in current_procinfo.flags) then
+               (force or
+                (pi_needs_got in current_procinfo.flags)) then
               case target_info.system of
                 system_powerpc_darwin,
                 system_powerpc64_darwin:
@@ -237,6 +240,7 @@ unit cgppc;
                        { procedures)                                         }
                        not(pi_do_call in current_procinfo.flags) then
                       list.concat(taicpu.op_reg_reg(A_MTSPR,NR_LR,NR_R0));
+                    result:=current_procinfo.got;
                   end;
               end;
           end;

+ 1 - 1
compiler/psub.pas

@@ -1026,7 +1026,7 @@ implementation
             cg.set_regalloc_live_range_direction(rad_backwards_reinit);
             current_filepos:=entrypos;
             { load got if necessary }
-            cg.g_maybe_got_init(templist);
+            current_procinfo.got:=cg.g_maybe_got_init(templist,false);
 
             aktproccode.insertlistafter(headertai,templist);
 

+ 16 - 3
compiler/x86/cgx86.pas

@@ -2124,11 +2124,24 @@ unit cgx86;
            { darwin/x86_64's assembler doesn't want @PLT after call symbols }
            (target_info.system<>system_x86_64_darwin) then
           begin
+            ref.refaddr:=addr_pic;
+{$ifdef i386}
             { it could be that we're called from a procedure not having the
-              got loaded
+              got loaded. Since all volatile registers can contain parameters,
+              we have to use the stack.
             }
-            g_maybe_got_init(list);
-            ref.refaddr:=addr_pic
+            list.concat(taicpu.op_reg(A_PUSH,S_L,NR_EBX));
+            ref.base:=g_maybe_got_init(list,true);
+            if (ref.base<>NR_EBX) then
+              internalerror(2009072801);
+            list.concat(taicpu.op_ref_reg(A_MOV,S_L,ref,NR_EBX));
+            reference_reset_base(ref,NR_ESP,0,sizeof(pint));
+            { restore ebx to its original value, and place target address
+              on the stack }
+            list.concat(taicpu.op_reg_ref(A_XCHG,S_L,NR_EBX,ref));
+            list.concat(taicpu.op_none(A_RET));
+            exit;
+{$endif i386}
           end
         else
           ref.refaddr:=addr_full;