From 245b58c249b4b29ffc54e6c1e50a1474cc84f7b1 Mon Sep 17 00:00:00 2001 From: florian Date: Wed, 9 Oct 2019 17:45:40 +0000 Subject: [PATCH] + support for arm attributes * abi notes fixed git-svn-id: trunk@43157 - --- .gitattributes | 1 + compiler/aasmbase.pas | 7 +- compiler/aasmtai.pas | 73 ++++++++++-- compiler/aggas.pas | 53 ++++++--- compiler/arm/cpuinfo.pas | 6 +- compiler/arm/cpunode.pas | 3 +- compiler/arm/narmutil.pas | 241 ++++++++++++++++++++++++++++++++++++++ compiler/assemble.pas | 96 ++++++++++++++- compiler/elfbase.pas | 1 + compiler/ogbase.pas | 34 +++++- compiler/ogcoff.pas | 3 +- compiler/ogelf.pas | 12 +- compiler/psabiehpi.pas | 2 +- compiler/raatt.pas | 12 +- rtl/linux/arm/abitag.inc | 2 +- 15 files changed, 503 insertions(+), 43 deletions(-) create mode 100644 compiler/arm/narmutil.pas diff --git a/.gitattributes b/.gitattributes index 536665e334..04793fc9a7 100644 --- a/.gitattributes +++ b/.gitattributes @@ -91,6 +91,7 @@ compiler/arm/narmld.pas svneol=native#text/pascal compiler/arm/narmmat.pas svneol=native#text/plain compiler/arm/narmmem.pas svneol=native#text/plain compiler/arm/narmset.pas svneol=native#text/plain +compiler/arm/narmutil.pas svneol=native#text/pascal compiler/arm/pp.lpi.template svneol=native#text/plain compiler/arm/raarm.pas svneol=native#text/plain compiler/arm/raarmgas.pas svneol=native#text/plain diff --git a/compiler/aasmbase.pas b/compiler/aasmbase.pas index 20ef29e77d..39f5c1542a 100644 --- a/compiler/aasmbase.pas +++ b/compiler/aasmbase.pas @@ -170,13 +170,18 @@ interface { initial heap segment for 16-bit DOS } sec_heap, { dwarf based/gcc style exception handling } - sec_gcc_except_table + sec_gcc_except_table, + sec_arm_attribute ); TObjCAsmSectionType = sec_objc_class..sec_objc_protolist; TAsmSectionOrder = (secorder_begin,secorder_default,secorder_end); + TSectionFlag = (SF_A,SF_W,SF_X); + TSectionFlags = set of TSectionFlag; + TSectionProgbits = (SPB_None,SPB_PROGBITS,SPB_NOBITS,SPB_NOTE,SPB_ARM_ATTRIBUTES); + TAsmSymbol = class(TFPHashObject) private { this need to be incremented with every symbol loading into the diff --git a/compiler/aasmtai.pas b/compiler/aasmtai.pas index 92bfcbfbce..776e6a8736 100644 --- a/compiler/aasmtai.pas +++ b/compiler/aasmtai.pas @@ -94,7 +94,8 @@ interface { SEH directives used in ARM,MIPS and x86_64 COFF targets } ait_seh_directive, { Dwarf CFI directive } - ait_cfi + ait_cfi, + ait_eabi_attribute ); taiconst_type = ( @@ -233,7 +234,8 @@ interface 'llvmmetadatarefop', {$endif} 'cfi', - 'seh_directive' + 'seh_directive', + 'eabi_attribute' ); type @@ -337,7 +339,8 @@ interface ait_llvmmetadatarefoperand, {$endif llvm} ait_seh_directive, - ait_cfi + ait_cfi, + ait_eabi_attribute ]; @@ -608,10 +611,6 @@ 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) sectype : TAsmSectiontype; @@ -983,6 +982,18 @@ interface procedure ppuwrite(ppufile:tcompilerppufile);override; end; + teattrtyp = (eattrtype_none,eattrtype_dword,eattrtype_ntbs); + tai_eabi_attribute = class(tai) + eattr_typ : teattrtyp; + tag,value : dword; + valuestr : pstring; + constructor create(atag,avalue : dword); + constructor create(atag : dword;const avalue : string); + destructor destroy;override; + constructor ppuload(t:taitype;ppufile:tcompilerppufile);override; + procedure ppuwrite(ppufile:tcompilerppufile);override; + end; + var { array with all class types for tais } aiclass : taiclassarray; @@ -1260,7 +1271,7 @@ implementation sectype:=TAsmSectiontype(ppufile.getbyte); secalign:=ppufile.getlongint; name:=ppufile.getpshortstring; - secflags:=TSectionFlags(ppufile.getbyte); + secflags:=TSectionFlags(ppufile.getdword); secprogbits:=TSectionProgbits(ppufile.getbyte); sec:=nil; end; @@ -1278,7 +1289,7 @@ implementation ppufile.putbyte(byte(sectype)); ppufile.putlongint(secalign); ppufile.putstring(name^); - ppufile.putbyte(byte(secflags)); + ppufile.putbyte(dword(secflags)); ppufile.putbyte(byte(secprogbits)); end; @@ -3413,6 +3424,50 @@ implementation begin end; + +{**************************************************************************** + tai_eabi_attribute + ****************************************************************************} + + constructor tai_eabi_attribute.create(atag,avalue : dword); + begin + inherited Create; + typ:=ait_eabi_attribute; + eattr_typ:=eattrtype_dword; + tag:=atag; + value:=avalue; + end; + + + constructor tai_eabi_attribute.create(atag: dword; const avalue: string); + begin + inherited Create; + typ:=ait_eabi_attribute; + eattr_typ:=eattrtype_ntbs; + tag:=atag; + valuestr:=NewStr(avalue); + end; + + + destructor tai_eabi_attribute.destroy; + begin + Inherited Destroy; + end; + + + constructor tai_eabi_attribute.ppuload(t:taitype;ppufile:tcompilerppufile); + begin + end; + + + procedure tai_eabi_attribute.ppuwrite(ppufile:tcompilerppufile); + begin + inherited ppuwrite(ppufile); + ppufile.putdword(tag); + ppufile.putdword(value); + end; + + {$ifdef JVM} {**************************************************************************** diff --git a/compiler/aggas.pas b/compiler/aggas.pas index 262647dc44..1e620bf025 100644 --- a/compiler/aggas.pas +++ b/compiler/aggas.pas @@ -50,7 +50,7 @@ interface 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; - secflags:TSectionFlags=SF_None;secprogbits:TSectionProgbits=SPB_None);virtual; + secflags:TSectionFlags=[];secprogbits:TSectionProgbits=SPB_None);virtual; procedure WriteExtraHeader;virtual; procedure WriteExtraFooter;virtual; procedure WriteInstruction(hp: tai); @@ -273,7 +273,8 @@ implementation '.objc_protolist', '.stack', '.heap', - '.gcc_except_table' + '.gcc_except_table', + '.ARM.attributes' ); secnames_pic : array[TAsmSectiontype] of string[length('__DATA, __datacoal_nt,coalesced')] = ('','', '.text', @@ -333,7 +334,8 @@ implementation '.objc_protolist', '.stack', '.heap', - '.gcc_except_table' + '.gcc_except_table', + '..ARM.attributes' ); var sep : string[3]; @@ -468,9 +470,10 @@ implementation end; - procedure TGNUAssembler.WriteSection(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder;secalign:longint;secflags:TSectionFlags=SF_None;secprogbits:TSectionProgbits=SPB_None); + procedure TGNUAssembler.WriteSection(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder;secalign:longint;secflags:TSectionFlags=[];secprogbits:TSectionProgbits=SPB_None); var s : string; + secflag: TSectionFlag; begin writer.AsmLn; case target_info.system of @@ -503,25 +506,30 @@ implementation s:=sectionname(atype,aname,aorder); writer.AsmWrite(s); { flags explicitly defined? } - if (secflags<>SF_None) or (secprogbits<>SPB_None) then + if (secflags<>[]) or (secprogbits<>SPB_None) then begin - case secflags of - SF_A: - writer.AsmWrite(',"a"'); - SF_W: - writer.AsmWrite(',"w"'); - SF_X: - writer.AsmWrite(',"x"'); - SF_None: - writer.AsmWrite(',""'); - end; + s:=',"'; + for secflag in secflags do + case secflag of + SF_A: + s:=s+'a'; + SF_W: + s:=s+'w'; + SF_X: + s:=s+'x'; + end; + writer.AsmWrite(s+'"'); case secprogbits of SPB_PROGBITS: writer.AsmWrite(',%progbits'); SPB_NOBITS: writer.AsmWrite(',%nobits'); + SPB_NOTE: + writer.AsmWrite(',%note'); SPB_None: ; + else + InternalError(2019100801); end; end else @@ -1513,6 +1521,18 @@ implementation begin WriteCFI(tai_cfi_base(hp)); end; + ait_eabi_attribute: + begin + case tai_eabi_attribute(hp).eattr_typ of + eattrtype_dword: + writer.AsmWrite(#9'.eabi_attribute '+tostr(tai_eabi_attribute(hp).tag)+','+tostr(tai_eabi_attribute(hp).value)); + eattrtype_ntbs: + writer.AsmWrite(#9'.eabi_attribute '+tostr(tai_eabi_attribute(hp).tag)+',"'+tai_eabi_attribute(hp).valuestr^+'"'); + else + Internalerror(2019100601); + end; + writer.AsmLn; + end; else internalerror(2006012201); end; @@ -1989,7 +2009,8 @@ implementation sec_none (* sec_objc_protlist *), sec_none (* sec_stack *), sec_none (* sec_heap *), - sec_none (* gcc_except_table *) + sec_none (* gcc_except_table *), + sec_none (* sec_arm_attribute *) ); begin Result := inherited SectionName (SecXTable [AType], AName, AOrder); diff --git a/compiler/arm/cpuinfo.pas b/compiler/arm/cpuinfo.pas index a7b484ca68..69b044c086 100644 --- a/compiler/arm/cpuinfo.pas +++ b/compiler/arm/cpuinfo.pas @@ -54,6 +54,9 @@ Type cpu_armv7r, cpu_armv7m, cpu_armv7em + { when new elements added afterwards, + update class procedure tarmnodeutils.InsertObjectInfo; in narmutil.pas + } ); tinstructionset = (is_thumb,is_arm); @@ -73,7 +76,8 @@ Type fpu_fpv4_s16, fpu_vfpv4, fpu_neon_vfpv4 - { when new elements added afterwards, update also fpu_vfp_last below } + { when new elements added afterwards, update also fpu_vfp_last below and + update class procedure tarmnodeutils.InsertObjectInfo; in narmutil.pas } ); Const diff --git a/compiler/arm/cpunode.pas b/compiler/arm/cpunode.pas index c0a519ca9f..69406b2d7b 100644 --- a/compiler/arm/cpunode.pas +++ b/compiler/arm/cpunode.pas @@ -46,7 +46,8 @@ unit cpunode; narmcnv, narmcon, narmset, - narmmem + narmmem, + narmutil {$else} llvmnode {$endif} diff --git a/compiler/arm/narmutil.pas b/compiler/arm/narmutil.pas new file mode 100644 index 0000000000..29a641f826 --- /dev/null +++ b/compiler/arm/narmutil.pas @@ -0,0 +1,241 @@ +{ + Copyright (c) 2019 by Florian Klämpfl + + ARM version of some node tree helper routines + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + **************************************************************************** +} +unit narmutil; + +{$i fpcdefs.inc} + +interface + + uses + ngenutil; + + type + tarmnodeutils = class(tnodeutils) + class procedure InsertObjectInfo; override; + end; + + + implementation + + uses + verbose, + systems, + globals, + cpuinfo, + aasmdata,aasmtai; + + const + Tag_File = 1; + Tag_Section = 2; + Tag_Symbol = 3; + Tag_CPU_raw_name = 4; + Tag_CPU_name = 5; + Tag_CPU_arch = 6; + Tag_CPU_arch_profile = 7; + Tag_ARM_ISA_use = 8; + Tag_THUMB_ISA_use = 9; + Tag_FP_Arch = 10; + Tag_WMMX_arch = 11; + Tag_Advanced_SIMD_arch = 12; + Tag_PCS_config = 13; + Tag_ABI_PCS_R9_use = 14; + Tag_ABI_PCS_RW_data = 15; + Tag_ABI_PCS_RO_data = 16; + Tag_ABI_PCS_GOT_use = 17; + Tag_ABI_PCS_wchar_t = 18; + Tag_ABI_FP_rounding = 19; + Tag_ABI_FP_denormal = 20; + Tag_ABI_FP_exceptions = 21; + Tag_ABI_FP_user_exceptions = 22; + Tag_ABI_FP_number_model = 23; + Tag_ABI_align_needed = 24; + Tag_ABI_align8_preserved = 25; + Tag_ABI_enum_size = 26; + Tag_ABI_HardFP_use = 27; + Tag_ABI_VFP_args = 28; + Tag_ABI_WMMX_args = 29; + Tag_ABI_optimization_goals = 30; + Tag_ABI_FP_optimization_goals = 31; + Tag_compatiblity = 32; + Tag_CPU_unaligned_access = 34; + Tag_FP_HP_extension = 36; + Tag_ABI_FP_16bit_format = 38; + Tag_MPextension_use = 42; + Tag_DIV_use = 44; + Tag_nodefaults = 64; + Tag_also_compatible_with = 65; + Tag_conformance = 67; + Tag_T2EE_use = 66; + Tag_Virtualization_use = 68; + + class procedure tarmnodeutils.InsertObjectInfo; + begin + inherited InsertObjectInfo; + { write eabi attributes to object file? } + if (target_info.system in [system_arm_linux]) and (target_info.abi in [abi_eabihf,abi_eabi]) then + begin + case current_settings.cputype of + cpu_armv3: + begin + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch,0)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch_profile,0)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_name,'')); + end; + cpu_armv4: + begin + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch,1)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch_profile,0)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_name,'4')); + end; + cpu_armv4t: + begin + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch,2)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch_profile,0)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_name,'4T')); + end; + cpu_armv5t: + begin + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch,3)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch_profile,0)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_name,'5T')); + end; + cpu_armv5te: + begin + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch,4)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch_profile,0)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_name,'5TE')); + end; + cpu_armv5tej: + begin + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch,5)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch_profile,0)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_name,'5TEJ')); + end; + cpu_armv6: + begin + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch,6)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch_profile,0)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_name,'6')); + end; + cpu_armv6k: + begin + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch,9)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch_profile,0)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_name,'6K')); + end; + cpu_armv6t2: + begin + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch,8)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch_profile,0)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_name,'T2')); + end; + cpu_armv6z: + begin + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch,7)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch_profile,0)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_name,'6Z')); + end; + cpu_armv6m: + begin + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch,11)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch_profile,0)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_name,'6-M')); + end; + cpu_armv7: + begin + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch,10)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch_profile,0)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_name,'7')); + end; + cpu_armv7a: + begin + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch,10)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch_profile,$41)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_name,'7-A')); + end; + cpu_armv7r: + begin + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch,10)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch_profile,$52)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_name,'7-R')); + end; + cpu_armv7m: + begin + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch,10)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch_profile,$4D)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_name,'7-M')); + end; + cpu_armv7em: + begin + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch,13)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_arch_profile,$4D)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_CPU_name,'7E-M')); + end; + else + Internalerror(2019100602); + end; + case current_settings.fputype of + fpu_soft, + fpu_libgcc: + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_FP_Arch,0)); + fpu_vfpv2: + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_FP_Arch,2)); + fpu_vfpv3, + fpu_neon_vfpv3: + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_FP_Arch,3)); + fpu_vfpv3_d16: + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_FP_Arch,4)); + fpu_fpv4_s16: + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_FP_Arch,6)); + fpu_vfpv4, + fpu_neon_vfpv4: + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_FP_Arch,5)); + else + Internalerror(2019100603); + end; + if FPUARM_HAS_FMA in fpu_capabilities[current_settings.fputype] then + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_Advanced_SIMD_arch,2)) + else if FPUARM_HAS_NEON in fpu_capabilities[current_settings.fputype] then + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_Advanced_SIMD_arch,1)) + else + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_Advanced_SIMD_arch,0)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_ARM_ISA_use,1)); + if CPUARM_HAS_THUMB2 in cpu_capabilities[current_settings.cputype] then + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_THUMB_ISA_use,2)) + else + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_THUMB_ISA_use,1)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_ABI_VFP_args,1)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_ABI_FP_denormal,1)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_ABI_FP_exceptions,1)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_ABI_FP_number_model,3)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_ABI_align_needed,0)); + current_asmdata.asmlists[al_start].Concat(tai_eabi_attribute.create(Tag_ABI_align8_preserved,1)); + { gcc typically writes more like enum size, wchar size, optimization goal, however, this + is normally not module global in FPC } + end; + end; + + + begin + cnodeutils:=tarmnodeutils; + end. + diff --git a/compiler/assemble.pas b/compiler/assemble.pas index e415e0b772..01eb2b239d 100644 --- a/compiler/assemble.pas +++ b/compiler/assemble.pas @@ -1558,6 +1558,7 @@ Implementation objsym, objsymend : TObjSymbol; cpu: tcputype; + eabi_section, TmpSection: TObjSection; begin while assigned(hp) do begin @@ -1672,7 +1673,10 @@ Implementation end; ait_section: begin - ObjData.CreateSection(Tai_section(hp).sectype,Tai_section(hp).name^,Tai_section(hp).secorder); + if Tai_section(hp).sectype=sec_user then + ObjData.CreateSection(Tai_section(hp).sectype,Tai_section(hp).secflags,Tai_section(hp).secprogbits,Tai_section(hp).name^,Tai_section(hp).secorder) + else + ObjData.CreateSection(Tai_section(hp).sectype,Tai_section(hp).name^,Tai_section(hp).secorder); Tai_section(hp).sec:=ObjData.CurrObjSec; end; ait_symbol : @@ -1696,6 +1700,28 @@ Implementation ait_cutobject : if SmartAsm then break; + ait_eabi_attribute : + begin + eabi_section:=ObjData.findsection('.ARM.attributes'); + if not(assigned(eabi_section)) then + begin + TmpSection:=ObjData.CurrObjSec; + ObjData.CreateSection(sec_arm_attribute,[],SPB_ARM_ATTRIBUTES,'',secorder_default); + eabi_section:=ObjData.CurrObjSec; + ObjData.setsection(TmpSection); + end; + if eabi_section.Size=0 then + eabi_section.alloc(16); + eabi_section.alloc(LengthUleb128(tai_eabi_attribute(hp).tag)); + case tai_eabi_attribute(hp).eattr_typ of + eattrtype_dword: + eabi_section.alloc(LengthUleb128(tai_eabi_attribute(hp).value)); + eattrtype_ntbs: + eabi_section.alloc(Length(tai_eabi_attribute(hp).valuestr^)+1); + else + Internalerror(2019100701); + end; + end; else ; end; @@ -1710,6 +1736,7 @@ Implementation objsym, objsymend : TObjSymbol; cpu: tcputype; + eabi_section: TObjSection; begin while assigned(hp) do begin @@ -1853,6 +1880,23 @@ Implementation internalerror(2010011102); end; end; + ait_eabi_attribute : + begin + eabi_section:=ObjData.findsection('.ARM.attributes'); + if not(assigned(eabi_section)) then + Internalerror(2019100702); + if eabi_section.Size=0 then + eabi_section.alloc(16); + eabi_section.alloc(LengthUleb128(tai_eabi_attribute(hp).tag)); + case tai_eabi_attribute(hp).eattr_typ of + eattrtype_dword: + eabi_section.alloc(LengthUleb128(tai_eabi_attribute(hp).value)); + eattrtype_ntbs: + eabi_section.alloc(Length(tai_eabi_attribute(hp).valuestr^)+1); + else + Internalerror(2019100703); + end; + end; else ; end; @@ -1885,6 +1929,10 @@ Implementation ccomp : comp; tmp : word; cpu: tcputype; + ddword : dword; + eabi_section: TObjSection; + s: String; + TmpDataPos: TObjSectionOfs; begin fillchar(zerobuf,sizeof(zerobuf),0); fillchar(objsym,sizeof(objsym),0); @@ -2182,6 +2230,52 @@ Implementation ait_seh_directive : tai_seh_directive(hp).generate_code(objdata); {$endif DISABLE_WIN64_SEH} + ait_eabi_attribute : + begin + eabi_section:=ObjData.findsection('.ARM.attributes'); + if not(assigned(eabi_section)) then + Internalerror(2019100704); + if eabi_section.Size=0 then + begin + s:='A'; + eabi_section.write(s[1],1); + ddword:=eabi_section.Size-1; + eabi_section.write(ddword,4); + s:='aeabi'#0; + eabi_section.write(s[1],6); + s:=#1; + eabi_section.write(s[1],1); + ddword:=eabi_section.Size-1-4-6-1; + eabi_section.write(ddword,4); + end; + leblen:=EncodeUleb128(tai_eabi_attribute(hp).tag,lebbuf,0); + eabi_section.write(lebbuf,leblen); + + case tai_eabi_attribute(hp).eattr_typ of + eattrtype_dword: + begin + leblen:=EncodeUleb128(tai_eabi_attribute(hp).value,lebbuf,0); + eabi_section.write(lebbuf,leblen); + end; + eattrtype_ntbs: + begin + s:=tai_eabi_attribute(hp).valuestr^+#0; + eabi_section.write(s[1],Length(s)); + end + else + Internalerror(2019100705); + end; + { update size of attributes section, write directly to the dyn. arrays as + we do not increase the size of section } + TmpDataPos:=eabi_section.Data.Pos; + eabi_section.Data.seek(1); + ddword:=eabi_section.Size-1; + eabi_section.Data.write(ddword,4); + eabi_section.Data.seek(12); + ddword:=eabi_section.Size-1-4-6; + eabi_section.Data.write(ddword,4); + eabi_section.Data.Seek(TmpDataPos); + end; else ; end; diff --git a/compiler/elfbase.pas b/compiler/elfbase.pas index e4ca0c6c1c..916292d42d 100644 --- a/compiler/elfbase.pas +++ b/compiler/elfbase.pas @@ -114,6 +114,7 @@ interface SHT_GNU_verdef = $6ffffffd; SHT_GNU_verneed = $6ffffffe; SHT_GNU_versym = $6fffffff; + SHT_ARM_ATTRIBUTES = $70000003; { ElfSechdr.sh_flags } SHF_WRITE = 1; diff --git a/compiler/ogbase.pas b/compiler/ogbase.pas index 2dc717a837..507a5e6a64 100644 --- a/compiler/ogbase.pas +++ b/compiler/ogbase.pas @@ -189,7 +189,11 @@ interface { Section to support the resolution of multiple symbols with the same name } oso_comdat, { section containing thread variables } - oso_threadvar + oso_threadvar, + { being a notes section } + oso_note, + { arm attributes section } + oso_arm_attributes ); TObjSectionOptions = set of TObjSectionOption; @@ -394,6 +398,7 @@ interface function sectiontype2options(atype:TAsmSectiontype):TObjSectionOptions;virtual; function sectiontype2align(atype:TAsmSectiontype):longint;virtual; function createsection(atype:TAsmSectionType;const aname:string='';aorder:TAsmSectionOrder=secorder_default):TObjSection;virtual; + function createsection(atype:TAsmSectionType;secflags:TSectionFlags;aprogbits:TSectionProgbits;const aname:string='';aorder:TAsmSectionOrder=secorder_default):TObjSection;virtual; function createsection(const aname:string;aalign:longint;aoptions:TObjSectionOptions;DiscardDuplicate:boolean=true):TObjSection;virtual; function createsectiongroup(const aname:string):TObjSectionGroup; procedure CreateDebugSections;virtual; @@ -1271,7 +1276,8 @@ implementation {sec_objc_protolist'} [oso_data,oso_load], {stack} [oso_load,oso_write], {heap} [oso_load,oso_write], - {gcc_except_table} [oso_data,oso_load] + {gcc_except_table} [oso_data,oso_load], + {arm_attribute} [oso_data] ); begin result:=secoptions[atype]; @@ -1281,7 +1287,8 @@ implementation function TObjData.sectiontype2align(atype:TAsmSectiontype):longint; begin case atype of - sec_stabstr,sec_debug_info,sec_debug_line,sec_debug_abbrev,sec_debug_aranges,sec_debug_ranges: + sec_stabstr,sec_debug_info,sec_debug_line,sec_debug_abbrev,sec_debug_aranges,sec_debug_ranges, + sec_arm_attribute: result:=1; sec_code, sec_bss, @@ -1307,6 +1314,27 @@ implementation end; + function TObjData.createsection(atype: TAsmSectionType; secflags: TSectionFlags; aprogbits: TSectionProgbits; const aname: string; aorder: TAsmSectionOrder): TObjSection; + var + flags : TObjSectionOptions; + begin + flags:=[oso_data]; + if SF_A in secflags then + Include(flags,oso_load); + if SF_W in secflags then + Include(flags,oso_write); + if SF_X in secflags then + Include(flags,oso_executable); + if aprogbits=SPB_NOBITS then + Exclude(flags,oso_data); + if aprogbits=SPB_NOTE then + Include(flags,oso_note); + if aprogbits=SPB_ARM_ATTRIBUTES then + Include(flags,oso_arm_attributes); + result:=createsection(sectionname(atype,aname,aorder),sectiontype2align(atype),flags); + end; + + function TObjData.createsection(const aname:string;aalign:longint;aoptions:TObjSectionOptions;DiscardDuplicate:boolean):TObjSection; begin if DiscardDuplicate then diff --git a/compiler/ogcoff.pas b/compiler/ogcoff.pas index 42a19eab23..8dac219d9b 100644 --- a/compiler/ogcoff.pas +++ b/compiler/ogcoff.pas @@ -593,7 +593,8 @@ implementation '.objc_protolist', '.stack', '.heap', - '.gcc_except_table' + '.gcc_except_table', + '.ARM.attributes' ); const go32v2stub : array[0..2047] of byte=( diff --git a/compiler/ogelf.pas b/compiler/ogelf.pas index 74e2eef9b9..bb77186427 100644 --- a/compiler/ogelf.pas +++ b/compiler/ogelf.pas @@ -388,11 +388,16 @@ implementation procedure encodesechdrflags(aoptions:TObjSectionOptions;out AshType:longint;out Ashflags:longint); begin { Section Type } - AshType:=SHT_PROGBITS; if oso_strings in aoptions then AshType:=SHT_STRTAB else if not(oso_data in aoptions) then - AshType:=SHT_NOBITS; + AshType:=SHT_NOBITS + else if oso_note in aoptions then + AshType:=SHT_NOTE + else if oso_arm_attributes in aoptions then + AshType:=SHT_ARM_ATTRIBUTES + else + AshType:=SHT_PROGBITS; { Section Flags } Ashflags:=0; if oso_load in aoptions then @@ -562,7 +567,8 @@ implementation '.objc_protolist', '.stack', '.heap', - '.gcc_except_table' + '.gcc_except_table', + '.ARM.attributes' ); var sep : string[3]; diff --git a/compiler/psabiehpi.pas b/compiler/psabiehpi.pas index fe5a9856e3..48ba65650a 100644 --- a/compiler/psabiehpi.pas +++ b/compiler/psabiehpi.pas @@ -402,7 +402,7 @@ implementation landingpadstack:=TFPList.Create; typefilterlist:=TFPList.Create; gcc_except_table:=new_section(gcc_except_table_data,sec_gcc_except_table,'',0); - gcc_except_table.secflags:=SF_A; + gcc_except_table.secflags:=[SF_A]; gcc_except_table.secprogbits:=SPB_PROGBITS; {$ifdef debug_eh} gcc_except_table_data.concat(tai_comment.Create(strpnew('gcc_except_table for '+procdef.fullprocname(true)))); diff --git a/compiler/raatt.pas b/compiler/raatt.pas index 81355d82fe..8879694fed 100644 --- a/compiler/raatt.pas +++ b/compiler/raatt.pas @@ -1316,7 +1316,7 @@ unit raatt; begin Consume(AS_SECTION); sectionname:=actasmpattern; - secflags:=SF_None; + secflags:=[]; secprogbits:=SPB_None; Consume(AS_STRING); if actasmtoken=AS_COMMA then @@ -1326,13 +1326,13 @@ unit raatt; begin case actasmpattern of 'a': - secflags:=SF_A; + Include(secflags,SF_A); 'w': - secflags:=SF_W; + Include(secflags,SF_W); 'x': - secflags:=SF_X; + Include(secflags,SF_X); '': - secflags:=SF_None; + ; else Message(asmr_e_syntax_error); end; @@ -1350,6 +1350,8 @@ unit raatt; secprogbits:=SPB_PROGBITS; 'NOBITS': secprogbits:=SPB_NOBITS; + 'NOTE': + secprogbits:=SPB_NOTE; else Message(asmr_e_syntax_error); end; diff --git a/rtl/linux/arm/abitag.inc b/rtl/linux/arm/abitag.inc index 0048d35a1f..9c8f236815 100644 --- a/rtl/linux/arm/abitag.inc +++ b/rtl/linux/arm/abitag.inc @@ -14,7 +14,7 @@ procedure ABITag;nostackframe;assembler; asm - .section ".note.ABI-tag", "a" + .section ".note.ABI-tag", "a", %note .align 4 .long 4 .long 16