* Link ordering working FreeBSD implementation

git-svn-id: trunk@3894 -
This commit is contained in:
marco 2006-06-19 14:17:45 +00:00
parent 8e952b634d
commit 2a5332e3bd
5 changed files with 74 additions and 52 deletions

View File

@ -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.

View File

@ -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;

View File

@ -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
*****************************************************************************}

View File

@ -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

View File

@ -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;