diff options
author | Ulrich Drepper <drepper@redhat.com> | 2006-06-11 00:20:43 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2006-06-11 00:20:43 +0000 |
commit | 2d88028a7b30d9e9be8e5af089cd6dcc22f80ce1 (patch) | |
tree | 5a10d1118c2d8d0d696c6b83c796c77ed7c30414 | |
parent | 697f4db2f34c054a2f93b45dbdbbaec82e34a409 (diff) | |
download | elfutils-2d88028a7b30d9e9be8e5af089cd6dcc22f80ce1.tar.gz |
Implement -z execstack/noexecstack options.
-rw-r--r-- | src/ChangeLog | 9 | ||||
-rw-r--r-- | src/ld.c | 4 | ||||
-rw-r--r-- | src/ld.h | 8 | ||||
-rw-r--r-- | src/ldgeneric.c | 46 |
4 files changed, 65 insertions, 2 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index fb4e011d..8bfd20c4 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -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 @@ -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 @@ -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; diff --git a/src/ldgeneric.c b/src/ldgeneric.c index 6cad1ac7..07cf3e19 100644 --- a/src/ldgeneric.c +++ b/src/ldgeneric.c @@ -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) |