ソースを参照

* Link ordering working FreeBSD implementation

git-svn-id: trunk@3894 -
marco 19 年 前
コミット
2a5332e3bd
5 ファイル変更74 行追加52 行削除
  1. 9 8
      compiler/cclasses.pas
  2. 1 1
      compiler/globtype.pas
  3. 9 1
      compiler/link.pas
  4. 10 5
      compiler/options.pas
  5. 45 37
      compiler/systems/t_bsd.pas

+ 9 - 8
compiler/cclasses.pas

@@ -520,7 +520,7 @@ type
        end;
 
 
-Const WeightDefault = 100;  
+Const WeightDefault = 1000;  
 
 Type
   TLinkRec = record 
@@ -3344,7 +3344,7 @@ end;
 
 function  TLinkStrMap.AddWeight(keyvalue:String):boolean;
 
-var i    : Longint;
+var i,j    : Longint;
     Code : Word;
     s    : AnsiString;
 
@@ -3354,10 +3354,10 @@ begin
   if i=0 then 
     exit;
   s:=Copy(KeyValue,i+1,length(KeyValue)-i);  
-  val(s,i,code);
-  if code<>0 Then
+  val(s,j,code);
+  if code=0 Then
     begin
-      Add(Copy(KeyValue,1,i-1),'',i);
+      Add(Copy(KeyValue,1,i-1),'',j);
       AddWeight:=True;
     end;  
 end;
@@ -3371,7 +3371,7 @@ begin
  while i<=k do
    begin
      j:=i;
-     while (i<=k) and (keys[i]<>';') do 
+     while (i<=k) and (keys[i]<>',') do 
        inc(i);
      add(copy(keys,j,i-j),'',weight);  
      inc(i);
@@ -3407,7 +3407,8 @@ begin
    lookup:=-1;
    i:=0;
    {$B-}
-   while (i<itemcnt) and (fmap[i].key<>key) do inc(i);
+   while (i<itemcnt) and (fmap[i].key<>key) do 
+     inc(i);
    {$B+}
    if i<>itemcnt then
       lookup:=i;
@@ -3452,7 +3453,6 @@ begin
         dest.add(LibN)
       else 
         dest.addseries(fmap[r].value);
-
     end;
 end;  
 
@@ -3470,3 +3470,4 @@ end;
 
 
 end.
+ 

+ 1 - 1
compiler/globtype.pas

@@ -142,7 +142,7 @@ than 255 characters. That's why using Ansi Strings}
          cs_link_nolink,cs_link_static,cs_link_smart,cs_link_shared,cs_link_deffile,
          cs_link_strip,cs_link_staticflag,cs_link_on_target,cs_link_extern,cs_link_opt_vtable,
          cs_link_opt_used_sections,
-         cs_link_map,cs_link_pthread
+         cs_link_map,cs_link_pthread,cs_link_no_default_lib_order
        );
        tglobalswitches = set of tglobalswitch;
 

+ 9 - 1
compiler/link.pas

@@ -65,6 +65,7 @@ Type
        Function  MakeStaticLibrary:boolean;virtual;
        procedure ExpandAndApplyOrder(var Src:TStringList);
        procedure LoadPredefinedLibraryOrder;virtual; 
+       function  ReOrderEntries : boolean;
      end;
 
     TExternalLinker = class(TLinker)
@@ -507,10 +508,11 @@ begin
   if (LinkLibraryAliases.count=0) and (LinkLibraryOrder.Count=0) Then 
     exit;
   p:=TLinkStrMap.Create;
-  
+    
   // expand libaliases, clears src
   LinkLibraryAliases.expand(src,p);
   
+  // writeln(src.count,' ',p.count,' ',linklibraryorder.count,' ',linklibraryaliases.count);
   // apply order
   p.UpdateWeights(LinkLibraryOrder);  
   p.SortOnWeight;
@@ -526,6 +528,12 @@ procedure TLinker.LoadPredefinedLibraryOrder;
 begin
 end;
 
+function  TLinker.ReOrderEntries : boolean;
+
+begin
+  result:=(LinkLibraryOrder.count>0) or (LinkLibraryAliases.count>0);
+end;
+
 {*****************************************************************************
                               TEXTERNALLINKER
 *****************************************************************************}

+ 10 - 5
compiler/options.pas

@@ -1277,8 +1277,9 @@ begin
                         DefaultReplacements(utilsprefix);
                         More:='';
                       end;
-                    'L' : begin  // -XLO is link order -XLA is link alias
-                            if (j=length(more)) or not ((more[j+1]='O') or (more[j+1]='A')) then
+                    'L' : begin  // -XLO is link order -XLA is link alias. -XLD avoids load defaults.
+                                 // these are not aggregable.
+                            if (j=length(more)) or not (more[j+1] in ['O','A','D']) then
                               IllegalPara(opt)
                             else
                               begin
@@ -1290,11 +1291,15 @@ begin
                                        end;
                                  'O' : begin
                                         s:=Copy(more,3,length(More)-2);
-                                        if not LinkLibraryAliases.AddWeight(s) Then
+                                        if not LinkLibraryOrder.AddWeight(s) Then
                                            IllegalPara(opt);
                                        end;
-                                   end;     
-                              end;
+                                 'D' : include(initglobalswitches,cs_link_no_default_lib_order)
+                                else
+                                  IllegalPara(opt);
+                                 end; {case}
+                                j:=length(more);    
+                              end; {else begin}
                           end;
                     'S' :
                       begin

+ 45 - 37
compiler/systems/t_bsd.pas

@@ -79,6 +79,7 @@ implementation
       procedure SetDefaultInfo;override;
       function  MakeExecutable:boolean;override;
       function  MakeSharedLibrary:boolean;override;
+      procedure LoadPredefinedLibraryOrder; override;
     end;
 
 
@@ -292,27 +293,30 @@ begin
        DllCmd[2]:='strip --strip-unneeded $EXE'
      else
        DllCmd[2]:='strip -x $EXE';
-     { first try glibc2 }
-{$ifdef GLIBC2} {Keep linux code in place. FBSD might go to a different
-                                glibc too once}
-     DynamicLinker:='/lib/ld-linux.so.2';
-     if FileExists(DynamicLinker) then
-      begin
-        Glibc2:=true;
-        { Check for 2.0 files, else use the glibc 2.1 stub }
-        if FileExists('/lib/ld-2.0.*') then
-         Glibc21:=false
-        else
-         Glibc21:=true;
-      end
-     else
-      DynamicLinker:='/lib/ld-linux.so.1';
-{$else}
       DynamicLinker:='';
-{$endif}
    end;
 end;
 
+procedure TLinkerBSD.LoadPredefinedLibraryOrder;
+// put your linkorder/linkalias overrides here. 
+// Note: assumes only called when reordering/aliasing is used.
+Begin
+  if not(target_info.system in [system_powerpc_darwin,system_i386_darwin]) then
+    begin
+      if (target_info.system =system_i386_freebsd) and 
+             not (cs_link_no_default_lib_order in  aktglobalswitches) Then   
+        Begin
+          LinkLibraryOrder.add('gcc','',15);		
+          LinkLibraryOrder.add('c','',50);		     // c and c_p mutual. excl?	
+          LinkLibraryOrder.add('c_p','',55);			
+          LinkLibraryOrder.add('pthread','',75);	     // pthread and c_r should be mutually exclusive
+          LinkLibraryOrder.add('c_r','',76);		 		
+          LinkLibraryOrder.add('kvm','',80);		     // must be before ncurses
+          if (cs_link_pthread in aktglobalswitches) Then     // convert libpthread to libc_r.
+            LinkLibraryAliases.add('pthread','c_r');
+        end;
+    end;
+End;
 
 Function TLinkerBSD.WriteResponseFile(isdll:boolean) : Boolean;
 Var
@@ -327,27 +331,29 @@ Var
   linkdynamic,
   linklibc     : boolean;
   Fl1,Fl2      : Boolean;
-
+  IsDarwin     : Boolean;
+  ReOrder      : Boolean;
+  
 begin
   WriteResponseFile:=False;
+  ReOrder:=False;
+  IsDarwin:=target_info.system in [system_powerpc_darwin,system_i386_darwin];
 { set special options for some targets }
-  if not(target_info.system in [system_powerpc_darwin,system_i386_darwin]) then
+  if not IsDarwin Then
     begin
-      linkdynamic:=not(SharedLibFiles.empty);
-      linklibc:=(SharedLibFiles.Find('c')<>nil);
-      linkpthread:=(SharedLibFiles.Find('pthread')<>nil);
-      if (target_info.system =system_i386_freebsd) and linkpthread Then
-        Begin
-          if not (cs_link_pthread in aktglobalswitches) Then
-            begin
-              {delete pthreads from list, in this case it is in libc_r}
-              SharedLibFiles.Remove(SharedLibFiles.Find('pthread').str);
-              LibrarySuffix:='r';
-            end;
-        End;
       prtobj:='prt0';
       cprtobj:='cprt0';
       gprtobj:='gprt0';
+      linkdynamic:=not(SharedLibFiles.empty);
+      linklibc:=(SharedLibFiles.Find('c')<>nil);
+      // this one is a bit complex.
+      // Only reorder for now if -XL or -XO params are given
+      // or when -Xf.
+      reorder:= linklibc and
+                ( 
+                  ReorderEntries
+                   or
+                  (cs_link_pthread in aktglobalswitches));
       if cs_profile in aktmoduleswitches then
        begin
          prtobj:=gprtobj;
@@ -360,6 +366,9 @@ begin
          if linklibc then
           prtobj:=cprtobj;
        end;
+      if reorder Then
+        ExpandAndApplyOrder(SharedLibFiles);
+      // after this point addition of shared libs not allowed.  
     end
   else
     begin
@@ -419,7 +428,7 @@ begin
    LinkRes.AddFileName(FindObjectFile(prtobj,'',false));
   { try to add crti and crtbegin if linking to C }
   if linklibc and
-     not(target_info.system in [system_powerpc_darwin,system_i386_darwin]) then
+     not IsDarwin Then
    begin
      if librarysearchpath.FindFile('crtbegin.o',s) then
       LinkRes.AddFileName(s);
@@ -459,7 +468,7 @@ begin
      While not SharedLibFiles.Empty do
       begin
         S:=SharedLibFiles.GetFirst;
-        if s<>'c' then
+        if (s<>'c') or reorder then
          begin
            i:=Pos(target_info.sharedlibext,S);
            if i>0 then
@@ -473,7 +482,7 @@ begin
          end;
       end;
      { be sure that libc is the last lib }
-     if linklibc then
+     if linklibc and not reorder then
        Begin
          If LibrarySuffix=' ' Then
           LinkRes.Add('-lc')
@@ -492,7 +501,7 @@ begin
    end;
   { objects which must be at the end }
   if linklibc and
-     not(target_info.system in [system_powerpc_darwin,system_i386_darwin]) then
+     not IsDarwin Then
    begin
      Fl1:=librarysearchpath.FindFile('crtend.o',s1);
      Fl2:=librarysearchpath.FindFile('crtn.o',s2);
@@ -508,8 +517,7 @@ begin
    end;
   { ignore the fact that our relocations are in non-writable sections, }
   { will be fixed once we have pic support                             }
-  if isdll and
-     (target_info.system in [system_powerpc_darwin,system_i386_darwin]) then
+  if isdll and IsDarwin Then
     LinkRes.Add('-read_only_relocs suppress');
 { Write and Close response }
   linkres.writetodisk;