]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Implement -z execstack/noexecstack options.
authorUlrich Drepper <drepper@redhat.com>
Sun, 11 Jun 2006 00:20:43 +0000 (00:20 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sun, 11 Jun 2006 00:20:43 +0000 (00:20 +0000)
src/ChangeLog
src/ld.c
src/ld.h
src/ldgeneric.c

index fb4e011dccf25f283ed76afd78d22aa27d71a185..8bfd20c4ccf2ad22b61c0d286e0707b1b2fd1aff 100644 (file)
@@ -1,3 +1,12 @@
+2006-06-10  Ulrich Drepper  <drepper@redhat.com>
+
+       * ld.c (parse_z_option): Recognize execstack and noexecstack.
+       * ld.h (struct ld_state): Add execstack field.
+       * ldgeneric.c (add_relocatable_file): Recognize .note.GNU-stack
+       sections.
+       (ld_generic_create_outfile): Fix program header creation in native
+       linker.  Add PT_GNU_STACK program header.
+
 2006-06-09  Ulrich Drepper  <drepper@redhat.com>
 
        * i386_ld.c (elf_i386_finalize_plt): Don't change symbol table entries
index 533865694dccc2fe76e2df80b0498b4b5549a43c..79efb3ac6899d2d0759a444ddaf197438641b624 100644 (file)
--- a/src/ld.c
+++ b/src/ld.c
@@ -931,6 +931,10 @@ parse_z_option (const char *arg)
     ld_state.as_needed = false;
   else if (strcmp (arg, "systemlibrary") == 0)
     ld_state.is_system_library = true;
+  else if (strcmp (arg, "execstack") == 0)
+    ld_state.execstack = execstack_true;
+  else if (strcmp (arg, "noexecstack") == 0)
+    ld_state.execstack = execstack_false_force;
   else if (strcmp (arg, "allextract") != 0
           && strcmp (arg, "defaultextract") != 0
           && strcmp (arg, "weakextract") != 0
index 6e8e7b5faf65a2a3ddeb4df592d77c11f402648b..1d96481493309664ff5842729971f1cffedd9131 100644 (file)
--- a/src/ld.h
+++ b/src/ld.h
@@ -956,6 +956,14 @@ struct ld_state
   bool default_bind_local;
   bool default_bind_global;
 
+  /* Execuatable stack selection.  */
+  enum execstack
+    {
+      execstack_false = 0, 
+      execstack_true,
+      execstack_false_force
+    } execstack;
+
   /* True if only used sections are used.  */
   bool gc_sections;
 
index 6cad1ac7d4a566142c0cf7e9c097fae18edd6477..07cf3e192deef03f9fe1dd68ba37beabb84351c1 100644 (file)
@@ -1028,6 +1028,9 @@ add_relocatable_file (struct usedfiles *fileinfo, GElf_Word secttype)
   size_t nsymbols = 0;
   size_t nlocalsymbols = 0;
   bool has_merge_sections = false;
+  /* Unless we have different information we assume the code needs
+     an executable stack.  */
+  enum execstack execstack = execstack_true;
 
   /* Prerequisites.  */
   assert (fileinfo->elf != NULL);
@@ -1234,9 +1237,29 @@ add_relocatable_file (struct usedfiles *fileinfo, GElf_Word secttype)
                          || shdr->sh_type == SHT_INIT_ARRAY
                          || shdr->sh_type == SHT_FINI_ARRAY
                          || shdr->sh_type == SHT_PREINIT_ARRAY))
-       add_section (fileinfo, &fileinfo->scninfo[cnt]);
+       {
+         /* Check whether the check needs to be executable.  */
+         if (shdr->sh_type == SHT_PROGBITS
+             && strcmp (elf_strptr (fileinfo->elf, fileinfo->shstrndx,
+                                    shdr->sh_name),
+                        ".note.GNU-stack") == 0
+             && (shdr->sh_flags & SHF_EXECINSTR) == 0)
+           execstack = execstack_false;
+         printf("%s %d\n", elf_strptr (fileinfo->elf, fileinfo->shstrndx,
+                                       shdr->sh_name),(int)execstack);
+
+         add_section (fileinfo, &fileinfo->scninfo[cnt]);
+       }
     }
 
+  /* Now we know more about the requirements for an executable stack
+     of the result.  */
+  if (fileinfo->file_type == relocatable_file_type
+      && execstack == execstack_true
+      && ld_state.execstack != execstack_false_force)
+    ld_state.execstack = execstack_true;
+  printf("%s: state = %d\n", fileinfo->fname,(int)ld_state.execstack);
+
   /* Handle the symbols.  Record defined and undefined symbols in the
      hash table.  In theory there can be a file without any symbol
      table.  */
@@ -5573,6 +5596,10 @@ cannot create hash table section for output file: %s"),
 
         XXX Determine whether the segment is non-empty.  */
       nphdr = 0;
+
+      /* We always add a PT_GNU_stack entry.  */
+      ++nphdr;
+
       segment = ld_state.output_segments;
       while (segment != NULL)
        {
@@ -5772,7 +5799,7 @@ internal error: nobits section follows nobits section"));
       xelf_getehdr (ld_state.outelf, ehdr);
       assert (ehdr != NULL);
 
-      xelf_getphdr_ptr (ld_state.outelf, 1, phdr);
+      xelf_getphdr_ptr (ld_state.outelf, 0, phdr);
       phdr->p_type = PT_PHDR;
       phdr->p_offset = ehdr->e_phoff;
       phdr->p_vaddr = ld_state.output_segments->addr + phdr->p_offset;
@@ -5784,6 +5811,21 @@ internal error: nobits section follows nobits section"));
       (void) xelf_update_phdr (ld_state.outelf, 0, phdr);
 
 
+      /* Add the stack information.  */
+      xelf_getphdr_ptr (ld_state.outelf, nphdr, phdr);
+      phdr->p_type = PT_GNU_STACK;
+      phdr->p_offset = 0;
+      phdr->p_vaddr = 0;
+      phdr->p_paddr = 0;
+      phdr->p_filesz = 0;
+      phdr->p_memsz = 0;
+      phdr->p_flags = ld_state.execstack == execstack_true ? PF_X : 0;
+      phdr->p_align = 0;
+
+      (void) xelf_update_phdr (ld_state.outelf, nphdr, phdr);
+      ++nphdr;
+
+
       /* Adjust the addresses in the address fields of the symbol
         records according to the load addresses of the sections.  */
       if (ld_state.need_symtab)