Browse Source

* record symbols that need to remain in their original order, and on Darwin
pass them to the linker so it does not reorder them
o fixes resource strings on Darwin when using LTO (this used to reorder the
resource string symbols, so they no longer all appeared between the START
and END symbols for their compilation module)

git-svn-id: trunk@41907 -

Jonas Maebe 6 năm trước cách đây
mục cha
commit
d150869dea

+ 1 - 0
compiler/aasmcnst.pas

@@ -1115,6 +1115,7 @@ implementation
              secname:=make_mangledname(basename,st,'2_'+itemname);
            exclude(options,tcalo_vectorized_dead_strip_item);
          end;
+       current_module.linkorderedsymbols.concat(sym.Name);
        finalize_asmlist(sym,def,sectype,secname,alignment,options);
      end;
 

+ 1 - 0
compiler/entfile.pas

@@ -120,6 +120,7 @@ const
   ibwpofile         = 84;
   ibmoduleoptions   = 85;
   ibunitimportsyms  = 86;
+  iborderedsymbols  = 87;
 
   ibmainname       = 90;
   ibsymtableoptions = 91;

+ 6 - 1
compiler/fmodule.pas

@@ -169,7 +169,8 @@ interface
         loaded_from   : tmodule;
         _exports      : tlinkedlist;
         dllscannerinputlist : TFPHashList;
-        resourcefiles : TCmdStrList;
+        resourcefiles,
+        linkorderedsymbols : TCmdStrList;
         linkunitofiles,
         linkunitstaticlibs,
         linkunitsharedlibs,
@@ -564,6 +565,7 @@ implementation
         used_units:=TLinkedList.Create;
         dependent_units:=TLinkedList.Create;
         resourcefiles:=TCmdStrList.Create;
+        linkorderedsymbols:=TCmdStrList.Create;
         linkunitofiles:=TLinkContainer.Create;
         linkunitstaticlibs:=TLinkContainer.Create;
         linkunitsharedlibs:=TLinkContainer.Create;
@@ -685,6 +687,7 @@ implementation
         used_units.free;
         dependent_units.free;
         resourcefiles.Free;
+        linkorderedsymbols.Free;
         linkunitofiles.Free;
         linkunitstaticlibs.Free;
         linkunitsharedlibs.Free;
@@ -841,6 +844,8 @@ implementation
         dependent_units:=TLinkedList.Create;
         resourcefiles.Free;
         resourcefiles:=TCmdStrList.Create;
+        linkorderedsymbols.Free;
+        linkorderedsymbols:=TCmdStrList.Create;;
         pendingspecializations.free;
         pendingspecializations:=tfphashobjectlist.create(false);
         if assigned(waitingforunit) and

+ 26 - 0
compiler/fppu.pas

@@ -96,6 +96,7 @@ interface
           procedure writederefdata;
           procedure writeImportSymbols;
           procedure writeResources;
+          procedure writeOrderedSymbols;
           procedure writeunitimportsyms;
           procedure writeasmsyms(kind:tunitasmlisttype;list:tfphashobjectlist);
           procedure writeextraheader;
@@ -106,6 +107,7 @@ interface
           procedure readderefdata;
           procedure readImportSymbols;
           procedure readResources;
+          procedure readOrderedSymbols;
           procedure readwpofile;
           procedure readunitimportsyms;
           procedure readasmsyms;
@@ -946,6 +948,20 @@ var
       end;
 
 
+    procedure tppumodule.writeOrderedSymbols;
+      var
+        res : TCmdStrListItem;
+      begin
+        res:=TCmdStrListItem(linkorderedsymbols.First);
+        while res<>nil do
+          begin
+            ppufile.putstring(res.FPStr);
+            res:=TCmdStrListItem(res.Next);
+          end;
+        ppufile.writeentry(iborderedsymbols);
+      end;
+
+
     procedure tppumodule.writeunitimportsyms;
       var
         i : longint;
@@ -1284,6 +1300,13 @@ var
       end;
 
 
+    procedure tppumodule.readOrderedSymbols;
+      begin
+        while not ppufile.endofentry do
+          linkorderedsymbols.Concat(ppufile.getstring);
+      end;
+
+
     procedure tppumodule.readwpofile;
       var
         orgwpofilename: string;
@@ -1430,6 +1453,8 @@ var
                readderefdata;
              ibresources:
                readResources;
+             iborderedsymbols:
+               readOrderedSymbols;
              ibwpofile:
                readwpofile;
              ibendinterface :
@@ -1550,6 +1575,7 @@ var
          writelinkcontainer(linkotherframeworks,iblinkotherframeworks,true);
          writeImportSymbols;
          writeResources;
+         writeOrderedSymbols;
          ppufile.do_crc:=true;
 
          { generate implementation deref data, the interface deref data is

+ 15 - 1
compiler/link.pas

@@ -55,7 +55,8 @@ interface
          ObjectFiles,
          SharedLibFiles,
          StaticLibFiles,
-         FrameworkFiles  : TCmdStrList;
+         FrameworkFiles,
+         OrderedSymbols: TCmdStrList;
          Constructor Create;virtual;
          Destructor Destroy;override;
          procedure AddModuleFiles(hp:tmodule);
@@ -65,6 +66,7 @@ interface
          Procedure AddStaticCLibrary(const S : TCmdStr);
          Procedure AddSharedCLibrary(S : TCmdStr);
          Procedure AddFramework(S : TCmdStr);
+         Procedure AddOrderedSymbol(const s: TCmdStr);
          procedure AddImportSymbol(const libname,symname,symmangledname:TCmdStr;OrdNr: longint;isvar:boolean);virtual;
          Procedure InitSysInitUnitName;virtual;
          Function  MakeExecutable:boolean;virtual;
@@ -353,6 +355,7 @@ Implementation
         SharedLibFiles:=TCmdStrList.Create_no_double;
         StaticLibFiles:=TCmdStrList.Create_no_double;
         FrameworkFiles:=TCmdStrList.Create_no_double;
+        OrderedSymbols:=TCmdStrList.Create;
       end;
 
 
@@ -362,6 +365,8 @@ Implementation
         SharedLibFiles.Free;
         StaticLibFiles.Free;
         FrameworkFiles.Free;
+        OrderedSymbols.Free;
+        inherited;
       end;
 
 
@@ -371,6 +376,7 @@ Implementation
         i,j  : longint;
         ImportLibrary : TImportLibrary;
         ImportSymbol  : TImportSymbol;
+        cmdstritem: TCmdStrListItem;
       begin
         with hp do
          begin
@@ -468,6 +474,8 @@ Implementation
                      ImportSymbol.MangledName,ImportSymbol.OrdNr,ImportSymbol.IsVar);
                  end;
              end;
+           { ordered symbols }
+           OrderedSymbols.concatList(linkorderedsymbols);
          end;
       end;
 
@@ -536,6 +544,12 @@ Implementation
       end;
 
 
+    procedure TLinker.AddOrderedSymbol(const s: TCmdStr);
+      begin
+        OrderedSymbols.Concat(s);
+      end;
+
+
     Procedure TLinker.AddStaticCLibrary(const S:TCmdStr);
       var
         ns : TCmdStr;

+ 3 - 1
compiler/systems.pas

@@ -165,7 +165,9 @@ interface
             tf_x86_far_procs_push_odd_bp,
             { indicates that this target can use dynamic packages otherwise an
               error will be generated if a package file is compiled }
-            tf_supports_packages
+            tf_supports_packages,
+            { supports symbol order file (to ensure symbols in vectorised sections are kept in the correct order) }
+            tf_supports_symbolorderfile
        );
 
        psysteminfo = ^tsysteminfo;

+ 5 - 5
compiler/systems/i_bsd.pas

@@ -811,7 +811,7 @@ unit i_bsd;
             system       : system_i386_darwin;
             name         : 'Darwin for i386';
             shortname    : 'Darwin';
-            flags        : [tf_p_ext_support,tf_files_case_sensitive,tf_smartlink_sections,tf_dwarf_relative_addresses,tf_dwarf_only_local_labels,tf_pic_uses_got,tf_pic_default,tf_has_winlike_resources];
+            flags        : [tf_p_ext_support,tf_files_case_sensitive,tf_smartlink_sections,tf_dwarf_relative_addresses,tf_dwarf_only_local_labels,tf_pic_uses_got,tf_pic_default,tf_has_winlike_resources,tf_supports_symbolorderfile];
             cpu          : cpu_i386;
             unit_env     : 'BSDUNITS';
             extradefines : 'UNIX;BSD;HASUNIX';
@@ -947,7 +947,7 @@ unit i_bsd;
             system       : system_powerpc64_darwin;
             name         : 'Darwin for PowerPC64';
             shortname    : 'Darwin';
-            flags        : [tf_p_ext_support,tf_files_case_sensitive,tf_smartlink_sections,tf_dwarf_relative_addresses,tf_dwarf_only_local_labels,tf_pic_default,tf_has_winlike_resources];
+            flags        : [tf_p_ext_support,tf_files_case_sensitive,tf_smartlink_sections,tf_dwarf_relative_addresses,tf_dwarf_only_local_labels,tf_pic_default,tf_has_winlike_resources,tf_supports_symbolorderfile];
             cpu          : cpu_powerpc64;
             unit_env     : 'BSDUNITS';
             extradefines : 'UNIX;BSD;HASUNIX';
@@ -1015,7 +1015,7 @@ unit i_bsd;
             system       : system_x86_64_darwin;
             name         : 'Darwin for x86_64';
             shortname    : 'Darwin';
-            flags        : [tf_p_ext_support,tf_files_case_sensitive,tf_smartlink_sections,tf_dwarf_relative_addresses,tf_dwarf_only_local_labels,tf_pic_default,tf_has_winlike_resources];
+            flags        : [tf_p_ext_support,tf_files_case_sensitive,tf_smartlink_sections,tf_dwarf_relative_addresses,tf_dwarf_only_local_labels,tf_pic_default,tf_has_winlike_resources,tf_supports_symbolorderfile];
             cpu          : cpu_x86_64;
             unit_env     : 'BSDUNITS';
             extradefines : 'UNIX;BSD;HASUNIX';
@@ -1149,7 +1149,7 @@ unit i_bsd;
             system       : system_arm_darwin;
             name         : 'Darwin for ARM';
             shortname    : 'Darwin';
-            flags        : [tf_p_ext_support,tf_requires_proper_alignment,tf_files_case_sensitive,tf_smartlink_sections,tf_dwarf_relative_addresses,tf_dwarf_only_local_labels,tf_has_winlike_resources,tf_pic_default];
+            flags        : [tf_p_ext_support,tf_requires_proper_alignment,tf_files_case_sensitive,tf_smartlink_sections,tf_dwarf_relative_addresses,tf_dwarf_only_local_labels,tf_has_winlike_resources,tf_pic_default,tf_supports_symbolorderfile];
             cpu          : cpu_arm;
             unit_env     : 'BSDUNITS';
             extradefines : 'UNIX;BSD;HASUNIX;CPUARMEL';
@@ -1217,7 +1217,7 @@ unit i_bsd;
             system       : system_aarch64_darwin;
             name         : 'Darwin for AArch64';
             shortname    : 'Darwin';
-            flags        : [tf_p_ext_support,tf_requires_proper_alignment,tf_files_case_sensitive,tf_smartlink_sections,tf_dwarf_relative_addresses,tf_dwarf_only_local_labels,tf_pic_default,tf_has_winlike_resources];
+            flags        : [tf_p_ext_support,tf_requires_proper_alignment,tf_files_case_sensitive,tf_smartlink_sections,tf_dwarf_relative_addresses,tf_dwarf_only_local_labels,tf_pic_default,tf_has_winlike_resources,tf_supports_symbolorderfile];
             cpu          : cpu_aarch64;
             unit_env     : 'BSDUNITS';
             extradefines : 'UNIX;BSD;HASUNIX';

+ 65 - 9
compiler/systems/t_bsd.pas

@@ -66,6 +66,7 @@ implementation
       Function  WriteResponseFile(isdll:boolean) : Boolean;
       function GetDarwinCrt1ObjName(isdll: boolean): TCmdStr;
       Function GetDarwinPrtobjName(isdll: boolean): TCmdStr;
+      Function WriteSymbolOrderFile: TCmdStr;
     public
       constructor Create;override;
       procedure SetDefaultInfo;override;
@@ -173,8 +174,8 @@ begin
        begin
          if not(target_info.system in systems_darwin) then
            begin
-             ExeCmd[1]:='ld $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP $MAP -L. -o $EXE $CATRES $FILELIST';
-             DllCmd[1]:='ld $TARGET $EMUL $OPT $MAP -shared -L. -o $EXE $CATRES $FILELIST'
+             ExeCmd[1]:='ld $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP $MAP $ORDERSYMS -L. -o $EXE $CATRES $FILELIST';
+             DllCmd[1]:='ld $TARGET $EMUL $OPT $MAP $ORDERSYMS -shared -L. -o $EXE $CATRES $FILELIST'
            end
          else
            begin
@@ -193,22 +194,22 @@ begin
                programs with problems that require Valgrind will have more
                than 60KB of data (first 4KB of address space is always invalid)
              }
-               ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP $MAP -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST';
+               ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP $MAP $ORDERSYMS -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST';
              if not(cs_gdb_valgrind in current_settings.globalswitches) then
                ExeCmd[1]:=ExeCmd[1]+' -pagezero_size 0x10000';
 {$else ndef cpu64bitaddr}
-             ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP $MAP -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST';
+             ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP $MAP $ORDERSYMS -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST';
 {$endif ndef cpu64bitaddr}
              if (apptype<>app_bundle) then
-               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS $MAP -dynamic -dylib -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST'
+               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS $MAP $ORDERSYMS -dynamic -dylib -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST'
              else
-               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS $MAP -dynamic -bundle -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST'
+               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS $MAP $ORDERSYMS -dynamic -bundle -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST'
            end
        end
      else
        begin
-         ExeCmd[1]:='ld $TARGET $EMUL $OPT $DYNLINK $STATIC  $GCSECTIONS $STRIP $MAP -L. -o $EXE $RES';
-         DllCmd[1]:='ld $TARGET $EMUL $OPT $INIT $FINI $SONAME $MAP -shared -L. -o $EXE $RES';
+         ExeCmd[1]:='ld $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP $MAP $ORDERSYMS -L. -o $EXE $RES';
+         DllCmd[1]:='ld $TARGET $EMUL $OPT $INIT $FINI $SONAME $MAP $ORDERSYMS -shared -L. -o $EXE $RES';
        end;
      if not(target_info.system in systems_darwin) then
        DllCmd[2]:='strip --strip-unneeded $EXE'
@@ -467,6 +468,30 @@ begin
 end;
 
 
+function tlinkerbsd.WriteSymbolOrderFile: TCmdStr;
+  var
+    item: TCmdStrListItem;
+    symfile: TScript;
+  begin
+    result:='';
+    { only for darwin for now; can also enable for other platforms when using
+      the LLVM linker }
+    if (OrderedSymbols.Empty) or
+       not(tf_supports_symbolorderfile in target_info.flags) then
+      exit;
+    symfile:=TScript.Create(outputexedir+'symbol_order.fpc');
+    item:=TCmdStrListItem(OrderedSymbols.First);
+    while assigned(item) do
+      begin
+        symfile.add(item.str);
+        item:=TCmdStrListItem(item.next);
+      end;
+    symfile.WriteToDisk;
+    result:=symfile.fn;
+    symfile.Free;
+  end;
+
+
 Function TLinkerBSD.WriteResponseFile(isdll:boolean) : Boolean;
 Var
   linkres      : TLinkRes;
@@ -777,7 +802,8 @@ var
   targetstr,
   emulstr,
   extdbgbinstr,
-  extdbgcmdstr: TCmdStr;
+  extdbgcmdstr,
+  ordersymfile: TCmdStr;
   linkscript: TAsmScript;
   DynLinkStr : string[60];
   GCSectionsStr,
@@ -861,6 +887,9 @@ begin
 { Write used files and libraries }
   WriteResponseFile(false);
 
+{ Write symbol order file }
+  ordersymfile:=WriteSymbolOrderFile;
+
 { Call linker }
   SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
   Replace(cmdstr,'$EXE',maybequoted(current_module.exefilename));
@@ -870,6 +899,16 @@ begin
   Replace(cmdstr,'$MAP',mapstr);
   Replace(cmdstr,'$CATRES',CatFileContent(outputexedir+Info.ResName));
   Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
+  if ordersymfile<>'' then
+    begin
+      if target_info.system in systems_darwin then
+        Replace(cmdstr,'$ORDERSYMS','-order_file '+maybequoted(ordersymfile))
+      else
+        Replace(cmdstr,'$ORDERSYMS','--symbol-ordering-file '+maybequoted(ordersymfile))
+    end
+  else
+    Replace(cmdstr,'$ORDERSYMS','');
+
   if (LdSupportsNoResponseFile) and (source_info.system in systems_all_windows) then
     Replace(cmdstr,'$FILELIST','-filelist '+maybequoted(outputexedir+'linkfiles.res'))
   else
@@ -922,6 +961,8 @@ begin
   if (success) and not(cs_link_nolink in current_settings.globalswitches) then
    begin
      DeleteFile(outputexedir+Info.ResName);
+     if ordersymfile<>'' then
+       DeleteFile(ordersymfile);
      if LdSupportsNoResponseFile Then
        begin
          DeleteFile(linkscript.fn);
@@ -946,6 +987,7 @@ var
   binstr,
   cmdstr,
   mapstr,
+  ordersymfile,
   targetstr,
   emulstr,
   extdbgbinstr,
@@ -964,6 +1006,9 @@ begin
 { Write used files and libraries }
   WriteResponseFile(true);
 
+{ Write symbol order file }
+  ordersymfile:=WriteSymbolOrderFile;
+
   if (cs_link_smart in current_settings.globalswitches) and
      (tf_smartlink_sections in target_info.flags) then
     if not(target_info.system in systems_darwin) then
@@ -1014,6 +1059,15 @@ begin
   Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
   Replace(cmdstr,'$SONAME',SoNameStr);
   Replace(cmdstr,'$MAP',mapstr);
+  if ordersymfile<>'' then
+    begin
+      if target_info.system in systems_darwin then
+        Replace(cmdstr,'$ORDERSYMS','-order_file '+maybequoted(ordersymfile))
+      else
+        Replace(cmdstr,'$ORDERSYMS','--symbol-ordering-file '+maybequoted(ordersymfile))
+    end
+  else
+    Replace(cmdstr,'$ORDERSYMS','');
   if (target_info.system in systems_darwin) then
     Replace(cmdstr,'$PRTOBJ',GetDarwinPrtobjName(true));
   BinStr:=FindUtil(utilsprefix+BinStr);
@@ -1080,6 +1134,8 @@ begin
   if (success) and not(cs_link_nolink in current_settings.globalswitches) then
     begin
       DeleteFile(outputexedir+Info.ResName);
+      if ordersymfile<>'' then
+        DeleteFile(ordersymfile);
       if LdSupportsNoResponseFile Then
         begin
           DeleteFile(linkscript.fn);

+ 4 - 0
compiler/utils/ppuutils/ppudump.pp

@@ -3840,6 +3840,10 @@ begin
            if not silent then
              ReadContainer('Resource file: ');
 
+         iborderedsymbols:
+           if not silent then
+             ReadContainer('Ordered symbol: ');
+
          iberror :
            begin
              WriteError('Error in PPU');