> Date: Tue, 18 Aug 2015 19:29:58 +0000
> From: Miod Vallat <m...@online.fr>
> 
> 2. I believe that some light smarts could be added to bfd to make .ctors
>    and .dtors read-only when linking a true static binary, which would
>    alleviate crt0 (.got being already RO in that case). So I will come
>    with a binutils diff shortly, so that you will be able to put your
>    crt0 diff in.

Doesn't look like .got is already RO in that case.  But we can make it
so.  Diff below forces .got, .ctors and .dtors to be read0only if we
have not .dynamic section, i.e. for truly static executables.  This
makes the segment that contains those sections read-only for
executables built with -static -nopie:

$ gcc -static -nopie -o hello hello.c
$ readelf -a hello.o
...
Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000000000 0x0000000000100000 0x0000000000100000
                 0x0000000000016b74 0x0000000000016b74  R E    100000
  LOAD           0x0000000000016b80 0x0000000000216b80 0x0000000000216b80
                 0x00000000000017cc 0x00000000000017cc  R      100000
  LOAD           0x0000000000018350 0x0000000000318350 0x0000000000318350
                 0x0000000000000590 0x0000000000000590  RW     100000
  LOAD           0x00000000000188e0 0x00000000004188e0 0x00000000004188e0
                 0x00000000000006d8 0x00000000000006d8  R      100000
  LOAD           0x0000000000018fb8 0x0000000000718fb8 0x0000000000718fb8
                 0x0000000000001088 0x000000000000c150  RW     100000
  NOTE           0x0000000000000238 0x0000000000100238 0x0000000000100238
                 0x0000000000000018 0x0000000000000018  R      4
  OPENBSD_RANDOM 0x0000000000018350 0x0000000000318350 0x0000000000318350
                 0x0000000000000008 0x0000000000000008  RW     8

 Section to Segment mapping:
  Segment Sections...
   00     .note.openbsd.ident .init .text .fini 
   01     .rodata .eh_frame 
   02     .openbsd.randomdata .jcr .data.rel.ro 
   03     .got .ctors .dtors 
   04     .data .bss 
   05     .note.openbsd.ident 
   06     .openbsd.randomdata 


All other types retain a writable segment, that is made read-only by
either ld.so or rcrt0.o.

Tested on macppc and sparc64.

ok?


Index: ld/emultempl/elf32.em
===================================================================
RCS file: /cvs/src/gnu/usr.bin/binutils-2.17/ld/emultempl/elf32.em,v
retrieving revision 1.3
diff -u -p -r1.3 elf32.em
--- ld/emultempl/elf32.em       4 Jul 2011 23:58:26 -0000       1.3
+++ ld/emultempl/elf32.em       21 Aug 2015 11:20:44 -0000
@@ -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
@@ -1119,6 +1135,27 @@ gld${EMULATION_NAME}_after_open (void)
   /* We only need to worry about this when doing a final link.  */
   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).

Reply via email to