2
0
Эх сурвалжийг харах

+ Support GOT/gp-relative constants in GAS and internal assemblers, MIPS and i386.
* Change MIPS jump tables in PIC mode to use gp-relative constants, making them ABI-compliant and not requiring dynamic relocations.

git-svn-id: trunk@26886 -

sergei 11 жил өмнө
parent
commit
46f8e78d1f

+ 6 - 1
compiler/aasmtai.pas

@@ -137,7 +137,10 @@ interface
           aitconst_64bit_unaligned,
           aitconst_64bit_unaligned,
           { i8086 far pointer; emits: 'DW symbol, SEG symbol' }
           { i8086 far pointer; emits: 'DW symbol, SEG symbol' }
           aitconst_farptr,
           aitconst_farptr,
-          aitconst_got
+          { offset of symbol's GOT slot in GOT }
+          aitconst_got,
+          { offset of symbol itself from GOT }
+          aitconst_gotoff_symbol
         );
         );
 
 
     const
     const
@@ -1838,6 +1841,8 @@ implementation
             result:=LengthSleb128(value);
             result:=LengthSleb128(value);
           aitconst_half16bit:
           aitconst_half16bit:
             result:=2;
             result:=2;
+          aitconst_gotoff_symbol:
+            result:=4;
           else
           else
             internalerror(200603253);
             internalerror(200603253);
         end;
         end;

+ 26 - 0
compiler/aggas.pas

@@ -951,6 +951,32 @@ implementation
                      AsmWrite(#9'.word'#9+tai_const(hp).sym.name+'(GOT)');
                      AsmWrite(#9'.word'#9+tai_const(hp).sym.name+'(GOT)');
                      Asmln;
                      Asmln;
                    end;
                    end;
+
+                 aitconst_gotoff_symbol:
+                   begin
+                     if (tai_const(hp).sym=nil) then
+                       InternalError(2014022601);
+                     case target_info.cpu of
+
+                       cpu_mipseb,cpu_mipsel:
+                         begin
+                           AsmWrite(#9'.gpword'#9);
+                           AsmWrite(tai_const(hp).sym.name);
+                         end;
+
+                       cpu_i386:
+                         begin
+                           AsmWrite(ait_const2str[aitconst_32bit]);
+                           AsmWrite(tai_const(hp).sym.name);
+                         end;
+                     else
+                       InternalError(2014022602);
+                     end;
+                     if (tai_const(hp).value<>0) then
+                       AsmWrite(tostr_with_plus(tai_const(hp).value));
+                     Asmln;
+                   end;
+
                  aitconst_uleb128bit,
                  aitconst_uleb128bit,
                  aitconst_sleb128bit,
                  aitconst_sleb128bit,
 {$ifdef cpu64bitaddr}
 {$ifdef cpu64bitaddr}

+ 2 - 0
compiler/assemble.pas

@@ -1488,6 +1488,8 @@ Implementation
                        { Required for DWARF2 support under Windows }
                        { Required for DWARF2 support under Windows }
                        ObjData.writereloc(Tai_const(hp).symofs,sizeof(longint),Objdata.SymbolRef(tai_const(hp).sym),RELOC_SECREL32);
                        ObjData.writereloc(Tai_const(hp).symofs,sizeof(longint),Objdata.SymbolRef(tai_const(hp).sym),RELOC_SECREL32);
                      end;
                      end;
+                   aitconst_gotoff_symbol:
+                     ObjData.writereloc(Tai_const(hp).symofs,sizeof(longint),Objdata.SymbolRef(tai_const(hp).sym),RELOC_GOTOFF);
                    aitconst_uleb128bit,
                    aitconst_uleb128bit,
                    aitconst_sleb128bit :
                    aitconst_sleb128bit :
                      begin
                      begin

+ 2 - 0
compiler/i386/cpuelf.pas

@@ -110,6 +110,8 @@ implementation
           result:=R_386_GOTPC;
           result:=R_386_GOTPC;
         RELOC_PLT32 :
         RELOC_PLT32 :
           result:=R_386_PLT32;
           result:=R_386_PLT32;
+        RELOC_GOTOFF:
+          result:=R_386_GOTOFF;
       else
       else
         result:=0;
         result:=0;
         InternalError(2012082301);
         InternalError(2012082301);

+ 11 - 2
compiler/mips/ncpuset.pas

@@ -71,6 +71,7 @@ var
   href:  treference;
   href:  treference;
   jumpsegment: TAsmlist;
   jumpsegment: TAsmlist;
   opcgsize: tcgsize;
   opcgsize: tcgsize;
+  labeltyp: taiconst_type;
 
 
   procedure genitem(t: pcaselabel);
   procedure genitem(t: pcaselabel);
   var
   var
@@ -80,9 +81,9 @@ var
       genitem(t^.less);
       genitem(t^.less);
     { fill possible hole }
     { fill possible hole }
     for i := last.svalue+1 to t^._low.svalue-1 do
     for i := last.svalue+1 to t^._low.svalue-1 do
-      jumpSegment.concat(Tai_const.Create_sym(elselabel));
+      jumpSegment.concat(Tai_const.Create_type_sym(labeltyp,elselabel));
     for i := t^._low.svalue to t^._high.svalue do
     for i := t^._low.svalue to t^._high.svalue do
-      jumpSegment.concat(Tai_const.Create_sym(blocklabel(t^.blockid)));
+      jumpSegment.concat(Tai_const.Create_type_sym(labeltyp,blocklabel(t^.blockid)));
     last := t^._high;
     last := t^._high;
     if assigned(t^.greater) then
     if assigned(t^.greater) then
       genitem(t^.greater);
       genitem(t^.greater);
@@ -108,6 +109,14 @@ begin
   jmpreg := cg.getaddressregister(current_asmdata.CurrAsmList);
   jmpreg := cg.getaddressregister(current_asmdata.CurrAsmList);
   cg.a_load_ref_reg(current_asmdata.CurrAsmList, OS_ADDR, OS_ADDR, href, jmpreg);
   cg.a_load_ref_reg(current_asmdata.CurrAsmList, OS_ADDR, OS_ADDR, href, jmpreg);
 
 
+  if (cs_create_pic in current_settings.moduleswitches) then
+    begin
+      cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_ADD,OS_ADDR,NR_GP,jmpreg,jmpreg);
+      labeltyp:=aitconst_gotoff_symbol;
+    end
+  else
+    labeltyp:=aitconst_ptr;
+
   current_asmdata.CurrAsmList.concat(taicpu.op_reg(A_JR, jmpreg));
   current_asmdata.CurrAsmList.concat(taicpu.op_reg(A_JR, jmpreg));
   { Delay slot }
   { Delay slot }
   current_asmdata.CurrAsmList.concat(taicpu.op_none(A_NOP));
   current_asmdata.CurrAsmList.concat(taicpu.op_none(A_NOP));

+ 2 - 0
compiler/ogbase.pas

@@ -84,6 +84,8 @@ interface
          RELOC_NONE,
          RELOC_NONE,
          { Darwin relocation, using PAIR }
          { Darwin relocation, using PAIR }
          RELOC_PIC_PAIR,
          RELOC_PIC_PAIR,
+         { Relative to GOT/gp }
+         RELOC_GOTOFF,
          { Untranslated target-specific value }
          { Untranslated target-specific value }
          RELOC_RAW
          RELOC_RAW
       );
       );