浏览代码

* i386 _GLOBAL_OFFSET_TABLE_ label special treatment moved to taicpu.pass2

git-svn-id: trunk@16100 -
pierre 15 年之前
父节点
当前提交
d2939bce3d
共有 2 个文件被更改,包括 36 次插入27 次删除
  1. 0 14
      compiler/ogelf.pas
  2. 36 13
      compiler/x86/aasmcpu.pas

+ 0 - 14
compiler/ogelf.pas

@@ -768,20 +768,6 @@ implementation
              end
            else
              begin
-{$ifdef i386}
-               { Hack for _GLOBAL_OFFSET_TABLE_ which needs a special 
-                 relocation type R_386_GOTPC, found by trial/error PM }
-               if p.name='_GLOBAL_OFFSET_TABLE_' then
-                 begin
-                   reltype:=RELOC_GOTPC;
-                   { This value comes from the offset of the relocation
-                     of _GLOBAL_OFFSET_TABLE symbol within the instruction
-                     movl $_GLOBAL_OFFSET_TABLE_,%ebx
-                     It might be wrong if the symbol is used
-                     in some other instruction having a bigger offset }
-                   inc(data,2);
-                 end;
-{$endif i386}
                CurrObjSec.addsymreloc(CurrObjSec.Size,p,reltype);
 {$ifndef x86_64}
                if (reltype=RELOC_RELATIVE) or (reltype=RELOC_PLT32) then

+ 36 - 13
compiler/x86/aasmcpu.pas

@@ -1972,6 +1972,29 @@ implementation
             end;
         end;
 {$endif x86_64}
+       procedure objdata_writereloc(Data:aint;len:aword;p:TObjSymbol;Reloctype:TObjRelocationType);
+         begin
+{$ifdef i386}
+               { Special case of '_GLOBAL_OFFSET_TABLE_'
+                 which needs a special relocation type R_386_GOTPC }
+               if assigned (p) and
+                  (p.name='_GLOBAL_OFFSET_TABLE_') and
+                  (tf_pic_uses_got in target_info.flags) then
+                 begin
+                   { nothing else than a 4 byte relocation should occur
+                     for GOT }
+                   if len<>4 then
+                     Message1(asmw_e_invalid_opcode_and_operands,GetString);
+                   Reloctype:=RELOC_GOTPC;
+                   { We need to add the offset of the relocation
+                     of _GLOBAL_OFFSET_TABLE symbol within
+                     the current instruction }
+                   inc(data,objdata.currobjsec.size-insoffset);
+                 end;
+{$endif i386}
+           objdata.writereloc(data,len,p,Reloctype);
+         end;
+
 
       const
         CondVal:array[TAsmCond] of byte=($0,
@@ -2070,7 +2093,7 @@ implementation
                 if (currval<-128) or (currval>127) then
                  Message2(asmw_e_value_exceeds_bounds,'signed byte',tostr(currval));
                 if assigned(currsym) then
-                  objdata.writereloc(currval,1,currsym,currabsreloc)
+                  objdata_writereloc(currval,1,currsym,currabsreloc)
                 else
                   objdata.writebytes(currval,1);
               end;
@@ -2080,7 +2103,7 @@ implementation
                 if (currval<-256) or (currval>255) then
                  Message2(asmw_e_value_exceeds_bounds,'byte',tostr(currval));
                 if assigned(currsym) then
-                 objdata.writereloc(currval,1,currsym,currabsreloc)
+                 objdata_writereloc(currval,1,currsym,currabsreloc)
                 else
                  objdata.writebytes(currval,1);
               end;
@@ -2090,7 +2113,7 @@ implementation
                 if (currval<0) or (currval>255) then
                  Message2(asmw_e_value_exceeds_bounds,'unsigned byte',tostr(currval));
                 if assigned(currsym) then
-                 objdata.writereloc(currval,1,currsym,currabsreloc)
+                 objdata_writereloc(currval,1,currsym,currabsreloc)
                 else
                  objdata.writebytes(currval,1);
               end;
@@ -2100,7 +2123,7 @@ implementation
                 if (currval<-65536) or (currval>65535) then
                  Message2(asmw_e_value_exceeds_bounds,'word',tostr(currval));
                 if assigned(currsym) then
-                 objdata.writereloc(currval,2,currsym,currabsreloc)
+                 objdata_writereloc(currval,2,currsym,currabsreloc)
                 else
                  objdata.writebytes(currval,2);
               end;
@@ -2110,14 +2133,14 @@ implementation
                 if opsize=S_Q then
                   begin
                     if assigned(currsym) then
-                     objdata.writereloc(currval,8,currsym,currabsreloc)
+                     objdata_writereloc(currval,8,currsym,currabsreloc)
                     else
                      objdata.writebytes(currval,8);
                   end
                 else
                   begin
                     if assigned(currsym) then
-                      objdata.writereloc(currval,4,currsym,currabsreloc32)
+                      objdata_writereloc(currval,4,currsym,currabsreloc32)
                     else
                       objdata.writebytes(currval,4);
                   end
@@ -2126,7 +2149,7 @@ implementation
               begin
                 getvalsym(c-32);
                 if assigned(currsym) then
-                 objdata.writereloc(currval,4,currsym,currabsreloc32)
+                 objdata_writereloc(currval,4,currsym,currabsreloc32)
                 else
                  objdata.writebytes(currval,4);
               end;
@@ -2144,17 +2167,17 @@ implementation
               begin
                 getvalsym(c-52);
                 if assigned(currsym) then
-                 objdata.writereloc(currval,4,currsym,currrelreloc)
+                 objdata_writereloc(currval,4,currsym,currrelreloc)
                 else
-                 objdata.writereloc(currval-insend,4,nil,currabsreloc32)
+                 objdata_writereloc(currval-insend,4,nil,currabsreloc32)
               end;
             56,57,58 :
               begin
                 getvalsym(c-56);
                 if assigned(currsym) then
-                 objdata.writereloc(currval,4,currsym,currrelreloc)
+                 objdata_writereloc(currval,4,currsym,currrelreloc)
                 else
-                 objdata.writereloc(currval-insend,4,nil,currabsreloc32)
+                 objdata_writereloc(currval-insend,4,nil,currabsreloc32)
               end;
             192,193,194 :
               begin
@@ -2294,7 +2317,7 @@ implementation
                              else
 {$endif x86_64}
                                currabsreloc:=RELOC_ABSOLUTE;
-                             objdata.writereloc(oper[opidx]^.ref^.offset,1,currsym,currabsreloc);
+                             objdata_writereloc(oper[opidx]^.ref^.offset,1,currsym,currabsreloc);
                            end
                          else
                           begin
@@ -2341,7 +2364,7 @@ implementation
                              currabsreloc:=RELOC_PIC_PAIR;
                              currval:=relsym.offset;
                            end;
-                         objdata.writereloc(currval,ea_data.bytes,currsym,currabsreloc);
+                         objdata_writereloc(currval,ea_data.bytes,currsym,currabsreloc);
                          inc(s,ea_data.bytes);
                        end;
                    end;