* 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 -
This commit is contained in:
Jonas Maebe 2007-09-28 22:48:41 +00:00
parent 827d380691
commit 5a0a6d0d9e
6 changed files with 57 additions and 20 deletions

View File

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

View File

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

View File

@ -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, { This works at least on Darwin (and is needed on Darwin to get }
// strpnew('"",'+tostr(N_FUNCTION)+',0,0,'+stabsendlabel.name+'-'+pd.mangledname))); { 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);

View File

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

View File

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

View File

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