Browse Source

* fixed and enabled smartlinking on Darwin by adding more .reference
statements (some to work around linker bugs, most because they were
really missing)

git-svn-id: trunk@8673 -

Jonas Maebe 18 năm trước cách đây
mục cha
commit
5a0a6d0d9e

+ 0 - 4
compiler/aggas.pas

@@ -1070,13 +1070,9 @@ implementation
           AsmWriteLn(target_asm.comment+'End asmlist '+AsmlistTypeStr[hal]);
           AsmWriteLn(target_asm.comment+'End asmlist '+AsmlistTypeStr[hal]);
         end;
         end;
 
 
-{
-      Result doesn't work properly yet due to a bug in Apple's linker
-
       if (cs_create_smart in current_settings.moduleswitches) and
       if (cs_create_smart in current_settings.moduleswitches) and
          (target_info.system in systems_darwin) then
          (target_info.system in systems_darwin) then
         AsmWriteLn(#9'.subsections_via_symbols');
         AsmWriteLn(#9'.subsections_via_symbols');
-}
 
 
       AsmLn;
       AsmLn;
 {$ifdef EXTDEBUG}
 {$ifdef EXTDEBUG}

+ 5 - 2
compiler/cresstr.pas

@@ -215,10 +215,13 @@ uses
         new_section(current_asmdata.asmlists[al_resourcestrings],sec_data,make_mangledname('RESSTR',current_module.localsymtable,'3_END'),sizeof(aint));
         new_section(current_asmdata.asmlists[al_resourcestrings],sec_data,make_mangledname('RESSTR',current_module.localsymtable,'3_END'),sizeof(aint));
         current_asmdata.AsmLists[al_resourcestrings].concat(tai_symbol.createname_global(
         current_asmdata.AsmLists[al_resourcestrings].concat(tai_symbol.createname_global(
           make_mangledname('RESSTR',current_module.localsymtable,'END'),AT_DATA,0));
           make_mangledname('RESSTR',current_module.localsymtable,'END'),AT_DATA,0));
-        { the darwin/ppc64 assembler or linker seems to have trouble       }
+        { The darwin/ppc64 assembler or linker seems to have trouble       }
         { if a section ends with a global label without any data after it. }
         { if a section ends with a global label without any data after it. }
         { So for safety, just put a dummy value here.                      }
         { So for safety, just put a dummy value here.                      }
-        if (target_info.system = system_powerpc64_darwin) then   
+        { Further, the regular linker also kills this symbol when turning  }
+        { on smart linking in case no value appears after it, so put the   }
+        { dummy byte there always                                          }
+        if (target_info.system in systems_darwin) then   
           current_asmdata.asmlists[al_resourcestrings].concat(Tai_const.create_8bit(0));
           current_asmdata.asmlists[al_resourcestrings].concat(Tai_const.create_8bit(0));
       end;
       end;
 
 

+ 8 - 3
compiler/dbgstabs.pas

@@ -1110,10 +1110,15 @@ implementation
             if assigned(pd.localst) and
             if assigned(pd.localst) and
                (pd.localst.symtabletype=localsymtable) then
                (pd.localst.symtabletype=localsymtable) then
               write_symtable_syms(templist,pd.localst);
               write_symtable_syms(templist,pd.localst);
-            { add a "size" stab as described in the last paragraph of 2.5 at  }
+
+            { Add a "size" stab as described in the last paragraph of 2.5 at  }
             { http://sourceware.org/gdb/current/onlinedocs/stabs_2.html#SEC12 }
             { http://sourceware.org/gdb/current/onlinedocs/stabs_2.html#SEC12 }
-//            templist.concat(Tai_stab.create(stab_stabs,
-//              strpnew('"",'+tostr(N_FUNCTION)+',0,0,'+stabsendlabel.name+'-'+pd.mangledname)));
+            { This works at least on Darwin (and is needed on Darwin to get   }
+            { correct smartlinking of stabs), but I don't know which binutils }
+            { version is required on other platforms                          }
+            if (target_info.system in systems_darwin) then
+              templist.concat(Tai_stab.create(stab_stabs,
+                strpnew('"",'+tostr(N_FUNCTION)+',0,0,'+stabsendlabel.name+'-'+pd.mangledname)));
 
 
             { after the endtai, because the ".size" must come before it }
             { after the endtai, because the ".size" must come before it }
             current_asmdata.asmlists[al_procedures].insertlistafter(pd.procendtai,templist);
             current_asmdata.asmlists[al_procedures].insertlistafter(pd.procendtai,templist);

+ 13 - 9
compiler/ncgcon.pas

@@ -267,7 +267,7 @@ implementation
     procedure tcgstringconstnode.pass_generate_code;
     procedure tcgstringconstnode.pass_generate_code;
       var
       var
          hp1,hp2 : tai;
          hp1,hp2 : tai;
-         l1,l2,
+         l1,
          lastlabel   : tasmlabel;
          lastlabel   : tasmlabel;
          lastlabelhp : tai;
          lastlabelhp : tai;
          pc       : pchar;
          pc       : pchar;
@@ -429,19 +429,21 @@ implementation
                            else
                            else
                              begin
                              begin
                                 current_asmdata.getdatalabel(l1);
                                 current_asmdata.getdatalabel(l1);
-                                current_asmdata.getdatalabel(l2);
-                                current_asmdata.asmlists[al_typedconsts].concat(Tai_label.Create(l2));
                                 current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_sym(l1));
                                 current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_sym(l1));
                                 current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_aint(-1));
                                 current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_aint(-1));
                                 current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_aint(len));
                                 current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_aint(len));
+                                { make sure the string doesn't get dead stripped if the header is referenced }
+                                if (target_info.system in systems_darwin) then
+                                  current_asmdata.asmlists[al_typedconsts].concat(tai_directive.create(asd_reference,l1.name));
                                 current_asmdata.asmlists[al_typedconsts].concat(Tai_label.Create(l1));
                                 current_asmdata.asmlists[al_typedconsts].concat(Tai_label.Create(l1));
+                                { ... and vice versa }
+                                if (target_info.system in systems_darwin) then
+                                  current_asmdata.asmlists[al_typedconsts].concat(tai_directive.create(asd_reference,lab_str.name));
                                 { include also terminating zero }
                                 { include also terminating zero }
                                 getmem(pc,len+1);
                                 getmem(pc,len+1);
                                 move(value_str^,pc^,len);
                                 move(value_str^,pc^,len);
                                 pc[len]:=#0;
                                 pc[len]:=#0;
                                 current_asmdata.asmlists[al_typedconsts].concat(Tai_string.Create_pchar(pc,len+1));
                                 current_asmdata.asmlists[al_typedconsts].concat(Tai_string.Create_pchar(pc,len+1));
-                                { return the offset of the real string }
-                                lab_str:=l2;
                              end;
                              end;
                         end;
                         end;
                       cst_widestring:
                       cst_widestring:
@@ -452,8 +454,6 @@ implementation
                            else
                            else
                              begin
                              begin
                                 current_asmdata.getdatalabel(l1);
                                 current_asmdata.getdatalabel(l1);
-                                current_asmdata.getdatalabel(l2);
-                                current_asmdata.asmlists[al_typedconsts].concat(Tai_label.Create(l2));
                                 current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_sym(l1));
                                 current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_sym(l1));
 
 
                                 { we use always UTF-16 coding for constants }
                                 { we use always UTF-16 coding for constants }
@@ -466,13 +466,17 @@ implementation
                                     current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_aint(-1));
                                     current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_aint(-1));
                                     current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_aint(len*cwidechartype.size));
                                     current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_aint(len*cwidechartype.size));
                                   end;
                                   end;
+                                { make sure the string doesn't get dead stripped if the header is referenced }
+                                if (target_info.system in systems_darwin) then
+                                  current_asmdata.asmlists[al_typedconsts].concat(tai_directive.create(asd_reference,l1.name));
                                 current_asmdata.asmlists[al_typedconsts].concat(Tai_label.Create(l1));
                                 current_asmdata.asmlists[al_typedconsts].concat(Tai_label.Create(l1));
+                                { ... and vice versa }
+                                if (target_info.system in systems_darwin) then
+                                  current_asmdata.asmlists[al_typedconsts].concat(tai_directive.create(asd_reference,lab_str.name));
                                 for i:=0 to len-1 do
                                 for i:=0 to len-1 do
                                   current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_16bit(pcompilerwidestring(value_str)^.data[i]));
                                   current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_16bit(pcompilerwidestring(value_str)^.data[i]));
                                 { terminating zero }
                                 { terminating zero }
                                 current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_16bit(0));
                                 current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_16bit(0));
-                                { return the offset of the real string }
-                                lab_str:=l2;
                              end;
                              end;
                         end;
                         end;
                       cst_shortstring:
                       cst_shortstring:

+ 14 - 1
compiler/ncgutil.pas

@@ -1927,18 +1927,31 @@ implementation
 
 
     procedure gen_proc_symbol(list:TAsmList);
     procedure gen_proc_symbol(list:TAsmList);
       var
       var
-        item : TCmdStrListItem;
+        item,
+        previtem : TCmdStrListItem;
       begin
       begin
+        previtem:=nil;
         item := TCmdStrListItem(current_procinfo.procdef.aliasnames.first);
         item := TCmdStrListItem(current_procinfo.procdef.aliasnames.first);
         while assigned(item) do
         while assigned(item) do
           begin
           begin
+            { "double link" all procedure entry symbols via .reference }
+            { directives on darwin, because otherwise the linker       }
+            { sometimes strips the procedure if only on of the symbols }
+            { is referenced                                            }
+            if assigned(previtem) and
+               (target_info.system in systems_darwin) then
+              list.concat(tai_directive.create(asd_reference,item.str));
             if (cs_profile in current_settings.moduleswitches) or
             if (cs_profile in current_settings.moduleswitches) or
               (po_global in current_procinfo.procdef.procoptions) then
               (po_global in current_procinfo.procdef.procoptions) then
               list.concat(Tai_symbol.createname_global(item.str,AT_FUNCTION,0))
               list.concat(Tai_symbol.createname_global(item.str,AT_FUNCTION,0))
             else
             else
               list.concat(Tai_symbol.createname(item.str,AT_FUNCTION,0));
               list.concat(Tai_symbol.createname(item.str,AT_FUNCTION,0));
+            if assigned(previtem) and
+               (target_info.system in systems_darwin) then
+              list.concat(tai_directive.create(asd_reference,previtem.str));
             if tf_use_function_relative_addresses in target_info.flags then
             if tf_use_function_relative_addresses in target_info.flags then
               list.concat(Tai_function_name.create(item.str));
               list.concat(Tai_function_name.create(item.str));
+            previtem:=item;
             item := TCmdStrListItem(item.next);
             item := TCmdStrListItem(item.next);
           end;
           end;
 
 

+ 17 - 1
compiler/ptconst.pas

@@ -631,7 +631,7 @@ implementation
           strlength : aint;
           strlength : aint;
           strval    : pchar;
           strval    : pchar;
           strch     : char;
           strch     : char;
-          ll        : tasmlabel;
+          ll,ll2    : tasmlabel;
           ca        : pchar;
           ca        : pchar;
         begin
         begin
           n:=comp_expr(true);
           n:=comp_expr(true);
@@ -699,10 +699,18 @@ implementation
                        begin
                        begin
                          current_asmdata.getdatalabel(ll);
                          current_asmdata.getdatalabel(ll);
                          list.concat(Tai_const.Create_sym(ll));
                          list.concat(Tai_const.Create_sym(ll));
+                         current_asmdata.getdatalabel(ll2);
                          current_asmdata.asmlists[al_const].concat(tai_align.create(const_align(sizeof(aint))));
                          current_asmdata.asmlists[al_const].concat(tai_align.create(const_align(sizeof(aint))));
+                         current_asmdata.asmlists[al_const].concat(Tai_label.Create(ll2));
                          current_asmdata.asmlists[al_const].concat(Tai_const.Create_aint(-1));
                          current_asmdata.asmlists[al_const].concat(Tai_const.Create_aint(-1));
                          current_asmdata.asmlists[al_const].concat(Tai_const.Create_aint(strlength));
                          current_asmdata.asmlists[al_const].concat(Tai_const.Create_aint(strlength));
+                         { make sure the string doesn't get dead stripped if the header is referenced }
+                         if (target_info.system in systems_darwin) then
+                           current_asmdata.asmlists[al_typedconsts].concat(tai_directive.create(asd_reference,ll.name));
                          current_asmdata.asmlists[al_const].concat(Tai_label.Create(ll));
                          current_asmdata.asmlists[al_const].concat(Tai_label.Create(ll));
+                         { ... and vice versa }
+                         if (target_info.system in systems_darwin) then
+                           list.concat(tai_directive.create(asd_reference,ll2.name));
                          getmem(ca,strlength+1);
                          getmem(ca,strlength+1);
                          move(strval^,ca^,strlength);
                          move(strval^,ca^,strlength);
                          { The terminating #0 to be stored in the .data section (JM) }
                          { The terminating #0 to be stored in the .data section (JM) }
@@ -719,7 +727,9 @@ implementation
                        begin
                        begin
                          current_asmdata.getdatalabel(ll);
                          current_asmdata.getdatalabel(ll);
                          list.concat(Tai_const.Create_sym(ll));
                          list.concat(Tai_const.Create_sym(ll));
+                         current_asmdata.getdatalabel(ll2);
                          current_asmdata.asmlists[al_const].concat(tai_align.create(const_align(sizeof(aint))));
                          current_asmdata.asmlists[al_const].concat(tai_align.create(const_align(sizeof(aint))));
+                         current_asmdata.asmlists[al_const].concat(Tai_label.Create(ll2));
                          if tf_winlikewidestring in target_info.flags then
                          if tf_winlikewidestring in target_info.flags then
                            current_asmdata.asmlists[al_const].concat(Tai_const.Create_32bit(strlength*cwidechartype.size))
                            current_asmdata.asmlists[al_const].concat(Tai_const.Create_32bit(strlength*cwidechartype.size))
                          else
                          else
@@ -727,7 +737,13 @@ implementation
                              current_asmdata.asmlists[al_const].concat(Tai_const.Create_aint(-1));
                              current_asmdata.asmlists[al_const].concat(Tai_const.Create_aint(-1));
                              current_asmdata.asmlists[al_const].concat(Tai_const.Create_aint(strlength*cwidechartype.size));
                              current_asmdata.asmlists[al_const].concat(Tai_const.Create_aint(strlength*cwidechartype.size));
                            end;
                            end;
+                         { make sure the string doesn't get dead stripped if the header is referenced }
+                         if (target_info.system in systems_darwin) then
+                           current_asmdata.asmlists[al_typedconsts].concat(tai_directive.create(asd_reference,ll.name));
                          current_asmdata.asmlists[al_const].concat(Tai_label.Create(ll));
                          current_asmdata.asmlists[al_const].concat(Tai_label.Create(ll));
+                         { ... and vice versa }
+                         if (target_info.system in systems_darwin) then
+                           current_asmdata.asmlists[al_typedconsts].concat(tai_directive.create(asd_reference,ll2.name));
                          for i:=0 to strlength-1 do
                          for i:=0 to strlength-1 do
                            current_asmdata.asmlists[al_const].concat(Tai_const.Create_16bit(pcompilerwidestring(strval)^.data[i]));
                            current_asmdata.asmlists[al_const].concat(Tai_const.Create_16bit(pcompilerwidestring(strval)^.data[i]));
                          { ending #0 }
                          { ending #0 }