From ac4c9b0459fe89f2b84bf8b18a3bf86bf569b7d1 Mon Sep 17 00:00:00 2001 From: Mickael Guene Date: Tue, 22 Dec 2015 14:12:35 +0000 Subject: [PATCH] Add support for ARM's NOREAD section flag. include/elf * arm.h: Add arm SHF_ARM_NOREAD section flag. bfd * bfd-in2.h: Regenerate. * section.c: Add SEC_ELF_NOREAD. * elf32-arm.c (elf32_arm_post_process_headers): Only set PF_X attribute if a segment only contains section with SHF_ARM_NOREAD flag. (elf32_arm_fake_sections): Add SEC_ELF_NOREAD conversion. (elf32_arm_section_flags): New function to convert SHF_ARM_NOREAD to bfd flag. (elf32_arm_lookup_section_flags): New function to allow INPUT_SECTION_FLAGS directive with SHF_ARM_NOREAD flag. (elf32_arm_special_sections): Add special sections array to catch section prefix by '.text.noread' pattern. ld/testsuite * ld-arm/arm-elf.exp: New tests. * ld-arm/thumb1-input-section-flag-match.d: New * ld-arm/thumb1-input-section-flag-match.s: New * ld-arm/thumb1-noread-not-present-mixing-two-section.d: New * ld-arm/thumb1-noread-not-present-mixing-two-section.s: New * ld-arm/thumb1-noread-present-one-section.d: New * ld-arm/thumb1-noread-present-one-section.s: New * ld-arm/thumb1-noread-present-two-section.d: New * ld-arm/thumb1-noread-present-two-section.s: New binutils * readelf.c (get_elf_section_flags): Add support for ARM specific section flags. --- bfd/ChangeLog | 15 ++++++ bfd/bfd-in2.h | 3 ++ bfd/elf32-arm.c | 59 ++++++++++++++++++++++ bfd/section.c | 3 ++ binutils/ChangeLog | 5 ++ binutils/readelf.c | 17 ++++++- include/ChangeLog | 4 -- include/elf/ChangeLog | 8 +++ include/elf/arm.h | 1 + ld/testsuite/ChangeLog | 12 +++++ ld/testsuite/ld-arm/arm-elf.exp | 12 +++++ ld/testsuite/ld-arm/arm_noread.ld | 32 ++++++++++++ .../ld-arm/thumb1-input-section-flag-match.d | 6 +++ .../ld-arm/thumb1-input-section-flag-match.s | 18 +++++++ .../thumb1-noread-not-present-mixing-two-section.d | 5 ++ .../thumb1-noread-not-present-mixing-two-section.s | 18 +++++++ .../ld-arm/thumb1-noread-present-one-section.d | 5 ++ .../ld-arm/thumb1-noread-present-one-section.s | 9 ++++ .../ld-arm/thumb1-noread-present-two-section.d | 5 ++ .../ld-arm/thumb1-noread-present-two-section.s | 19 +++++++ 20 files changed, 251 insertions(+), 5 deletions(-) create mode 100644 ld/testsuite/ld-arm/arm_noread.ld create mode 100644 ld/testsuite/ld-arm/thumb1-input-section-flag-match.d create mode 100644 ld/testsuite/ld-arm/thumb1-input-section-flag-match.s create mode 100644 ld/testsuite/ld-arm/thumb1-noread-not-present-mixing-two-section.d create mode 100644 ld/testsuite/ld-arm/thumb1-noread-not-present-mixing-two-section.s create mode 100644 ld/testsuite/ld-arm/thumb1-noread-present-one-section.d create mode 100644 ld/testsuite/ld-arm/thumb1-noread-present-one-section.s create mode 100644 ld/testsuite/ld-arm/thumb1-noread-present-two-section.d create mode 100644 ld/testsuite/ld-arm/thumb1-noread-present-two-section.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index f81e90d..03fbb34 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,18 @@ +2015-12-22 Mickael Guene + + * bfd-in2.h: Regenerate. + * section.c: Add SEC_ELF_NOREAD. + * elf32-arm.c (elf32_arm_post_process_headers): Only set + PF_X attribute if a segment only contains section with + SHF_ARM_NOREAD flag. + (elf32_arm_fake_sections): Add SEC_ELF_NOREAD conversion. + (elf32_arm_section_flags): New function to convert SHF_ARM_NOREAD + to bfd flag. + (elf32_arm_lookup_section_flags): New function to allow + INPUT_SECTION_FLAGS directive with SHF_ARM_NOREAD flag. + (elf32_arm_special_sections): Add special sections array + to catch section prefix by '.text.noread' pattern. + 2015-12-18 H.J. Lu * coff-x86_64.c (coff_amd64_reloc): Fix formatting. diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 39eb19a..ca0cafd 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -1432,6 +1432,9 @@ typedef struct bfd_section when memory read flag isn't set. */ #define SEC_COFF_NOREAD 0x40000000 + /* Indicate that section has the no read flag set. */ +#define SEC_ELF_NOREAD 0x80000000 + /* End of section flags. */ /* Some internal packed boolean fields. */ diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 49d6469..5d31ef2 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -15417,6 +15417,7 @@ elf32_arm_post_process_headers (bfd * abfd, struct bfd_link_info * link_info ATT { Elf_Internal_Ehdr * i_ehdrp; /* ELF file header, internal form. */ struct elf32_arm_link_hash_table *globals; + struct elf_segment_map *m; i_ehdrp = elf_elfheader (abfd); @@ -15442,6 +15443,26 @@ elf32_arm_post_process_headers (bfd * abfd, struct bfd_link_info * link_info ATT else i_ehdrp->e_flags |= EF_ARM_ABI_FLOAT_SOFT; } + + /* Scan segment to set p_flags attribute if it contains only sections with + SHF_ARM_NOREAD flag. */ + for (m = elf_seg_map (abfd); m != NULL; m = m->next) + { + unsigned int j; + + if (m->count == 0) + continue; + for (j = 0; j < m->count; j++) + { + if (!(elf_section_flags (m->sections[j]) & SHF_ARM_NOREAD)) + break; + } + if (j == m->count) + { + m->p_flags = PF_X; + m->p_flags_valid = 1; + } + } } static enum elf_reloc_type_class @@ -15493,6 +15514,10 @@ elf32_arm_fake_sections (bfd * abfd, Elf_Internal_Shdr * hdr, asection * sec) hdr->sh_type = SHT_ARM_EXIDX; hdr->sh_flags |= SHF_LINK_ORDER; } + + if (sec->flags & SEC_ELF_NOREAD) + hdr->sh_flags |= SHF_ARM_NOREAD; + return TRUE; } @@ -17690,6 +17715,33 @@ elf32_arm_get_synthetic_symtab (bfd *abfd, return n; } +static const struct bfd_elf_special_section +elf32_arm_special_sections[] = +{ +/* Catch sections with .text.noread prefix and apply allocate, execute and + noread section attributes. */ + { STRING_COMMA_LEN (".text.noread"), -2, SHT_PROGBITS, + SHF_ALLOC + SHF_EXECINSTR + SHF_ARM_NOREAD }, + { NULL, 0, 0, 0, 0 } +}; + +static bfd_boolean +elf32_arm_section_flags (flagword *flags, const Elf_Internal_Shdr * hdr) +{ + if (hdr->sh_flags & SHF_ARM_NOREAD) + *flags |= SEC_ELF_NOREAD; + return TRUE; +} + +static flagword +elf32_arm_lookup_section_flags (char *flag_name) +{ + if (!strcmp (flag_name, "SHF_ARM_NOREAD")) + return SHF_ARM_NOREAD; + + return SEC_NO_FLAGS; +} + #define ELF_ARCH bfd_arch_arm #define ELF_TARGET_ID ARM_ELF_DATA #define ELF_MACHINE_CODE EM_ARM @@ -17768,6 +17820,13 @@ elf32_arm_get_synthetic_symtab (bfd *abfd, #define elf_backend_obj_attrs_order elf32_arm_obj_attrs_order #define elf_backend_obj_attrs_handle_unknown elf32_arm_obj_attrs_handle_unknown +#undef elf_backend_special_sections +#define elf_backend_special_sections elf32_arm_special_sections +#undef elf_backend_section_flags +#define elf_backend_section_flags elf32_arm_section_flags +#undef elf_backend_lookup_section_flags_hook +#define elf_backend_lookup_section_flags_hook elf32_arm_lookup_section_flags + #include "elf32-target.h" /* Native Client targets. */ diff --git a/bfd/section.c b/bfd/section.c index 247d98a..1a78c11 100644 --- a/bfd/section.c +++ b/bfd/section.c @@ -361,6 +361,9 @@ CODE_FRAGMENT . when memory read flag isn't set. *} .#define SEC_COFF_NOREAD 0x40000000 . +. {* Indicate that section has the no read flag set. *} +.#define SEC_ELF_NOREAD 0x80000000 +. . {* End of section flags. *} . . {* Some internal packed boolean fields. *} diff --git a/binutils/ChangeLog b/binutils/ChangeLog index f588410..fce5f89 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,8 @@ +2015-12-22 Nick Clifton + + * readelf.c (get_elf_section_flags): Add support for ARM specific + section flags. + 2015-12-17 Maciej W. Rozycki * MAINTAINERS: Add myself as MIPS maintainer. diff --git a/binutils/readelf.c b/binutils/readelf.c index c21ce3f..a31db52 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -5273,7 +5273,11 @@ get_elf_section_flags (bfd_vma sh_flags) /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") }, /* SPARC specific. */ /* 19 */ { STRING_COMMA_LEN ("ORDERED") }, - /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") } + /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") }, + /* ARM specific. */ + /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") }, + /* 22 */ { STRING_COMMA_LEN ("ARM_NOREAD") }, + /* 23 */ { STRING_COMMA_LEN ("COMDEF") } }; if (do_section_details) @@ -5343,6 +5347,17 @@ get_elf_section_flags (bfd_vma sh_flags) if (flag == SHF_ORDERED) sindex = 19; break; + + case EM_ARM: + switch (flag) + { + case SHF_ENTRYSECT: sindex = 21; break; + case SHF_ARM_NOREAD: sindex = 22; break; + case SHF_COMDEF: sindex = 23; break; + default: break; + } + break; + default: break; } diff --git a/include/ChangeLog b/include/ChangeLog index 4dcfe10..cd33a61 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,7 +1,3 @@ -2015-12-16 Mickael Guene - - * elf/arm.h: Add new arm relocations. - 2015-12-01 Alan Modra * bout.h: Invoke aout N_* macros with pointer to diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog index 5b98c66..93b00016 100644 --- a/include/elf/ChangeLog +++ b/include/elf/ChangeLog @@ -1,3 +1,11 @@ +2015-12-22 Mickael Guene + + * arm.h: Add arm SHF_ARM_NOREAD section flag. + +2015-12-16 Mickael Guene + + * arm.h: Add new arm relocations. + 2015-12-14 Yoshinori Sato * rx.h (E_FLAG_RX_V2): New RXv2 type. diff --git a/include/elf/arm.h b/include/elf/arm.h index 5691118..4f09b6a 100644 --- a/include/elf/arm.h +++ b/include/elf/arm.h @@ -82,6 +82,7 @@ /* ARM-specific values for sh_flags. */ #define SHF_ENTRYSECT 0x10000000 /* Section contains an entry point. */ +#define SHF_ARM_NOREAD 0x20000000 /* Section contains code that can be place on no read memory area. */ #define SHF_COMDEF 0x80000000 /* Section may be multiply defined in the input to a link step. */ /* ARM-specific program header flags. */ diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index ac3d142..d5982b9 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,15 @@ +2015-12-22 Mickael Guene + + * ld-arm/arm-elf.exp: New tests. + * ld-arm/thumb1-input-section-flag-match.d: New + * ld-arm/thumb1-input-section-flag-match.s: New + * ld-arm/thumb1-noread-not-present-mixing-two-section.d: New + * ld-arm/thumb1-noread-not-present-mixing-two-section.s: New + * ld-arm/thumb1-noread-present-one-section.d: New + * ld-arm/thumb1-noread-present-one-section.s: New + * ld-arm/thumb1-noread-present-two-section.d: New + * ld-arm/thumb1-noread-present-two-section.s: New + 2015-12-16 Mickael Guene * ld-arm/arm-elf.exp (armelftests_common): Add new relocations diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp index 23c9e57..a970dba 100644 --- a/ld/testsuite/ld-arm/arm-elf.exp +++ b/ld/testsuite/ld-arm/arm-elf.exp @@ -299,6 +299,18 @@ set armelftests_nonacl { {"TLS shared library gdesc local" "--no-fix-arm1176 -shared -T arm-dyn.ld" "" "" {tls-lib-loc.s} {{objdump -fdw tls-lib-loc.d} {objdump -Rw tls-lib-loc.r}} "tls-lib-loc.so"} + {"PF_R not present when one noread section" "-static -T arm.ld" "" "" {thumb1-noread-present-one-section.s} + {{readelf -l thumb1-noread-present-one-section.d}} + "thumb1-noread-present-one-section"} + {"PF_R not present when two noread sections" "-static -T arm.ld" "" "" {thumb1-noread-present-two-section.s} + {{readelf -l thumb1-noread-present-two-section.d}} + "thumb1-noread-present-two-section"} + {"PF_R present when mixing noread section with read section" "-static -T arm.ld" "" "" {thumb1-noread-not-present-mixing-two-section.s} + {{readelf -l thumb1-noread-not-present-mixing-two-section.d}} + "thumb1-noread-not-present-mixing-two-section"} + {"Match SHF_ARM_NOREAD with INPUT_SECTION_FLAGS directive" "-static -T arm_noread.ld" "" "" {thumb1-input-section-flag-match.s} + {{readelf -l thumb1-input-section-flag-match.d}} + "thumb1-noread-not-present-mixing-two-section"} } run_ld_link_tests $armelftests_common diff --git a/ld/testsuite/ld-arm/arm_noread.ld b/ld/testsuite/ld-arm/arm_noread.ld new file mode 100644 index 0000000..3ff17bc --- /dev/null +++ b/ld/testsuite/ld-arm/arm_noread.ld @@ -0,0 +1,32 @@ +/* Script for ld testsuite. */ +OUTPUT_ARCH(arm) +ENTRY(_start) +MEMORY +{ + read_memory (rx) : ORIGIN = 0x00008000, LENGTH = 4M + noread_memory (!rx) : ORIGIN = 0x00800000, LENGTH = 4M +} +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + PROVIDE (__executable_start = 0x8000); . = 0x8000; + .text.noread : + { + INPUT_SECTION_FLAGS (SHF_ARM_NOREAD) *(.text*) + } > noread_memory + .text : + { + *(.before) + *(.text) + *(.after) + *(.ARM.extab*) + *(.glue_7) + *(.v4_bx) + } > read_memory + .ARM.exidx : { *(.ARM.exidx*) } + . = 0x9000; + .got : { *(.got) *(.got.plt)} + . = 0x12340000; + .far : { *(.far) } + .ARM.attribues 0 : { *(.ARM.atttributes) } +} diff --git a/ld/testsuite/ld-arm/thumb1-input-section-flag-match.d b/ld/testsuite/ld-arm/thumb1-input-section-flag-match.d new file mode 100644 index 0000000..e25a4f4 --- /dev/null +++ b/ld/testsuite/ld-arm/thumb1-input-section-flag-match.d @@ -0,0 +1,6 @@ +#... +Program Headers: +#... + LOAD 0x000000 0x00000000 0x00000000 0x08002 0x08002 R E 0x10000 + LOAD 0x010000 0x00800000 0x00800000 0x00002 0x00002 E 0x10000 +#... diff --git a/ld/testsuite/ld-arm/thumb1-input-section-flag-match.s b/ld/testsuite/ld-arm/thumb1-input-section-flag-match.s new file mode 100644 index 0000000..ac7c89f --- /dev/null +++ b/ld/testsuite/ld-arm/thumb1-input-section-flag-match.s @@ -0,0 +1,18 @@ + .text + .section .text.noread + .arch armv6s-m + .syntax unified + .global _start + .thumb_func + .type _start, %function +_start: + bx lr + + .text + .arch armv6s-m + .syntax unified + .global foo + .thumb_func + .type foo, %function +foo: + bx lr diff --git a/ld/testsuite/ld-arm/thumb1-noread-not-present-mixing-two-section.d b/ld/testsuite/ld-arm/thumb1-noread-not-present-mixing-two-section.d new file mode 100644 index 0000000..9150576 --- /dev/null +++ b/ld/testsuite/ld-arm/thumb1-noread-not-present-mixing-two-section.d @@ -0,0 +1,5 @@ +#... +Program Headers: +#... + LOAD 0x000000 0x00000000 0x00000000 0x08004 0x08004 R E 0x10000 +#... diff --git a/ld/testsuite/ld-arm/thumb1-noread-not-present-mixing-two-section.s b/ld/testsuite/ld-arm/thumb1-noread-not-present-mixing-two-section.s new file mode 100644 index 0000000..ac7c89f --- /dev/null +++ b/ld/testsuite/ld-arm/thumb1-noread-not-present-mixing-two-section.s @@ -0,0 +1,18 @@ + .text + .section .text.noread + .arch armv6s-m + .syntax unified + .global _start + .thumb_func + .type _start, %function +_start: + bx lr + + .text + .arch armv6s-m + .syntax unified + .global foo + .thumb_func + .type foo, %function +foo: + bx lr diff --git a/ld/testsuite/ld-arm/thumb1-noread-present-one-section.d b/ld/testsuite/ld-arm/thumb1-noread-present-one-section.d new file mode 100644 index 0000000..1faf40c --- /dev/null +++ b/ld/testsuite/ld-arm/thumb1-noread-present-one-section.d @@ -0,0 +1,5 @@ +#... +Program Headers: +#... + LOAD 0x000000 0x00000000 0x00000000 0x08002 0x08002 E 0x10000 +#... diff --git a/ld/testsuite/ld-arm/thumb1-noread-present-one-section.s b/ld/testsuite/ld-arm/thumb1-noread-present-one-section.s new file mode 100644 index 0000000..4be37d2 --- /dev/null +++ b/ld/testsuite/ld-arm/thumb1-noread-present-one-section.s @@ -0,0 +1,9 @@ + .text + .section .text.noread + .arch armv6s-m + .syntax unified + .global _start + .thumb_func + .type _start, %function +_start: + bx lr diff --git a/ld/testsuite/ld-arm/thumb1-noread-present-two-section.d b/ld/testsuite/ld-arm/thumb1-noread-present-two-section.d new file mode 100644 index 0000000..365cab0 --- /dev/null +++ b/ld/testsuite/ld-arm/thumb1-noread-present-two-section.d @@ -0,0 +1,5 @@ +#... +Program Headers: +#... + LOAD 0x000000 0x00000000 0x00000000 0x08004 0x08004 E 0x10000 +#... diff --git a/ld/testsuite/ld-arm/thumb1-noread-present-two-section.s b/ld/testsuite/ld-arm/thumb1-noread-present-two-section.s new file mode 100644 index 0000000..a97f379 --- /dev/null +++ b/ld/testsuite/ld-arm/thumb1-noread-present-two-section.s @@ -0,0 +1,19 @@ + .text + .section .text.noread.first + .arch armv6s-m + .syntax unified + .global _start + .thumb_func + .type _start, %function +_start: + bx lr + + .text + .section .text.noread.second + .arch armv6s-m + .syntax unified + .global foo + .thumb_func + .type foo, %function +foo: + bx lr -- 2.7.4