diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2015-09-09 09:16:59 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2015-09-09 09:16:59 +0000 |
commit | 2a1748ca4933cc50a719a089c87d84534980dab9 (patch) | |
tree | c4072cce733dc6108f104cb6645f12d2331198b5 | |
parent | 860d1bf002d266a56987b59800a1ed7c272e7737 (diff) |
For truly static binaries, force .ctors, .dtors and .got to be read-only.
This will make the segment containing those sections read-only for binaries
that use the OpenBSD W^X layout, preventing W^X violations on architectures
that need an executable GOT (basically BSS-PLT powerpc).
ok miod@
-rw-r--r-- | gnu/usr.bin/binutils-2.17/ld/emultempl/elf32.em | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/gnu/usr.bin/binutils-2.17/ld/emultempl/elf32.em b/gnu/usr.bin/binutils-2.17/ld/emultempl/elf32.em index 1f8222a1db9..f25d2bd8df2 100644 --- a/gnu/usr.bin/binutils-2.17/ld/emultempl/elf32.em +++ b/gnu/usr.bin/binutils-2.17/ld/emultempl/elf32.em @@ -1109,6 +1109,22 @@ EOF if test x"$LDEMUL_AFTER_OPEN" != xgld"$EMULATION_NAME"_after_open; then cat >>e${EMULATION_NAME}.c <<EOF +static void +gld${EMULATION_NAME}_force_readonly(lang_input_statement_type *s) +{ + asection *sec; + + if (s->the_bfd == NULL) + return; + + sec = bfd_get_section_by_name (s->the_bfd, ".ctors"); + if (sec) + sec->flags |= SEC_READONLY; + sec = bfd_get_section_by_name (s->the_bfd, ".dtors"); + if (sec) + sec->flags |= SEC_READONLY; +} + /* This is called after all the input files have been opened. */ static void @@ -1120,6 +1136,27 @@ gld${EMULATION_NAME}_after_open (void) if (link_info.relocatable || !link_info.executable) return; + /* If we don't have a .dynamic section, we have no relocations, and + we can make .got, .ctors and .dtors read-only. This will make + the segment containing those sections to be read-only in static + executables. */ + if (link_info.hash->type == bfd_link_elf_hash_table + && !elf_hash_table (&link_info)->dynamic_sections_created) + { + bfd *dynobj = elf_hash_table (&link_info)->dynobj; + + if (dynobj != NULL) + { + asection *sec; + + sec = bfd_get_section_by_name (dynobj, ".got"); + if (sec) + sec->flags |= SEC_READONLY; + } + + lang_for_each_input_file (gld${EMULATION_NAME}_force_readonly); + } + /* Get the list of files which appear in DT_NEEDED entries in dynamic objects included in the link (often there will be none). For each such file, we want to track down the corresponding |