binutils/
authorJakub Jelinek <jakub@redhat.com>
Tue, 3 Jun 2003 22:27:24 +0000 (22:27 +0000)
committerJakub Jelinek <jakub@redhat.com>
Tue, 3 Jun 2003 22:27:24 +0000 (22:27 +0000)
* readelf.c (get_segment_type): Handle PT_GNU_STACK.
bfd/
* elf.c (_bfd_elf_print_private_bfd_data): Handle PT_GNU_STACK.
(bfd_section_from_phdr): Likewise.
(map_sections_to_segments): Create PT_GNU_STACK segment header.
(get_program_header_size): Count with PT_GNU_STACK.
* elf-bfd.h (struct elf_obj_tdata): Add stack_flags.
* elflink.h (bfd_elfNN_size_dynamic_sections): Set stack_flags.
include/
* bfdlink.h (struct bfd_link_info): Add execstack and noexecstack.
* elf/common.h (PT_GNU_STACK): Define.
ld/
* ldgram.y (phdr_type): Grok PT_GNU_STACK.
* emultempl/elf32.em (gld${EMULATION_NAME}_handle_option): Add
-z execstack and -z noexecstack.
(gld${EMULATION_NAME}_list_options): Likewise.
* scripttempl/elf.sc: If not -r, discard .note.GNU-stack section.

13 files changed:
bfd/ChangeLog
bfd/elf-bfd.h
bfd/elf.c
bfd/elflink.h
binutils/ChangeLog
binutils/readelf.c
include/ChangeLog
include/bfdlink.h
include/elf/common.h
ld/ChangeLog
ld/emultempl/elf32.em
ld/ldgram.y
ld/scripttempl/elf.sc

index 9ff266ae4629a49874b2688cbe40b529d11355b5..e2bb60a868f3b93541cb647e61bfbf363ebbe303 100644 (file)
@@ -1,3 +1,12 @@
+2003-06-03  Jakub Jelinek  <jakub@redhat.com>
+
+       * elf.c (_bfd_elf_print_private_bfd_data): Handle PT_GNU_STACK.
+       (bfd_section_from_phdr): Likewise.
+       (map_sections_to_segments): Create PT_GNU_STACK segment header.
+       (get_program_header_size): Count with PT_GNU_STACK.
+       * elf-bfd.h (struct elf_obj_tdata): Add stack_flags.
+       * elflink.h (bfd_elfNN_size_dynamic_sections): Set stack_flags.
+
 2003-06-03  H.J. Lu <hongjiu.lu@intel.com>
 
        * elflink.h (elf_link_input_bfd): Call linker error_handler
index 1da605502b5a54bdcbeffc314686d34a2aae58b3..d3973071fb314131bf9ff9131ffc514f481ab123 100644 (file)
@@ -1254,6 +1254,9 @@ struct elf_obj_tdata
   /* Number of symbol version references we are about to emit.  */
   unsigned int cverrefs;
 
+  /* Segment flags for the PT_GNU_STACK segment.  */
+  unsigned int stack_flags;  
+
   /* Symbol version definitions in external objects.  */
   Elf_Internal_Verdef *verdef;
 
index e1cbe0aee0d8b093ce34a0570996191e58a6fd3c..906e13d879650a8894e51a5d1d8877e50da1429d 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -1070,6 +1070,7 @@ _bfd_elf_print_private_bfd_data (abfd, farg)
            case PT_PHDR: pt = "PHDR"; break;
            case PT_TLS: pt = "TLS"; break;
            case PT_GNU_EH_FRAME: pt = "EH_FRAME"; break;
+           case PT_GNU_STACK: pt = "STACK"; break;
            default: sprintf (buf, "0x%lx", p->p_type); pt = buf; break;
            }
          fprintf (f, "%8s off    0x", pt);
@@ -2296,6 +2297,9 @@ bfd_section_from_phdr (abfd, hdr, index)
       return _bfd_elf_make_section_from_phdr (abfd, hdr, index,
                                              "eh_frame_hdr");
 
+    case PT_GNU_STACK:
+      return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "stack");
+
     default:
       /* Check for any processor-specific program segment types.
          If no handler for them, default to making "segment" sections.  */
@@ -3513,6 +3517,21 @@ map_sections_to_segments (abfd)
       pm = &m->next;
     }
 
+  if (elf_tdata (abfd)->stack_flags)
+    {
+      amt = sizeof (struct elf_segment_map);
+      m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
+      if (m == NULL)
+       goto error_return;
+      m->next = NULL;
+      m->p_type = PT_GNU_STACK;
+      m->p_flags = elf_tdata (abfd)->stack_flags;
+      m->p_flags_valid = 1;
+
+      *pm = m;
+      pm = &m->next;
+    }
+
   free (sections);
   sections = NULL;
 
@@ -4099,6 +4118,12 @@ get_program_header_size (abfd)
       ++segs;
     }
 
+  if (elf_tdata (abfd)->stack_flags)
+    {
+      /* We need a PT_GNU_STACK segment.  */
+      ++segs;
+    }
+
   for (s = abfd->sections; s != NULL; s = s->next)
     {
       if ((s->flags & SEC_LOAD) != 0
index a7ef7427bf35ef904aa557845d7da815cc4d2661..8acb7a93632a5b9e309e8dac72d27da2ab1f0ea9 100644 (file)
@@ -1937,6 +1937,43 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
   if (! is_elf_hash_table (info))
     return TRUE;
 
+  if (info->execstack)
+    elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X;
+  else if (info->noexecstack)
+    elf_tdata (output_bfd)->stack_flags = PF_R | PF_W;
+  else
+    {
+      bfd *inputobj;
+      asection *notesec = NULL;
+      int exec = 0;
+
+      for (inputobj = info->input_bfds;
+          inputobj;
+          inputobj = inputobj->link_next)
+       {
+         asection *s;
+
+         if (inputobj->flags & DYNAMIC)
+           continue;
+         s = bfd_get_section_by_name (inputobj, ".note.GNU-stack");
+         if (s)
+           {
+             if (s->flags & SEC_CODE)
+               exec = PF_X;
+             notesec = s;
+           }
+         else
+           exec = PF_X;
+       }
+      if (notesec)
+       {
+         elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | exec;
+         if (exec && info->relocateable
+             && notesec->output_section != bfd_abs_section_ptr)
+           notesec->output_section->flags |= SEC_CODE;
+       }
+    }
+
   /* Any syms created from now on start with -1 in
      got.refcount/offset and plt.refcount/offset.  */
   elf_hash_table (info)->init_refcount = elf_hash_table (info)->init_offset;
index 0b42501d6801770c33ce9a8cdc1e24a7ded5b179..3d271bf4db90e207549cf8e2475deaceab89ab80 100644 (file)
@@ -1,3 +1,7 @@
+2003-05-23  Jakub Jelinek  <jakub@redhat.com>
+
+       * readelf.c (get_segment_type): Handle PT_GNU_STACK.
+
 2003-06-03  Elias Athanasopoulos  <elathan@phys.uoa.gr>
 
        * NEWS: Document the new BSD/POSIX single-character mapping for
index dbd802aa060c1363c1bacbbcecc948f984cada4f..8e8d39e2508206cf83fa63cdbba3783c62c3fbfc 100644 (file)
@@ -2332,6 +2332,7 @@ get_segment_type (p_type)
 
     case PT_GNU_EH_FRAME:
                        return "GNU_EH_FRAME";
+    case PT_GNU_STACK: return "STACK";
 
     default:
       if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
index 96f1777729ee8821a4a4c3b640e9d5c3067de172..18d0b3509e76ac0d522a0b053215f58ae400d4f6 100644 (file)
@@ -1,3 +1,8 @@
+2003-05-23  Jakub Jelinek  <jakub@redhat.com>
+
+       * bfdlink.h (struct bfd_link_info): Add execstack and noexecstack.
+       * elf/common.h (PT_GNU_STACK): Define.
+
 2003-06-03  H.J. Lu <hongjiu.lu@intel.com>
 
        * bfdlink.h (LD_DEFINITION_IN_DISCARDED_SECTION): New.
index d68fe113f1f864232c9a45b8a9ecb0202c23efda..4636025b8b9c78113c1b445d9a4f4ca53f73ffad 100644 (file)
@@ -297,6 +297,14 @@ struct bfd_link_info
   /* TRUE if generating an executable, position independent or not.  */
   unsigned int executable : 1;
 
+  /* TRUE if PT_GNU_STACK segment should be created with PF_R|PF_W|PF_X
+     flags.  */
+  unsigned int execstack: 1;
+
+  /* TRUE if PT_GNU_STACK segment should be created with PF_R|PF_W
+     flags.  */
+  unsigned int noexecstack: 1;
+
   /* Which symbols to strip.  */
   enum bfd_link_strip strip;
 
index f342d573710c7071000dae9f5c45c1dab92be689..3635bbb6419238780ff1c17989583713a240c0b4 100644 (file)
 #define PT_HIPROC      0x7FFFFFFF      /* Processor-specific */
 
 #define PT_GNU_EH_FRAME        (PT_LOOS + 0x474e550)
+#define PT_GNU_STACK   (PT_LOOS + 0x474e551)
 
 /* Program segment permissions, in program header p_flags field.  */
 
index a14119f1863d91e2a0ba120b424f825e3e9d21c5..2be279fc80bcd68dfac7e583071ad00c2839a141 100644 (file)
@@ -1,6 +1,15 @@
+2003-05-23  Jakub Jelinek  <jakub@redhat.com>
+
+       * ldgram.y (phdr_type): Grok PT_GNU_STACK.
+       * emultempl/elf32.em (gld${EMULATION_NAME}_handle_option): Add
+       -z execstack and -z noexecstack.
+       (gld${EMULATION_NAME}_list_options): Likewise.
+       * scripttempl/elf.sc: If not -r, discard .note.GNU-stack section.
+
 2003-06-03  Michael Snyder  <msnyder@redhat.com>
         and Bernd Schmidt   <bernds@redhat.com>
        and Alexandre Oliva <aoliva@redhat.com>
+
        * Makefile.am: Add new emulations for h8300sx.
        * Makefile.in: Regenerate.
        * configure.tgt: Add new emulations.
index 11668fdb9b6d3e465884f73637dab09cde152de2..5529f323e439cf6c4e3ba7bb2beee89e2694547a 100644 (file)
@@ -1684,6 +1684,16 @@ cat >>e${EMULATION_NAME}.c <<EOF
        link_info.combreloc = FALSE;
       else if (strcmp (optarg, "nocopyreloc") == 0)
         link_info.nocopyreloc = TRUE;
+      else if (strcmp (optarg, "execstack") == 0)
+       {
+         link_info.execstack = TRUE;
+         link_info.noexecstack = FALSE;
+       }
+      else if (strcmp (optarg, "noexecstack") == 0)
+       {
+         link_info.noexecstack = TRUE;
+         link_info.execstack = FALSE;
+       }
       /* What about the other Solaris -z options? FIXME.  */
       break;
 EOF
@@ -1722,6 +1732,7 @@ cat >>e${EMULATION_NAME}.c <<EOF
   fprintf (file, _("  --eh-frame-hdr\tCreate .eh_frame_hdr section\n"));
   fprintf (file, _("  -z combreloc\t\tMerge dynamic relocs into one section and sort\n"));
   fprintf (file, _("  -z defs\t\tDisallows undefined symbols\n"));
+  fprintf (file, _("  -z execstack\t\tMark executable as requiring executable stack\n"));
   fprintf (file, _("  -z initfirst\t\tMark DSO to be initialized first at runtime\n"));
   fprintf (file, _("  -z interpose\t\tMark object to interpose all DSOs but executable\n"));
   fprintf (file, _("  -z loadfltr\t\tMark object requiring immediate process\n"));
@@ -1732,6 +1743,7 @@ cat >>e${EMULATION_NAME}.c <<EOF
   fprintf (file, _("  -z nodelete\t\tMark DSO non-deletable at runtime\n"));
   fprintf (file, _("  -z nodlopen\t\tMark DSO not available to dlopen\n"));
   fprintf (file, _("  -z nodump\t\tMark DSO not available to dldump\n"));
+  fprintf (file, _("  -z noexecstack\t\tMark executable as not requiring executable stack\n"));
   fprintf (file, _("  -z now\t\tMark object non-lazy runtime binding\n"));
   fprintf (file, _("  -z origin\t\tMark object requiring immediate \$ORIGIN processing\n\t\t\t  at runtime\n"));
   fprintf (file, _("  -z KEYWORD\t\tIgnored for Solaris compatibility\n"));
index e9c8a9fe4905de07a8ab98a9f7f6d7f9598b75eb..22dbb248ce4441326fd14f053ce11c1f456c722f 100644 (file)
@@ -1006,6 +1006,8 @@ phdr_type:
                        {
                          if (strcmp (s, "PT_GNU_EH_FRAME") == 0)
                            $$ = exp_intop (0x6474e550);
+                         else if (strcmp (s, "PT_GNU_STACK") == 0)
+                           $$ = exp_intop (0x6474e551);
                          else
                            {
                              einfo (_("\
index d4ffcd68183610932e72ab0ff21136af23bb35d3..97b100e43caf65f5b1ea28337aca1445be09b55d 100644 (file)
@@ -84,6 +84,7 @@ INTERP=".interp       ${RELOCATING-0} : { *(.interp) }"
 PLT=".plt          ${RELOCATING-0} : { *(.plt) }"
 DYNAMIC=".dynamic      ${RELOCATING-0} : { *(.dynamic) }"
 RODATA=".rodata       ${RELOCATING-0} : { *(.rodata${RELOCATING+ .rodata.* .gnu.linkonce.r.*}) }"
+STACKNOTE="/DISCARD/ : { *(.note.GNU-stack) }"
 if test -z "${NO_SMALL_DATA}"; then
   SBSS=".sbss         ${RELOCATING-0} :
   {
@@ -396,5 +397,6 @@ cat <<EOF
   ${STACK_ADDR+${STACK}}
   ${OTHER_SECTIONS}
   ${RELOCATING+${OTHER_END_SYMBOLS}}
+  ${RELOCATING+${STACKNOTE}}
 }
 EOF