From ae4cdf25f83e0561d2b767e6e4bc53567d4cc0a8 Mon Sep 17 00:00:00 2001 From: sergei Date: Wed, 13 Jul 2011 23:45:28 +0000 Subject: [PATCH] + aggas.pas: Write section attributes when long section names are used for smart linking (enabled for win32 and win64). It is needed because GAS does not understand that '.text.something' is part of '.text' and assigns default attributes (writable data) to all such sections, which is not the desired behavior. git-svn-id: trunk@17989 - --- compiler/aggas.pas | 78 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 68 insertions(+), 10 deletions(-) diff --git a/compiler/aggas.pas b/compiler/aggas.pas index 9850bfe338..3238142494 100644 --- a/compiler/aggas.pas +++ b/compiler/aggas.pas @@ -45,6 +45,7 @@ interface TGNUAssembler=class(texternalassembler) protected function sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;virtual; + function sectionattrs_coff(atype:TAsmSectiontype):string;virtual; procedure WriteSection(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder); procedure WriteExtraHeader;virtual; procedure WriteInstruction(hp: tai); @@ -238,6 +239,19 @@ implementation result := target_asm.labelprefix+'$set$'+tostr(setcount); end; + function is_smart_section(atype:TAsmSectiontype):boolean; + begin + { For bss we need to set some flags that are target dependent, + it is easier to disable it for smartlinking. It doesn't take up + filespace } + result:=not(target_info.system in systems_darwin) and + create_smartlink_sections and + (atype<>sec_toc) and + (atype<>sec_user) and + { on embedded systems every byte counts, so smartlink bss too } + ((atype<>sec_bss) or (target_info.system in systems_embedded)); + end; + function TGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string; const secnames : array[TAsmSectiontype] of string[length('__DATA, __datacoal_nt,coalesced')] = ('','', @@ -404,16 +418,7 @@ implementation if atype=sec_user then secname:=aname; - { For bss we need to set some flags that are target dependent, - it is easier to disable it for smartlinking. It doesn't take up - filespace } - if not(target_info.system in systems_darwin) and - create_smartlink_sections and - (aname<>'') and - (atype<>sec_toc) and - (atype<>sec_user) and - { on embedded systems every byte counts, so smartlink bss too } - ((atype<>sec_bss) or (target_info.system in systems_embedded)) then + if is_smart_section(atype) and (aname<>'') then begin case aorder of secorder_begin : @@ -430,6 +435,45 @@ implementation end; + function TGNUAssembler.sectionattrs_coff(atype:TAsmSectiontype):string; + begin + case atype of + sec_code, sec_init, sec_fini, sec_stub: + result:='x'; + + { TODO: must be individual for each section } + sec_user: + result:='d'; + + sec_data, sec_data_lazy, sec_data_nonlazy, sec_fpc, + sec_idata2, sec_idata4, sec_idata5, sec_idata6, sec_idata7: + result:='d'; + + { TODO: these need a fix to become read-only } + sec_rodata, sec_rodata_norel: + result:='d'; + + sec_bss: + result:='b'; + + { TODO: Somewhat questionable. FPC does not allow initialized threadvars, + so no sense to mark it as containing data. But Windows allows it to + contain data, and Linux even has .tdata and .tbss } + sec_threadvar: + result:='b'; + + sec_pdata, sec_edata, sec_eh_frame, sec_toc: + result:='r'; + + sec_stab,sec_stabstr, + sec_debug_frame,sec_debug_info,sec_debug_line,sec_debug_abbrev: + result:='n'; + else + result:=''; { defaults to data+load } + end; + end; + + procedure TGNUAssembler.WriteSection(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder); var s : string; @@ -484,6 +528,20 @@ implementation internalerror(2006031101); end; end; + else + { GNU AS won't recognize '.text.n_something' section name as belonging + to '.text' and assigns default attributes to it, which is not + always correct. We have to fix it. + + TODO: This likely applies to all systems which smartlink without + creating libraries } + if (target_info.system in [system_i386_win32,system_x86_64_win64]) and + is_smart_section(atype) and (aname<>'') then + begin + s:=sectionattrs_coff(atype); + if (s<>'') then + AsmWrite(',"'+s+'"'); + end; end; AsmLn; LastSecType:=atype;