diff --git a/compiler/aasmtai.pas b/compiler/aasmtai.pas index 99057b8696..bde96d5732 100644 --- a/compiler/aasmtai.pas +++ b/compiler/aasmtai.pas @@ -578,6 +578,9 @@ interface function getcopy:tlinkedlistitem;override; end; + type + TSectionFlags = (SF_None,SF_A,SF_W,SF_X); + TSectionProgbits = (SPB_None,SPB_PROGBITS,SPB_NOBITS); { Generates a section / segment directive } tai_section = class(tai) @@ -585,7 +588,11 @@ interface secorder : TasmSectionorder; secalign : longint; name : pshortstring; - sec : TObjSection; { used in binary writer } + { used in binary writer } + sec : TObjSection; + { used only by ELF so far } + secflags : TSectionFlags; + secprogbits : TSectionProgbits; destructor Destroy;override; constructor ppuload(t:taitype;ppufile:tcompilerppufile);override; procedure ppuwrite(ppufile:tcompilerppufile);override; @@ -947,7 +954,7 @@ interface add_reg_instruction_hook : tadd_reg_instruction_proc; procedure maybe_new_object_file(list:TAsmList); - procedure new_section(list:TAsmList;Asectype:TAsmSectiontype;const Aname:string;Aalign:byte;Asecorder:TasmSectionorder=secorder_default); + function new_section(list:TAsmList;Asectype:TAsmSectiontype;const Aname:string;Aalign:byte;Asecorder:TasmSectionorder=secorder_default) : tai_section; function ppuloadai(ppufile:tcompilerppufile):tai; procedure ppuwriteai(ppufile:tcompilerppufile;n:tai); @@ -966,7 +973,6 @@ implementation const pputaimarker = 254; - {**************************************************************************** Helpers ****************************************************************************} @@ -978,9 +984,10 @@ implementation end; - procedure new_section(list:TAsmList;Asectype:TAsmSectiontype;const Aname:string;Aalign:byte;Asecorder:TasmSectionorder=secorder_default); + function new_section(list:TAsmList;Asectype:TAsmSectiontype;const Aname:string;Aalign:byte;Asecorder:TasmSectionorder=secorder_default) : tai_section; begin - list.concat(tai_section.create(Asectype,Aname,Aalign,Asecorder)); + Result:=tai_section.create(Asectype,Aname,Aalign,Asecorder); + list.concat(Result); inc(list.section_count); list.concat(cai_align.create(Aalign)); end; @@ -1211,6 +1218,8 @@ implementation sectype:=TAsmSectiontype(ppufile.getbyte); secalign:=ppufile.getlongint; name:=ppufile.getpshortstring; + secflags:=TSectionFlags(ppufile.getbyte); + secprogbits:=TSectionProgbits(ppufile.getbyte); sec:=nil; end; @@ -1227,6 +1236,8 @@ implementation ppufile.putbyte(byte(sectype)); ppufile.putlongint(secalign); ppufile.putstring(name^); + ppufile.putbyte(byte(secflags)); + ppufile.putbyte(byte(secprogbits)); end; diff --git a/compiler/aggas.pas b/compiler/aggas.pas index 4478bc3dc4..d01ba4ff5e 100644 --- a/compiler/aggas.pas +++ b/compiler/aggas.pas @@ -49,7 +49,8 @@ interface function sectionattrs(atype:TAsmSectiontype):string;virtual; function sectionattrs_coff(atype:TAsmSectiontype):string;virtual; function sectionalignment_aix(atype:TAsmSectiontype;secalign: longint):string; - procedure WriteSection(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder;secalign:longint);virtual; + procedure WriteSection(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder;secalign:longint; + secflags:TSectionFlags=SF_None;secprogbits:TSectionProgbits=SPB_None);virtual; procedure WriteExtraHeader;virtual; procedure WriteExtraFooter;virtual; procedure WriteInstruction(hp: tai); @@ -457,7 +458,7 @@ implementation end; - procedure TGNUAssembler.WriteSection(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder;secalign:longint); + procedure TGNUAssembler.WriteSection(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder;secalign:longint;secflags:TSectionFlags=SF_None;secprogbits:TSectionProgbits=SPB_None); var s : string; begin @@ -491,58 +492,85 @@ implementation end; s:=sectionname(atype,aname,aorder); writer.AsmWrite(s); - case atype of - sec_fpc : - if aname = 'resptrs' then - writer.AsmWrite(', "a", @progbits'); - sec_stub : - begin - case target_info.system of - { there are processor-independent shortcuts available } - { for this, namely .symbol_stub and .picsymbol_stub, but } - { they don't work and gcc doesn't use them either... } - system_powerpc_darwin, - system_powerpc64_darwin: - if (cs_create_pic in current_settings.moduleswitches) then - writer.AsmWriteln('__TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32') - else - writer.AsmWriteln('__TEXT,__symbol_stub1,symbol_stubs,pure_instructions,16'); - system_i386_darwin, - system_i386_iphonesim: - writer.AsmWriteln('__IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5'); - system_arm_darwin: - if (cs_create_pic in current_settings.moduleswitches) then - writer.AsmWriteln('__TEXT,__picsymbolstub4,symbol_stubs,none,16') - else - writer.AsmWriteln('__TEXT,__symbol_stub4,symbol_stubs,none,12') - { darwin/(x86-64/AArch64) uses PC-based GOT addressing, no - explicit symbol stubs } - else - 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 } + { flags explicitly defined? } + if (secflags<>SF_None) or (secprogbits<>SPB_None) then begin - if is_smart_section(atype) and (aname<>'') then + case secflags of + SF_A: + writer.AsmWrite(',"a"'); + SF_W: + writer.AsmWrite(',"w"'); + SF_X: + writer.AsmWrite(',"x"'); + SF_None: + writer.AsmWrite(',""'); + else + Internalerror(2018101502); + end; + case secprogbits of + SPB_PROGBITS: + writer.AsmWrite(',%progbits'); + SPB_NOBITS: + writer.AsmWrite(',%nobits'); + SPB_None: + ; + else + Internalerror(2018101503); + end; + end + else + case atype of + sec_fpc : + if aname = 'resptrs' then + writer.AsmWrite(', "a", @progbits'); + sec_stub : begin - s:=sectionattrs(atype); - if (s<>'') then - writer.AsmWrite(',"'+s+'"'); - end; - if target_info.system in systems_aix then - begin - s:=sectionalignment_aix(atype,secalign); - if s<>'' then - writer.AsmWrite(','+s); + case target_info.system of + { there are processor-independent shortcuts available } + { for this, namely .symbol_stub and .picsymbol_stub, but } + { they don't work and gcc doesn't use them either... } + system_powerpc_darwin, + system_powerpc64_darwin: + if (cs_create_pic in current_settings.moduleswitches) then + writer.AsmWriteln('__TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32') + else + writer.AsmWriteln('__TEXT,__symbol_stub1,symbol_stubs,pure_instructions,16'); + system_i386_darwin, + system_i386_iphonesim: + writer.AsmWriteln('__IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5'); + system_arm_darwin: + if (cs_create_pic in current_settings.moduleswitches) then + writer.AsmWriteln('__TEXT,__picsymbolstub4,symbol_stubs,none,16') + else + writer.AsmWriteln('__TEXT,__symbol_stub4,symbol_stubs,none,12') + { darwin/(x86-64/AArch64) uses PC-based GOT addressing, no + explicit symbol stubs } + else + 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 } + begin + if is_smart_section(atype) and (aname<>'') then + begin + s:=sectionattrs(atype); + if (s<>'') then + writer.AsmWrite(',"'+s+'"'); + end; + if target_info.system in systems_aix then + begin + s:=sectionalignment_aix(atype,secalign); + if s<>'' then + writer.AsmWrite(','+s); + end; + end; end; - end; writer.AsmLn; LastSecType:=atype; end; @@ -725,9 +753,11 @@ implementation begin if tai_section(hp).sectype<>sec_none then if replaceforbidden then - WriteSection(tai_section(hp).sectype,ReplaceForbiddenAsmSymbolChars(tai_section(hp).name^),tai_section(hp).secorder,tai_section(hp).secalign) + WriteSection(tai_section(hp).sectype,ReplaceForbiddenAsmSymbolChars(tai_section(hp).name^),tai_section(hp).secorder, + tai_section(hp).secalign,tai_section(hp).secflags,tai_section(hp).secprogbits) else - WriteSection(tai_section(hp).sectype,tai_section(hp).name^,tai_section(hp).secorder,tai_section(hp).secalign) + WriteSection(tai_section(hp).sectype,tai_section(hp).name^,tai_section(hp).secorder, + tai_section(hp).secalign,tai_section(hp).secflags,tai_section(hp).secprogbits) else begin {$ifdef EXTDEBUG} diff --git a/compiler/ppcgen/agppcgas.pas b/compiler/ppcgen/agppcgas.pas index aafa808429..ce53c537f9 100644 --- a/compiler/ppcgen/agppcgas.pas +++ b/compiler/ppcgen/agppcgas.pas @@ -58,7 +58,7 @@ unit agppcgas; constructor CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean); override; protected function sectionname(atype: TAsmSectiontype; const aname: string; aorder: TAsmSectionOrder): string; override; - procedure WriteSection(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder;secalign:longint); override; + procedure WriteSection(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder;secalign:longint;secflags:TSectionFlags=SF_None;secprogbits:TSectionProgbits=SPB_None); override; procedure WriteAsmList; override; procedure WriteExtraHeader; override; procedure WriteExtraFooter; override; @@ -484,11 +484,12 @@ unit agppcgas; max_alignment[cur_sectype]:=8; end; - procedure TPPCAIXAssembler.WriteSection(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder;secalign:longint); + procedure TPPCAIXAssembler.WriteSection(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder;secalign:longint; + secflags:TSectionFlags=SF_None;secprogbits:TSectionProgbits=SPB_None); begin secalign:=max_alignment[atype]; - Inherited WriteSection(atype,aname,aorder,secalign); + Inherited WriteSection(atype,aname,aorder,secalign,secflags,secprogbits); end; procedure TPPCAIXAssembler.WriteAsmList; diff --git a/compiler/raatt.pas b/compiler/raatt.pas index a795ce3401..4f9a4f9d98 100644 --- a/compiler/raatt.pas +++ b/compiler/raatt.pas @@ -1049,12 +1049,15 @@ unit raatt; hl : tasmlabel; commname, symname, - symval : string; + symval ,sectionname: string; lasTSec : TAsmSectiontype; l1, l2, symofs : tcgint; symtyp : TAsmsymtype; + section : tai_section; + secflags : TSectionFlags; + secprogbits : TSectionProgbits; Begin Message1(asmr_d_start_reading,'GNU AS'); firsttoken:=TRUE; @@ -1312,9 +1315,61 @@ unit raatt; AS_SECTION: begin Consume(AS_SECTION); - new_section(curlist, sec_user, actasmpattern, 0); + sectionname:=actasmpattern; + secflags:=SF_None; + secprogbits:=SPB_None; + Consume(AS_STRING); + if actasmtoken=AS_COMMA then + begin + Consume(AS_COMMA); + if actasmtoken=AS_STRING then + begin + case actasmpattern of + 'a': + secflags:=SF_A; + 'w': + secflags:=SF_W; + 'x': + secflags:=SF_X; + '': + secflags:=SF_None; + else + Message(asmr_e_syntax_error); + end; + Consume(AS_STRING); + if actasmtoken=AS_COMMA then + begin + Consume(AS_COMMA); + if actasmtoken=AS_MOD then + begin + Consume(AS_MOD); + if actasmtoken=AS_ID then + begin + case actasmpattern of + 'PROGBITS': + secprogbits:=SPB_PROGBITS; + 'NOBITS': + secprogbits:=SPB_NOBITS; + else + Message(asmr_e_syntax_error); + end; + Consume(AS_ID); + end + else + Message(asmr_e_syntax_error); + end + else + Message(asmr_e_syntax_error); + end; + end + else + Message(asmr_e_syntax_error); + end; + //curList.concat(tai_section.create(sec_user, actasmpattern, 0)); - consume(AS_STRING); + section:=new_section(curlist, sec_user, sectionname, 0); + section.secflags:=secflags; + section.secprogbits:=secprogbits; end; AS_TARGET_DIRECTIVE: