This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [Patch, ARM] Support NOREAD section attribute across Bintuils for ARM target


On 18/04/14 03:41, Terry Guo wrote:
> Hi there,
> 
> In order to protect proprietary code from reverse-engineering, some ARM
> baremetal boards have a special flash area where code is executable but not
> readable. Normally this area is very small and can only accommodate certain
> code sections (sections with NOREAD attribute in this case). The attached
> patch implements a new letter 'y' to represent this new SHF_NOREAD section
> attribute and enables user to define/allocate such code sections to
> executable-only flash area in linker script. We talked to community with an
> intention to make it to be a common and standard ELF section attribute, but
> got rejected. So now it is implemented as a process-specific attribute for
> ARM target.
> 
> This new attribute is a supplementary attribute to normal code section. It
> won't break current way to handle code section. It will be safely ignored
> for targets that don't have executable-only feature i.e. code section with
> this new attribute will be treated as a normal code section.
> 
> Tested with all regression tests in Binutils, no new regressions. Is it OK
> to trunk?
> 

This isn't documented in AAELF.

R.

> BR,
> Terry
> 
>  include/ChangeLog:
> 2014-04-18  Terry Guo  <terry.guo@arm.com>
> 
>      * elf/arm.h (SHF_NOREAD): New flag to represent NOREAD attribute.
> 
> bfd/ChangeLog:
> 2014-04-18  Terry Guo  <terry.guo@arm.com>
> 
>      * elf32-arm.c (elf32_arm_elf_lookup_section_flags): New function to
> help linker
>      recognize flag SHF_NOREAD.
>      (elf_backend_lookup_section_flags_hook): Implement this hook for ARM
> target.
> 
> gas/ChangeLog:
> 2014-04-18  Terry Guo  <terry.guo@arm.com>
> 
>      * config/obj-elf.c (obj_elf_change_section): Accept ARM executable-only
> text section.
>      * config/tc-arm.h (md_elf_section_letter): Implement this hook for ARM
> target.
>      (arm_elf_section_letter): Declare it.
>      * config/tc-arm.c (arm_elf_section_letter): Handle ARM section
> attribute letter 'y'.
>      * doc/c-arm.texi (ARM section attribute 'y'): Document it.
> 
> gas/testsuite/ChangeLog:
> 2014-04-18  Terry Guo  <terry.guo@arm.com>
> 
>      * gas/arm/section-execute-only.s: New test case.
>      * gas/arm/section-execute-only.d: Expected output.
> 
> binutils/ChangeLog:
> 2014-04-18  Terry Guo  <terry.guo@arm.com>
> 
>      * readelf.c (get_elf_section_flags): Display ARM specific NOREAD
> section attribute.
> 
> ld/testsuite/ChangeLog:
> 2014-04-18  Terry Guo  <terry.guo@arm.com>
> 
>      * ld-arm/section-execute-only.s: New test.
>      * ld-arm/execute-only-section.ld: Linker script with executable-only
> memory.
>      * ld-arm/section-execute-only.d: Expected output for target with
> executable-only memory.
>      * ld-arm/no-execute-only-section.ld: Linker script without
> executable-only memory.
>      * ld-arm/no-section-execute-only.d: Expected output for target without
> executable-only memory.
>      * ld-arm/arm-elf.exp: Add tests for executable-only attribute.
> 
> 
> binutils-exo-v4.txt
> 
> 
> diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
> index 16467a4..aea5b9c 100644
> --- a/bfd/elf32-arm.c
> +++ b/bfd/elf32-arm.c
> @@ -15877,6 +15877,16 @@ elf32_arm_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
>    return TRUE;
>  }
>  
> +static flagword
> +elf32_arm_elf_lookup_section_flags (char *flag_name)
> +{
> +
> +  if (!strcmp (flag_name, "SHF_NOREAD"))
> +    return SHF_NOREAD;
> +
> +  return 0;
> +}
> +
>  /* We use this to override swap_symbol_in and swap_symbol_out.  */
>  const struct elf_size_info elf32_arm_size_info =
>  {
> @@ -16142,6 +16152,7 @@ elf32_arm_get_synthetic_symtab (bfd *abfd,
>  #define elf_backend_output_arch_local_syms      elf32_arm_output_arch_local_syms
>  #define elf_backend_begin_write_processing      elf32_arm_begin_write_processing
>  #define elf_backend_add_symbol_hook		elf32_arm_add_symbol_hook
> +#define elf_backend_lookup_section_flags_hook   elf32_arm_elf_lookup_section_flags
>  
>  #define elf_backend_can_refcount       1
>  #define elf_backend_can_gc_sections    1
> diff --git a/binutils/readelf.c b/binutils/readelf.c
> index c757a63..846990c 100644
> --- a/binutils/readelf.c
> +++ b/binutils/readelf.c
> @@ -4752,7 +4752,9 @@ get_elf_section_flags (bfd_vma sh_flags)
>        /* Generic.  */
>        /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
>        /* SPARC specific.  */
> -      /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
> +      /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
> +      /* ARM specific.  */
> +      /* 20 */ { STRING_COMMA_LEN ("NOREAD") }
>      };
>  
>    if (do_section_details)
> @@ -4821,6 +4823,10 @@ get_elf_section_flags (bfd_vma sh_flags)
>  		  if (flag == SHF_ORDERED)
>  		    sindex = 19;
>  		  break;
> +		case EM_ARM:
> +		  if (flag == SHF_NOREAD)
> +		    sindex = 20;
> +		  break;
>  		default:
>  		  break;
>  		}
> @@ -4869,6 +4875,9 @@ get_elf_section_flags (bfd_vma sh_flags)
>  		   || elf_header.e_machine == EM_K1OM)
>  		  && flag == SHF_X86_64_LARGE)
>  		*p = 'l';
> +	      else if (elf_header.e_machine == EM_ARM
> +		       && flag == SHF_NOREAD)
> +		*p = 'y';
>  	      else if (flag & SHF_MASKOS)
>  		{
>  		  *p = 'o';
> diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
> index 52c6b64..46929c5 100644
> --- a/gas/config/obj-elf.c
> +++ b/gas/config/obj-elf.c
> @@ -64,6 +64,10 @@
>  #include "elf/nios2.h"
>  #endif
>  
> +#ifdef TC_ARM
> +#include "elf/arm.h"
> +#endif
> +
>  static void obj_elf_line (int);
>  static void obj_elf_size (int);
>  static void obj_elf_type (int);
> @@ -672,6 +676,11 @@ obj_elf_change_section (const char *name,
>  	    /* RX init/fini arrays can and should have the "awx" attributes set.  */
>  	    ;
>  #endif
> +#ifdef TC_ARM
> +	  else if (attr == (SHF_EXECINSTR | SHF_NOREAD | SHF_ALLOC))
> +	    /* ARM can have code section with SHF_NOREAD attribute.  */
> +	    ;
> +#endif
>  	  else
>  	    {
>  	      if (group_name == NULL)
> diff --git a/gas/config/tc-arm.h b/gas/config/tc-arm.h
> index f88fa29..11bb1ac 100644
> --- a/gas/config/tc-arm.h
> +++ b/gas/config/tc-arm.h
> @@ -276,6 +276,7 @@ struct current_it
>  # define md_elf_section_type(str, len)	arm_elf_section_type (str, len)
>  # define GLOBAL_OFFSET_TABLE_NAME	"_GLOBAL_OFFSET_TABLE_"
>  # define TC_SEGMENT_INFO_TYPE 		struct arm_segment_info_type
> +# define md_elf_section_letter		arm_elf_section_letter
>  
>  /* This is not really an alignment operation, but it's something we
>     need to do at the same time: whenever we are figuring out the
> @@ -369,6 +370,7 @@ void tc_pe_dwarf2_emit_offset (symbolS *, unsigned int);
>  #define CONVERT_SYMBOLIC_ATTRIBUTE(name) arm_convert_symbolic_attribute (name)
>  extern int arm_convert_symbolic_attribute (const char *);
>  extern int arm_apply_sym_value (struct fix *);
> +extern bfd_vma arm_elf_section_letter (int, char **);
>  #endif
>  
>  #define tc_comment_chars arm_comment_chars
> diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
> index 69299c7..7c44961 100644
> --- a/gas/config/tc-arm.c
> +++ b/gas/config/tc-arm.c
> @@ -25373,4 +25373,17 @@ arm_apply_sym_value (struct fix * fixP)
>      }
>    return 0;
>  }
> +
> +/* Map 'y' to SHF_NOREAD.  */
> +
> +bfd_vma
> +arm_elf_section_letter (int letter, char **ptr_msg)
> +{
> +  if (letter == 'y')
> +    return SHF_NOREAD;
> +
> +  *ptr_msg = _("bad .section directive: want a,e,w,x,y,M,S,G,T in string");
> +
> +  return -1;
> +}
>  #endif /* OBJ_ELF */
> diff --git a/gas/doc/c-arm.texi b/gas/doc/c-arm.texi
> index 7bcce94..fdee70d 100644
> --- a/gas/doc/c-arm.texi
> +++ b/gas/doc/c-arm.texi
> @@ -23,6 +23,7 @@
>  * ARM Opcodes::              Opcodes
>  * ARM Mapping Symbols::      Mapping Symbols
>  * ARM Unwinding Tutorial::   Unwinding
> +* ARM Section Attribute::    Section Attribute
>  @end menu
>  
>  @node ARM Options
> @@ -1185,3 +1186,13 @@ code that calls functions which may throw exceptions.  If you need to
>  know more about the object-file format used to represent unwind
>  information, you may consult the @cite{Exception Handling ABI for the
>  ARM Architecture} available from @uref{http://infocenter.arm.com}.
> +
> +@node ARM Section Attribute
> +@section Section Attribute
> +
> +@cindex ARM section attribute
> +@table @code
> +@item y
> +text section with NOREAD attribute for target that supports this feature,
> +otherwise such section will be treated as normal text section.
> +@end table
> diff --git a/gas/testsuite/gas/arm/section-execute-only.d b/gas/testsuite/gas/arm/section-execute-only.d
> new file mode 100644
> index 0000000..fd6fe90
> --- /dev/null
> +++ b/gas/testsuite/gas/arm/section-execute-only.d
> @@ -0,0 +1,27 @@
> +# name: test executable-only section attribute
> +# as:
> +# readelf: -t
> +# This test is only valid on EABI based ports.
> +# target: *-*-*eabi* *-*-nacl*
> +There are 10 section headers, starting at offset 0xc4:
> +
> +Section Headers:
> +  \[Nr\] Name
> +       Type            Addr     Off    Size   ES   Lk Inf Al
> +       Flags
> +  \[ 0\] 
> +       NULL            00000000 000000 000000 00   0   0  0
> +       \[00000000\]: 
> +  \[ 1\] .text
> +       PROGBITS        00000000 000034 000000 00   0   0  2
> +       \[00000006\]: ALLOC, EXEC
> +  \[ 2\] .data
> +       PROGBITS        00000000 000034 000000 00   0   0  1
> +       \[00000003\]: WRITE, ALLOC
> +  \[ 3\] .bss
> +       NOBITS          00000000 000034 000000 00   0   0  1
> +       \[00000003\]: WRITE, ALLOC
> +  \[ 4\] .text.foo
> +       PROGBITS        00000000 000034 000010 00   0   0  4
> +       \[20000006\]: ALLOC, EXEC, NOREAD
> +#pass
> diff --git a/gas/testsuite/gas/arm/section-execute-only.s b/gas/testsuite/gas/arm/section-execute-only.s
> new file mode 100644
> index 0000000..9d5ffc6
> --- /dev/null
> +++ b/gas/testsuite/gas/arm/section-execute-only.s
> @@ -0,0 +1,30 @@
> +        .syntax unified
> +        .cpu cortex-m3
> +        .fpu softvfp
> +        .eabi_attribute 20, 1
> +        .eabi_attribute 21, 1
> +        .eabi_attribute 23, 3
> +        .eabi_attribute 24, 1
> +        .eabi_attribute 25, 1
> +        .eabi_attribute 26, 1
> +        .eabi_attribute 30, 2
> +        .eabi_attribute 34, 1
> +        .eabi_attribute 18, 4
> +        .thumb
> +        .section        .text.foo,"axy",%progbits
> +        .align  2
> +        .global foo
> +        .thumb
> +        .thumb_func
> +        .type   foo, %function
> +foo:
> +        @ args = 0, pretend = 0, frame = 0
> +        @ frame_needed = 0, uses_anonymous_args = 0
> +        @ link register save eliminated.
> +        movs    r0, #1
> +        movs    r1, #1
> +        movw    r2, #257
> +        movs    r3, #1
> +        b       madd
> +        .size   foo, .-foo
> +
> diff --git a/include/elf/arm.h b/include/elf/arm.h
> index 34afdfd..c6cd873 100644
> --- a/include/elf/arm.h
> +++ b/include/elf/arm.h
> @@ -84,6 +84,7 @@
>  /* ARM-specific values for sh_flags.  */
>  #define SHF_ENTRYSECT      0x10000000   /* Section contains an entry point.  */
>  #define SHF_COMDEF         0x80000000   /* Section may be multiply defined in the input to a link step.  */
> +#define SHF_NOREAD         0x20000000   /* Section isn't readable.  */
>  
>  /* ARM-specific program header flags.  */
>  #define PF_ARM_SB          0x10000000   /* Segment contains the location addressed by the static base.  */
> diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp
> index c255587..d95f47f 100644
> --- a/ld/testsuite/ld-arm/arm-elf.exp
> +++ b/ld/testsuite/ld-arm/arm-elf.exp
> @@ -671,6 +671,13 @@ set armeabitests_nonacl {
>       {{objdump -d thumb-b-lks-sym.d}}
>       "thumb-b-lks-sym"}
>  
> +    {"link executable-only text section for targets supporting this feature" "-T execute-only-section.ld" "" "" {section-execute-only.s}
> +     {{readelf -S section-execute-only.d}}
> +     "has-execute-only-memory"}
> +    {"link executable-only text section for normal targets" "-T no-execute-only-section.ld" "" "" {section-execute-only.s}
> +     {{readelf -S no-section-execute-only.d}}
> +     "no-execute-only-memory"}
> +
>      {"erratum 760522 fix (default for v6z)" "--section-start=.foo=0x2001014" ""
>       "-march=armv6z" {fix-arm1176.s}
>       {{objdump -d fix-arm1176-on.d}}
> diff --git a/ld/testsuite/ld-arm/execute-only-section.ld b/ld/testsuite/ld-arm/execute-only-section.ld
> new file mode 100644
> index 0000000..b2897b0
> --- /dev/null
> +++ b/ld/testsuite/ld-arm/execute-only-section.ld
> @@ -0,0 +1,22 @@
> +/* Linker script to configure memory regions. */
> +MEMORY
> +{
> +  FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K
> +  FLASH_XO (rx) : ORIGIN = 0x00000000+256K, LENGTH = 256K
> +  RAM (rwx) : ORIGIN = 0x100000C8, LENGTH = (32K - 0xC8)
> +}
> +
> +ENTRY(main)
> +
> +SECTIONS
> +{
> +  .text :
> +  {
> +     INPUT_SECTION_FLAGS (!SHF_NOREAD) *(.text*)
> +  } > FLASH
> +
> +  .text.xo :
> +  {
> +     INPUT_SECTION_FLAGS (SHF_NOREAD) *(.text*)
> +  } > FLASH_XO
> +}
> diff --git a/ld/testsuite/ld-arm/no-execute-only-section.ld b/ld/testsuite/ld-arm/no-execute-only-section.ld
> new file mode 100644
> index 0000000..5746138
> --- /dev/null
> +++ b/ld/testsuite/ld-arm/no-execute-only-section.ld
> @@ -0,0 +1,16 @@
> +/* Linker script to configure memory regions. */
> +MEMORY
> +{
> +  FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K
> +  RAM (rwx) : ORIGIN = 0x100000C8, LENGTH = (32K - 0xC8)
> +}
> +
> +ENTRY(main)
> +
> +SECTIONS
> +{
> +  .text :
> +  {
> +     *(.text*)
> +  } > FLASH
> +}
> diff --git a/ld/testsuite/ld-arm/no-section-execute-only.d b/ld/testsuite/ld-arm/no-section-execute-only.d
> new file mode 100644
> index 0000000..30e73a0
> --- /dev/null
> +++ b/ld/testsuite/ld-arm/no-section-execute-only.d
> @@ -0,0 +1,11 @@
> +There are 6 section headers, starting at offset 0x807c:
> +
> +Section Headers:
> +  \[Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
> +  \[ 0\]                   NULL            00000000 000000 000000 00      0   0  0
> +  \[ 1\] .text             PROGBITS        00000000 008000 000018 00  AX  0   0  4
> +  \[ 2\] .ARM.attributes   ARM_ATTRIBUTES  00000000 008018 000033 00      0   0  1
> +  \[ 3\] .shstrtab         STRTAB          00000000 00804b 000031 00      0   0  1
> +  \[ 4\] .symtab           SYMTAB          00000000 00816c 0000a0 10      5   7  4
> +  \[ 5\] .strtab           STRTAB          00000000 00820c 00002f 00      0   0  1
> +#pass
> diff --git a/ld/testsuite/ld-arm/section-execute-only.d b/ld/testsuite/ld-arm/section-execute-only.d
> new file mode 100644
> index 0000000..12b0ed5
> --- /dev/null
> +++ b/ld/testsuite/ld-arm/section-execute-only.d
> @@ -0,0 +1,12 @@
> +There are 7 section headers, starting at offset 0x1007c:
> +
> +Section Headers:
> +  \[Nr\] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
> +  \[ 0\]                   NULL            00000000 000000 000000 00      0   0  0
> +  \[ 1\] .text             PROGBITS        00000000 008000 00000c 00  AX  0   0  4
> +  \[ 2\] .text.xo          PROGBITS        00040000 010000 00000c 00 AXy  0   0  4
> +  \[ 3\] .ARM.attributes   ARM_ATTRIBUTES  00000000 01000c 000033 00      0   0  1
> +  \[ 4\] .shstrtab         STRTAB          00000000 01003f 00003a 00      0   0  1
> +  \[ 5\] .symtab           SYMTAB          00000000 010194 0000b0 10      6   8  4
> +  \[ 6\] .strtab           STRTAB          00000000 010244 00002f 00      0   0  1
> +#pass
> diff --git a/ld/testsuite/ld-arm/section-execute-only.s b/ld/testsuite/ld-arm/section-execute-only.s
> new file mode 100644
> index 0000000..d3838f0
> --- /dev/null
> +++ b/ld/testsuite/ld-arm/section-execute-only.s
> @@ -0,0 +1,58 @@
> +        .syntax unified
> +        .cpu cortex-m3
> +        .fpu softvfp
> +        .eabi_attribute 20, 1
> +        .eabi_attribute 21, 1
> +        .eabi_attribute 23, 3
> +        .eabi_attribute 24, 1
> +        .eabi_attribute 25, 1
> +        .eabi_attribute 26, 1
> +        .eabi_attribute 30, 2
> +        .eabi_attribute 34, 1
> +        .eabi_attribute 18, 4
> +        .thumb
> +        .section        .text.foo,"axy",%progbits
> +        .align  2
> +        .global foo
> +        .thumb
> +        .thumb_func
> +        .type   foo, %function
> +foo:
> +        @ args = 0, pretend = 0, frame = 0
> +        @ frame_needed = 0, uses_anonymous_args = 0
> +        @ link register save eliminated.
> +        movs    r0, #1
> +        movs    r1, #1
> +        movw    r2, #257
> +        movs    r3, #1
> +        bx      lr
> +        .size   foo, .-foo
> +
> +        .section        .text.bar,"ax",%progbits
> +        .align  2
> +        .global bar
> +        .thumb
> +        .thumb_func
> +        .type   bar, %function
> +bar:
> +        @ args = 0, pretend = 0, frame = 0
> +        @ frame_needed = 0, uses_anonymous_args = 0
> +        @ link register save eliminated.
> +        movs    r0, #1
> +        movs    r1, #1
> +	bx	lr
> +
> +        .section        .text.startup,"ax",%progbits
> +        .align  2
> +        .global main
> +        .thumb
> +        .thumb_func
> +        .type   main, %function
> +main:
> +        @ args = 0, pretend = 0, frame = 0
> +        @ frame_needed = 0, uses_anonymous_args = 0
> +        @ link register save eliminated.
> +        movs    r0, #0
> +        bx      lr
> +        .size   main, .-main
> +
> 



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]