diff options
-rw-r--r-- | bfd/ChangeLog | 9 | ||||
-rw-r--r-- | bfd/elf-bfd.h | 3 | ||||
-rw-r--r-- | bfd/elf.c | 25 | ||||
-rw-r--r-- | bfd/elflink.h | 37 | ||||
-rw-r--r-- | binutils/ChangeLog | 4 | ||||
-rw-r--r-- | binutils/readelf.c | 1 | ||||
-rw-r--r-- | include/ChangeLog | 5 | ||||
-rw-r--r-- | include/bfdlink.h | 8 | ||||
-rw-r--r-- | include/elf/common.h | 1 | ||||
-rw-r--r-- | ld/ChangeLog | 9 | ||||
-rw-r--r-- | ld/emultempl/elf32.em | 12 | ||||
-rw-r--r-- | ld/ldgram.y | 2 | ||||
-rw-r--r-- | ld/scripttempl/elf.sc | 2 |
13 files changed, 118 insertions, 0 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 9ff266a..e2bb60a 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -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 diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 1da6055..d397307 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -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; @@ -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 diff --git a/bfd/elflink.h b/bfd/elflink.h index a7ef742..8acb7a9 100644 --- a/bfd/elflink.h +++ b/bfd/elflink.h @@ -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; diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 0b42501..3d271bf 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -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 diff --git a/binutils/readelf.c b/binutils/readelf.c index dbd802a..8e8d39e 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -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)) diff --git a/include/ChangeLog b/include/ChangeLog index 96f1777..18d0b35 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -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. diff --git a/include/bfdlink.h b/include/bfdlink.h index d68fe11..4636025 100644 --- a/include/bfdlink.h +++ b/include/bfdlink.h @@ -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; diff --git a/include/elf/common.h b/include/elf/common.h index f342d57..3635bbb 100644 --- a/include/elf/common.h +++ b/include/elf/common.h @@ -288,6 +288,7 @@ #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. */ diff --git a/ld/ChangeLog b/ld/ChangeLog index a14119f..2be279f 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -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. diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em index 11668fd..5529f32 100644 --- a/ld/emultempl/elf32.em +++ b/ld/emultempl/elf32.em @@ -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")); diff --git a/ld/ldgram.y b/ld/ldgram.y index e9c8a9f..22dbb24 100644 --- a/ld/ldgram.y +++ b/ld/ldgram.y @@ -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 (_("\ diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc index d4ffcd6..97b100e 100644 --- a/ld/scripttempl/elf.sc +++ b/ld/scripttempl/elf.sc @@ -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 |