From: Ulrich Drepper Date: Sun, 11 Jun 2006 00:20:43 +0000 (+0000) Subject: Implement -z execstack/noexecstack options. X-Git-Tag: elfutils-0.121~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2d88028a7b30d9e9be8e5af089cd6dcc22f80ce1;p=thirdparty%2Felfutils.git Implement -z execstack/noexecstack options. --- diff --git a/src/ChangeLog b/src/ChangeLog index fb4e011dc..8bfd20c4c 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,12 @@ +2006-06-10 Ulrich Drepper + + * 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 * i386_ld.c (elf_i386_finalize_plt): Don't change symbol table entries diff --git a/src/ld.c b/src/ld.c index 533865694..79efb3ac6 100644 --- 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 diff --git a/src/ld.h b/src/ld.h index 6e8e7b5fa..1d9648149 100644 --- 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; diff --git a/src/ldgeneric.c b/src/ldgeneric.c index 6cad1ac7d..07cf3e192 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)