Browse Source

* initial addr_pic support for x86_64 binary writer

git-svn-id: trunk@4848 -
peter 19 years ago
parent
commit
71665dbc4c
3 changed files with 95 additions and 44 deletions
  1. 3 0
      compiler/ogbase.pas
  2. 38 28
      compiler/ogelf.pas
  3. 54 16
      compiler/x86/aasmcpu.pas

+ 3 - 0
compiler/ogbase.pas

@@ -55,6 +55,9 @@ interface
          RELOC_RELATIVE_3,
          RELOC_RELATIVE_3,
          RELOC_RELATIVE_4,
          RELOC_RELATIVE_4,
          RELOC_RELATIVE_5,
          RELOC_RELATIVE_5,
+         { PIC }
+         RELOC_GOTPCREL,
+         RELOC_PLT32,
 {$endif x86_64}
 {$endif x86_64}
 {$ifdef arm}
 {$ifdef arm}
          RELOC_RELATIVE_24,
          RELOC_RELATIVE_24,

+ 38 - 28
compiler/ogelf.pas

@@ -57,7 +57,7 @@ interface
          destructor  destroy;override;
          destructor  destroy;override;
          function  sectionname(atype:TAsmSectiontype;const aname:string):string;override;
          function  sectionname(atype:TAsmSectiontype;const aname:string):string;override;
          procedure CreateDebugSections;override;
          procedure CreateDebugSections;override;
-         procedure writereloc(data,len:aint;p:TObjSymbol;relative:TObjRelocationType);override;
+         procedure writereloc(data,len:aint;p:TObjSymbol;reltype:TObjRelocationType);override;
          procedure writestab(offset:aint;ps:TObjSymbol;nidx,nother:byte;ndesc:word;p:pchar);override;
          procedure writestab(offset:aint;ps:TObjSymbol;nidx,nother:byte;ndesc:word;p:pchar);override;
        end;
        end;
 
 
@@ -155,11 +155,11 @@ implementation
       R_X86_64_32S = 11;
       R_X86_64_32S = 11;
       { Direct 16 bit zero extended  }
       { Direct 16 bit zero extended  }
       R_X86_64_16 = 12;
       R_X86_64_16 = 12;
-      { 16 bit sign extended pc relative  }
+      { 16 bit sign extended PC relative  }
       R_X86_64_PC16 = 13;
       R_X86_64_PC16 = 13;
       { Direct 8 bit sign extended   }
       { Direct 8 bit sign extended   }
       R_X86_64_8 = 14;
       R_X86_64_8 = 14;
-      { 8 bit sign extended pc relative  }
+      { 8 bit sign extended PC relative  }
       R_X86_64_PC8 = 15;
       R_X86_64_PC8 = 15;
       { ID of module containing symbol  }
       { ID of module containing symbol  }
       R_X86_64_DTPMOD64 = 16;
       R_X86_64_DTPMOD64 = 16;
@@ -611,7 +611,7 @@ implementation
       end;
       end;
 
 
 
 
-    procedure TElfObjData.writereloc(data,len:aint;p:TObjSymbol;relative:TObjRelocationType);
+    procedure TElfObjData.writereloc(data,len:aint;p:TObjSymbol;reltype:TObjRelocationType);
       var
       var
         symaddr : longint;
         symaddr : longint;
       begin
       begin
@@ -626,24 +626,25 @@ implementation
            { real address of the symbol }
            { real address of the symbol }
            symaddr:=p.address;
            symaddr:=p.address;
            { Local ObjSymbols can be resolved already or need a section reloc }
            { Local ObjSymbols can be resolved already or need a section reloc }
-           if (p.bind=AB_LOCAL) then
+           if (p.bind=AB_LOCAL) and
+              (reltype in [RELOC_RELATIVE,RELOC_ABSOLUTE{$ifdef x86_64},RELOC_ABSOLUTE32{$endif x86_64}]) then
              begin
              begin
-               { For a relative relocation in the same section the
+               { For a reltype relocation in the same section the
                  value can be calculated }
                  value can be calculated }
                if (p.objsection=CurrObjSec) and
                if (p.objsection=CurrObjSec) and
-                  (relative=RELOC_RELATIVE) then
+                  (reltype=RELOC_RELATIVE) then
                  inc(data,symaddr-len-CurrObjSec.Size)
                  inc(data,symaddr-len-CurrObjSec.Size)
                else
                else
                  begin
                  begin
-                   CurrObjSec.addsectionreloc(CurrObjSec.Size,p.objsection,relative);
+                   CurrObjSec.addsectionreloc(CurrObjSec.Size,p.objsection,reltype);
                    inc(data,symaddr);
                    inc(data,symaddr);
                  end;
                  end;
              end
              end
            else
            else
              begin
              begin
-               CurrObjSec.addsymreloc(CurrObjSec.Size,p,relative);
+               CurrObjSec.addsymreloc(CurrObjSec.Size,p,reltype);
 {$ifndef x86_64}
 {$ifndef x86_64}
-               if relative=RELOC_RELATIVE then
+               if reltype=RELOC_RELATIVE then
                  dec(data,len);
                  dec(data,len);
 {$endif x86_64}
 {$endif x86_64}
             end;
             end;
@@ -723,24 +724,6 @@ implementation
                objreloc:=TObjRelocation(s.Objrelocations[i]);
                objreloc:=TObjRelocation(s.Objrelocations[i]);
                fillchar(rel,sizeof(rel),0);
                fillchar(rel,sizeof(rel),0);
                rel.address:=objreloc.dataoffset;
                rel.address:=objreloc.dataoffset;
-               if assigned(objreloc.symbol) then
-                 begin
-                   if (objreloc.symbol.bind=AB_LOCAL) then
-                     relsym:=objreloc.symbol.objsection.secsymidx
-                   else
-                     begin
-                       if objreloc.symbol.symidx=-1 then
-                         internalerror(200603012);
-                       relsym:=objreloc.symbol.symidx;
-                     end;
-                 end
-               else
-                 begin
-                   if objreloc.objsection<>nil then
-                     relsym:=objreloc.objsection.secsymidx
-                   else
-                     relsym:=SHN_UNDEF;
-                 end;
 
 
                { when things settle down, we can create processor specific
                { when things settle down, we can create processor specific
                  derived classes }
                  derived classes }
@@ -766,10 +749,37 @@ implementation
                    reltyp:=R_X86_64_64;
                    reltyp:=R_X86_64_64;
                  RELOC_ABSOLUTE32 :
                  RELOC_ABSOLUTE32 :
                    reltyp:=R_X86_64_32S;
                    reltyp:=R_X86_64_32S;
+                 RELOC_GOTPCREL :
+                   begin
+                     reltyp:=R_X86_64_GOTPCREL;
+                     { length of the relocated location is handled here }
+                     rel.addend:=qword(-4);
+                   end;
+                 RELOC_PLT32 :
+                   begin
+                     reltyp:=R_X86_64_PLT32;
+                     { length of the relocated location is handled here }
+                     rel.addend:=qword(-4);
+                   end;
 {$endif x86_64}
 {$endif x86_64}
                  else
                  else
                    internalerror(200602261);
                    internalerror(200602261);
                end;
                end;
+
+               { Symbol }
+               if assigned(objreloc.symbol) then
+                 begin
+                   if objreloc.symbol.symidx=-1 then
+                     internalerror(200603012);
+                   relsym:=objreloc.symbol.symidx;
+                 end
+               else
+                 begin
+                   if objreloc.objsection<>nil then
+                     relsym:=objreloc.objsection.secsymidx
+                   else
+                     relsym:=SHN_UNDEF;
+                 end;
 {$ifdef cpu64bit}
 {$ifdef cpu64bit}
                rel.info:=(qword(relsym) shl 32) or reltyp;
                rel.info:=(qword(relsym) shl 32) or reltyp;
 {$else cpu64bit}
 {$else cpu64bit}

+ 54 - 16
compiler/x86/aasmcpu.pas

@@ -1017,7 +1017,14 @@ implementation
                 end;
                 end;
               top_ref :
               top_ref :
                 begin
                 begin
-                  if ref^.refaddr=addr_no then
+                  if (ref^.refaddr=addr_no)
+{$ifdef x86_64}
+                     or (
+                         (ref^.refaddr=addr_pic) and
+                         (ref^.base<>NR_NO)
+                        )
+{$endif x86_64}
+                     then
                     begin
                     begin
                       { create ot field }
                       { create ot field }
                       if (ot and OT_SIZE_MASK)=0 then
                       if (ot and OT_SIZE_MASK)=0 then
@@ -1463,7 +1470,7 @@ implementation
         o:=input.ref^.offset;
         o:=input.ref^.offset;
         sym:=input.ref^.symbol;
         sym:=input.ref^.symbol;
         if ((ir<>NR_NO) and (getregtype(ir)<>R_INTREGISTER)) or
         if ((ir<>NR_NO) and (getregtype(ir)<>R_INTREGISTER)) or
-           ((br<>NR_NO) and (getregtype(br)<>R_INTREGISTER)) then
+           ((br<>NR_NO) and (br<>NR_RIP) and (getregtype(br)<>R_INTREGISTER)) then
           internalerror(200301081);
           internalerror(200301081);
         { it's direct address }
         { it's direct address }
         if (br=NR_NO) and (ir=NR_NO) then
         if (br=NR_NO) and (ir=NR_NO) then
@@ -1976,6 +1983,9 @@ implementation
       var
       var
         currval : aint;
         currval : aint;
         currsym : tobjsymbol;
         currsym : tobjsymbol;
+        currrelreloc,
+        currabsreloc,
+        currabsreloc32 : TObjRelocationType;
 {$ifdef x86_64}
 {$ifdef x86_64}
         rexwritten : boolean;
         rexwritten : boolean;
 {$endif x86_64}
 {$endif x86_64}
@@ -1987,11 +1997,27 @@ implementation
                 begin
                 begin
                   currval:=oper[opidx]^.ref^.offset;
                   currval:=oper[opidx]^.ref^.offset;
                   currsym:=ObjData.symbolref(oper[opidx]^.ref^.symbol);
                   currsym:=ObjData.symbolref(oper[opidx]^.ref^.symbol);
+{$ifdef x86_64}
+                  if oper[opidx]^.ref^.refaddr=addr_pic then
+                    begin
+                      currrelreloc:=RELOC_PLT32;
+                      currabsreloc:=RELOC_GOTPCREL;
+                      currabsreloc32:=RELOC_GOTPCREL;
+                    end
+                  else
+{$endif x86_64}
+                    begin
+                      currrelreloc:=RELOC_RELATIVE;
+                      currabsreloc:=RELOC_ABSOLUTE;
+                      currabsreloc32:=RELOC_ABSOLUTE32;
+                    end;
                 end;
                 end;
               top_const :
               top_const :
                 begin
                 begin
                   currval:=aint(oper[opidx]^.val);
                   currval:=aint(oper[opidx]^.val);
                   currsym:=nil;
                   currsym:=nil;
+                  currabsreloc:=RELOC_ABSOLUTE;
+                  currabsreloc32:=RELOC_ABSOLUTE32;
                 end;
                 end;
               else
               else
                 Message(asmw_e_immediate_or_reference_expected);
                 Message(asmw_e_immediate_or_reference_expected);
@@ -2105,7 +2131,7 @@ implementation
                 if (currval<-128) or (currval>127) then
                 if (currval<-128) or (currval>127) then
                  Message2(asmw_e_value_exceeds_bounds,'signed byte',tostr(currval));
                  Message2(asmw_e_value_exceeds_bounds,'signed byte',tostr(currval));
                 if assigned(currsym) then
                 if assigned(currsym) then
-                  objdata.writereloc(currval,1,currsym,RELOC_ABSOLUTE)
+                  objdata.writereloc(currval,1,currsym,currabsreloc)
                 else
                 else
                   objdata.writebytes(currval,1);
                   objdata.writebytes(currval,1);
               end;
               end;
@@ -2115,7 +2141,7 @@ implementation
                 if (currval<-256) or (currval>255) then
                 if (currval<-256) or (currval>255) then
                  Message2(asmw_e_value_exceeds_bounds,'byte',tostr(currval));
                  Message2(asmw_e_value_exceeds_bounds,'byte',tostr(currval));
                 if assigned(currsym) then
                 if assigned(currsym) then
-                 objdata.writereloc(currval,1,currsym,RELOC_ABSOLUTE)
+                 objdata.writereloc(currval,1,currsym,currabsreloc)
                 else
                 else
                  objdata.writebytes(currval,1);
                  objdata.writebytes(currval,1);
               end;
               end;
@@ -2125,7 +2151,7 @@ implementation
                 if (currval<0) or (currval>255) then
                 if (currval<0) or (currval>255) then
                  Message2(asmw_e_value_exceeds_bounds,'unsigned byte',tostr(currval));
                  Message2(asmw_e_value_exceeds_bounds,'unsigned byte',tostr(currval));
                 if assigned(currsym) then
                 if assigned(currsym) then
-                 objdata.writereloc(currval,1,currsym,RELOC_ABSOLUTE)
+                 objdata.writereloc(currval,1,currsym,currabsreloc)
                 else
                 else
                  objdata.writebytes(currval,1);
                  objdata.writebytes(currval,1);
               end;
               end;
@@ -2135,7 +2161,7 @@ implementation
                 if (currval<-65536) or (currval>65535) then
                 if (currval<-65536) or (currval>65535) then
                  Message2(asmw_e_value_exceeds_bounds,'word',tostr(currval));
                  Message2(asmw_e_value_exceeds_bounds,'word',tostr(currval));
                 if assigned(currsym) then
                 if assigned(currsym) then
-                 objdata.writereloc(currval,2,currsym,RELOC_ABSOLUTE)
+                 objdata.writereloc(currval,2,currsym,currabsreloc)
                 else
                 else
                  objdata.writebytes(currval,2);
                  objdata.writebytes(currval,2);
               end;
               end;
@@ -2145,14 +2171,14 @@ implementation
                 if opsize=S_Q then
                 if opsize=S_Q then
                   begin
                   begin
                     if assigned(currsym) then
                     if assigned(currsym) then
-                     objdata.writereloc(currval,8,currsym,RELOC_ABSOLUTE)
+                     objdata.writereloc(currval,8,currsym,currabsreloc)
                     else
                     else
                      objdata.writebytes(currval,8);
                      objdata.writebytes(currval,8);
                   end
                   end
                 else
                 else
                   begin
                   begin
                     if assigned(currsym) then
                     if assigned(currsym) then
-                      objdata.writereloc(currval,4,currsym,RELOC_ABSOLUTE32)
+                      objdata.writereloc(currval,4,currsym,currabsreloc32)
                     else
                     else
                       objdata.writebytes(currval,4);
                       objdata.writebytes(currval,4);
                   end
                   end
@@ -2161,7 +2187,7 @@ implementation
               begin
               begin
                 getvalsym(c-32);
                 getvalsym(c-32);
                 if assigned(currsym) then
                 if assigned(currsym) then
-                 objdata.writereloc(currval,4,currsym,RELOC_ABSOLUTE32)
+                 objdata.writereloc(currval,4,currsym,currabsreloc32)
                 else
                 else
                  objdata.writebytes(currval,4);
                  objdata.writebytes(currval,4);
               end;
               end;
@@ -2179,17 +2205,17 @@ implementation
               begin
               begin
                 getvalsym(c-52);
                 getvalsym(c-52);
                 if assigned(currsym) then
                 if assigned(currsym) then
-                 objdata.writereloc(currval,4,currsym,RELOC_RELATIVE)
+                 objdata.writereloc(currval,4,currsym,currrelreloc)
                 else
                 else
-                 objdata.writereloc(currval-insend,4,nil,RELOC_ABSOLUTE32)
+                 objdata.writereloc(currval-insend,4,nil,currabsreloc32)
               end;
               end;
             56,57,58 :
             56,57,58 :
               begin
               begin
                 getvalsym(c-56);
                 getvalsym(c-56);
                 if assigned(currsym) then
                 if assigned(currsym) then
-                 objdata.writereloc(currval,4,currsym,RELOC_RELATIVE)
+                 objdata.writereloc(currval,4,currsym,currrelreloc)
                 else
                 else
-                 objdata.writereloc(currval-insend,4,nil,RELOC_ABSOLUTE32)
+                 objdata.writereloc(currval-insend,4,nil,currabsreloc32)
               end;
               end;
             192,193,194 :
             192,193,194 :
               begin
               begin
@@ -2317,7 +2343,13 @@ implementation
                          if (oper[opidx]^.ot and OT_MEMORY)=OT_MEMORY then
                          if (oper[opidx]^.ot and OT_MEMORY)=OT_MEMORY then
                            begin
                            begin
                              currsym:=objdata.symbolref(oper[opidx]^.ref^.symbol);
                              currsym:=objdata.symbolref(oper[opidx]^.ref^.symbol);
-                             objdata.writereloc(oper[opidx]^.ref^.offset,1,currsym,RELOC_ABSOLUTE);
+{$ifdef x86_64}
+                             if oper[opidx]^.ref^.refaddr=addr_pic then
+                               currabsreloc:=RELOC_PLT32
+                             else
+{$endif x86_64}
+                               currabsreloc:=RELOC_ABSOLUTE;
+                             objdata.writereloc(oper[opidx]^.ref^.offset,1,currsym,currabsreloc);
                            end
                            end
                          else
                          else
                           begin
                           begin
@@ -2328,8 +2360,14 @@ implementation
                        end;
                        end;
                      2,4 :
                      2,4 :
                        begin
                        begin
-                         objdata.writereloc(oper[opidx]^.ref^.offset,ea_data.bytes,
-                           objdata.symbolref(oper[opidx]^.ref^.symbol),RELOC_ABSOLUTE32);
+                         currsym:=objdata.symbolref(oper[opidx]^.ref^.symbol);
+{$ifdef x86_64}
+                         if oper[opidx]^.ref^.refaddr=addr_pic then
+                           currabsreloc:=RELOC_PLT32
+                         else
+{$endif x86_64}
+                           currabsreloc:=RELOC_ABSOLUTE;
+                         objdata.writereloc(oper[opidx]^.ref^.offset,ea_data.bytes,currsym,currabsreloc);
                          inc(s,ea_data.bytes);
                          inc(s,ea_data.bytes);
                        end;
                        end;
                    end;
                    end;