Pārlūkot izejas kodu

* Partial fix for i386 linux PIC code generation

git-svn-id: trunk@16080 -
pierre 15 gadi atpakaļ
vecāks
revīzija
292e85a59a
4 mainītis faili ar 78 papildinājumiem un 2 dzēšanām
  1. 5 1
      compiler/aasmdata.pas
  2. 6 0
      compiler/ogbase.pas
  3. 38 1
      compiler/ogelf.pas
  4. 29 0
      compiler/x86/aasmcpu.pas

+ 5 - 1
compiler/aasmdata.pas

@@ -449,7 +449,11 @@ implementation
 
     procedure TAsmData.getlabel(out l : TAsmLabel;alt:TAsmLabeltype);
       begin
-        l:=TAsmLabel.createlocal(AsmSymbolDict,FNextLabelNr[alt],alt);
+        if (cs_link_smart in current_settings.globalswitches) and
+           (alt = alt_dbgline) then
+          l:=TAsmLabel.createglobal(AsmSymbolDict,name,FNextLabelNr[alt],alt)
+        else
+          l:=TAsmLabel.createlocal(AsmSymbolDict,FNextLabelNr[alt],alt);
         inc(FNextLabelNr[alt]);
       end;
 

+ 6 - 0
compiler/ogbase.pas

@@ -59,6 +59,12 @@ interface
          RELOC_GOTPCREL,
          RELOC_PLT32,
 {$endif x86_64}
+{$ifdef i386}
+         { PIC }
+         RELOC_GOTPC,
+         RELOC_GOT32,
+         RELOC_PLT32,
+{$endif i386}
 {$ifdef arm}
          RELOC_RELATIVE_24,
 {$endif arm}

+ 38 - 1
compiler/ogelf.pas

@@ -546,13 +546,28 @@ implementation
 ****************************************************************************}
 
     constructor TElfObjData.create(const n:string);
+      var
+        need_datarel : boolean;
       begin
         inherited create(n);
         CObjSection:=TElfObjSection;
         { we need at least the following sections }
         createsection(sec_code);
+        if (cs_create_pic in current_settings.moduleswitches) and
+           not(target_info.system in systems_darwin) then
+          begin
+            { We still need an empty data section }
+            system.exclude(current_settings.moduleswitches,cs_create_pic);
+            need_datarel:=true;
+          end
+        else
+          need_datarel:=false;
         createsection(sec_data);
+        if need_datarel then
+          system.include(current_settings.moduleswitches,cs_create_pic);
         createsection(sec_bss);
+        if need_datarel then
+          createsection(sec_data);
         if tf_section_threadvars in target_info.flags then
           createsection(sec_threadvar);
         if (tf_needs_dwarf_cfi in target_info.flags) and
@@ -753,9 +768,23 @@ 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 then
+               if (reltype=RELOC_RELATIVE) or (reltype=RELOC_PLT32) then
                  dec(data,len);
 {$endif x86_64}
             end;
@@ -822,6 +851,14 @@ implementation
                    reltyp:=R_386_PC32;
                  RELOC_ABSOLUTE :
                    reltyp:=R_386_32;
+                 RELOC_GOT32 :
+                   reltyp:=R_386_GOT32;
+                 RELOC_GOTPC :
+                   reltyp:=R_386_GOTPC;
+                 RELOC_PLT32 :
+                   begin
+                     reltyp:=R_386_PLT32;
+                   end;
 {$endif i386}
 {$ifdef sparc}
                  RELOC_ABSOLUTE :

+ 29 - 0
compiler/x86/aasmcpu.pas

@@ -274,6 +274,7 @@ implementation
      uses
        cutils,
        globals,
+       systems,
        itcpugas,
        symsym;
 
@@ -929,6 +930,12 @@ implementation
               top_ref :
                 begin
                   if (ref^.refaddr=addr_no)
+{$ifdef i386}
+                     or (
+                         (ref^.refaddr in [addr_pic]) and
+                         (ref^.base=NR_EBX)
+                        )
+{$endif i386}
 {$ifdef x86_64}
                      or (
                          (ref^.refaddr in [addr_pic,addr_pic_no_got]) and
@@ -1918,6 +1925,16 @@ implementation
                 begin
                   currval:=oper[opidx]^.ref^.offset;
                   currsym:=ObjData.symbolref(oper[opidx]^.ref^.symbol);
+{$ifdef i386}
+                  if (oper[opidx]^.ref^.refaddr=addr_pic) and
+                     (tf_pic_uses_got in target_info.flags) then
+                    begin
+                      currrelreloc:=RELOC_PLT32;
+                      currabsreloc:=RELOC_GOT32;
+                      currabsreloc32:=RELOC_GOT32;
+                    end
+                  else
+{$endif i386}
 {$ifdef x86_64}
                   if oper[opidx]^.ref^.refaddr=addr_pic then
                     begin
@@ -2265,6 +2282,12 @@ implementation
                          if (oper[opidx]^.ot and OT_MEMORY)=OT_MEMORY then
                            begin
                              currsym:=objdata.symbolref(oper[opidx]^.ref^.symbol);
+{$ifdef i386}
+                             if (oper[opidx]^.ref^.refaddr=addr_pic) and
+                                (tf_pic_uses_got in target_info.flags) then
+                               currabsreloc:=RELOC_GOT32
+                             else
+{$endif i386}
 {$ifdef x86_64}
                              if oper[opidx]^.ref^.refaddr=addr_pic then
                                currabsreloc:=RELOC_GOTPCREL
@@ -2303,6 +2326,12 @@ implementation
                              end
                            else
 {$endif x86_64}
+{$ifdef i386}
+                         if (oper[opidx]^.ref^.refaddr=addr_pic) and
+                            (tf_pic_uses_got in target_info.flags) then
+                           currabsreloc:=RELOC_GOT32
+                         else
+{$endif i386}
                              currabsreloc:=RELOC_ABSOLUTE32;
 
                            if (currabsreloc=RELOC_ABSOLUTE32) and