From 94b11780add5766507abe9dfe493186d085fdd60 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Thu, 16 Aug 2007 13:38:09 +0000 Subject: [PATCH] bfd/ 2007-08-16 H.J. Lu * elf.c (get_segment_type): Change PT_GNU_STACK to PT_GNU_ATTR. (bfd_section_from_phdr): Likewise. (get_program_header_size): Likewise. Add a PT_GNU_ATTR segment if there is an attribute section. (_bfd_elf_map_sections_to_segments): Likewise. (IS_SECTION_IN_INPUT_SEGMENT): Likewise. binutils/ 2007-08-16 H.J. Lu * readelf.c (get_segment_type): Change PT_GNU_STACK to PT_GNU_ATTR. include/elf/ 2007-08-16 H.J. Lu * common.h (PT_GNU_STACK): Renamed to ... (PT_GNU_ATTR): This. (PT_GNU_STACK): New. Make an alias of PT_GNU_ATTR. --- bfd/ChangeLog | 9 +++++ bfd/elf.c | 98 ++++++++++++++++++++++++++++++++++----------------- binutils/ChangeLog | 5 +++ binutils/readelf.c | 2 +- include/elf/ChangeLog | 6 ++++ include/elf/common.h | 3 +- 6 files changed, 89 insertions(+), 34 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 5f5d291..c5dbc97 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,12 @@ +2007-08-16 H.J. Lu + + * elf.c (get_segment_type): Change PT_GNU_STACK to PT_GNU_ATTR. + (bfd_section_from_phdr): Likewise. + (get_program_header_size): Likewise. Add a PT_GNU_ATTR segment + if there is an attribute section. + (_bfd_elf_map_sections_to_segments): Likewise. + (IS_SECTION_IN_INPUT_SEGMENT): Likewise. + 2007-08-14 H.J. Lu PR ld/4918 diff --git a/bfd/elf.c b/bfd/elf.c index ae3af35..b0e7cee 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -1083,7 +1083,7 @@ get_segment_type (unsigned int p_type) 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; + case PT_GNU_ATTR: pt = "ATTR"; break; case PT_GNU_RELRO: pt = "RELRO"; break; default: pt = NULL; break; } @@ -2355,8 +2355,8 @@ bfd_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int 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"); + case PT_GNU_ATTR: + return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "attr"); case PT_GNU_RELRO: return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "relro"); @@ -3300,7 +3300,8 @@ get_program_header_size (bfd *abfd, struct bfd_link_info *info) { size_t segs; asection *s; - const struct elf_backend_data *bed; + asection *attr = NULL; + const struct elf_backend_data *bed = get_elf_backend_data (abfd); /* Assume we will need exactly two PT_LOAD segments: one for text and one for data. */ @@ -3335,14 +3336,26 @@ get_program_header_size (bfd *abfd, struct bfd_link_info *info) ++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 (elf_section_type (s) == bed->obj_attrs_section_type) + { + BFD_ASSERT (attr == NULL); + attr = s; + + /* elf_tdata (abfd)->stack_flags is checked for the + PT_GNU_ATTR segment. If there is an attribute + section, we make sure that stack_flags isn't zero so + that the PT_GNU_ATTR segment will be created. */ + if (! elf_tdata (abfd)->stack_flags) + { + if (bed->default_execstack) + elf_tdata (abfd)->stack_flags = PF_R | PF_W | PF_X; + else + elf_tdata (abfd)->stack_flags = PF_R | PF_W; + } + } + if ((s->flags & SEC_LOAD) != 0 && CONST_STRNEQ (s->name, ".note")) { @@ -3364,6 +3377,12 @@ get_program_header_size (bfd *abfd, struct bfd_link_info *info) } } + if (elf_tdata (abfd)->stack_flags) + { + /* We need a PT_GNU_ATTR segment. */ + ++segs; + } + for (s = abfd->sections; s != NULL; s = s->next) { if (s->flags & SEC_THREAD_LOCAL) @@ -3375,7 +3394,6 @@ get_program_header_size (bfd *abfd, struct bfd_link_info *info) } /* Let the backend count up any program headers it might need. */ - bed = get_elf_backend_data (abfd); if (bed->elf_backend_additional_program_headers) { int a; @@ -3520,6 +3538,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info) asection *first_tls = NULL; asection *dynsec, *eh_frame_hdr; bfd_size_type amt; + asection *attr = NULL; /* Select the allocated sections, and sort them. */ @@ -3530,6 +3549,12 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info) i = 0; for (s = abfd->sections; s != NULL; s = s->next) { + if (elf_section_type (s) == bed->obj_attrs_section_type) + { + BFD_ASSERT (attr == NULL); + attr = s; + } + if ((s->flags & SEC_ALLOC) != 0) { sections[i] = s; @@ -3843,10 +3868,17 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info) if (m == NULL) goto error_return; m->next = NULL; - m->p_type = PT_GNU_STACK; + m->p_type = PT_GNU_ATTR; m->p_flags = elf_tdata (abfd)->stack_flags; m->p_flags_valid = 1; + if (attr) + { + /* Add the attribute section if needed. */ + m->count = 1; + m->sections[0] = attr; + } + *pm = m; pm = &m->next; } @@ -5033,31 +5065,33 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd) 2. It is an allocated segment, 3. There is an output section associated with it, 4. The section has not already been allocated to a previous segment. - 5. PT_GNU_STACK segments do not include any sections. + 5. PT_GNU_ATTR only contains attribute section. 6. PT_TLS segment includes only SHF_TLS sections. 7. SHF_TLS sections are only in PT_TLS or PT_LOAD segments. 8. PT_DYNAMIC should not contain empty sections at the beginning (with the possible exception of .dynamic). */ #define IS_SECTION_IN_INPUT_SEGMENT(section, segment, bed) \ - ((((segment->p_paddr \ - ? IS_CONTAINED_BY_LMA (section, segment, segment->p_paddr) \ - : IS_CONTAINED_BY_VMA (section, segment)) \ - && (section->flags & SEC_ALLOC) != 0) \ - || IS_COREFILE_NOTE (segment, section)) \ - && segment->p_type != PT_GNU_STACK \ - && (segment->p_type != PT_TLS \ - || (section->flags & SEC_THREAD_LOCAL)) \ - && (segment->p_type == PT_LOAD \ - || segment->p_type == PT_TLS \ - || (section->flags & SEC_THREAD_LOCAL) == 0) \ - && (segment->p_type != PT_DYNAMIC \ - || SECTION_SIZE (section, segment) > 0 \ - || (segment->p_paddr \ - ? segment->p_paddr != section->lma \ - : segment->p_vaddr != section->vma) \ - || (strcmp (bfd_get_section_name (ibfd, section), ".dynamic") \ - == 0)) \ - && ! section->segment_mark) + ((segment->p_type == PT_GNU_ATTR \ + && elf_section_type (section) == bed->obj_attrs_section_type) \ + || ((((segment->p_paddr \ + ? IS_CONTAINED_BY_LMA (section, segment, segment->p_paddr) \ + : IS_CONTAINED_BY_VMA (section, segment)) \ + && (section->flags & SEC_ALLOC) != 0) \ + || IS_COREFILE_NOTE (segment, section)) \ + && segment->p_type != PT_GNU_ATTR \ + && (segment->p_type != PT_TLS \ + || (section->flags & SEC_THREAD_LOCAL)) \ + && (segment->p_type == PT_LOAD \ + || segment->p_type == PT_TLS \ + || (section->flags & SEC_THREAD_LOCAL) == 0) \ + && (segment->p_type != PT_DYNAMIC \ + || SECTION_SIZE (section, segment) > 0 \ + || (segment->p_paddr \ + ? segment->p_paddr != section->lma \ + : segment->p_vaddr != section->vma) \ + || (strcmp (bfd_get_section_name (ibfd, section), \ + ".dynamic") == 0)) \ + && ! section->segment_mark)) /* If the output section of a section in the input segment is NULL, it is removed from the corresponding output segment. */ diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 352e722..6522f1d 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,8 @@ +2007-08-16 H.J. Lu + + * readelf.c (get_segment_type): Change PT_GNU_STACK to + PT_GNU_ATTR. + 2007-08-12 Daniel Jacobowitz * NEWS: Add a marker for the 2.18 features. diff --git a/binutils/readelf.c b/binutils/readelf.c index 7e30584..69bd55d 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -2467,7 +2467,7 @@ get_segment_type (unsigned long p_type) case PT_GNU_EH_FRAME: return "GNU_EH_FRAME"; - case PT_GNU_STACK: return "GNU_STACK"; + case PT_GNU_ATTR: return "GNU_ATTR"; case PT_GNU_RELRO: return "GNU_RELRO"; default: diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog index 8341638..5f2fa54 100644 --- a/include/elf/ChangeLog +++ b/include/elf/ChangeLog @@ -1,3 +1,9 @@ +2007-08-16 H.J. Lu + + * common.h (PT_GNU_STACK): Renamed to ... + (PT_GNU_ATTR): This. + (PT_GNU_STACK): New. Make an alias of PT_GNU_ATTR. + 2007-07-09 Roland McGrath * common.h (NT_GNU_HWCAP, NT_GNU_BUILD_ID): New macros. diff --git a/include/elf/common.h b/include/elf/common.h index bc9a5cf..2bba1e2 100644 --- a/include/elf/common.h +++ b/include/elf/common.h @@ -307,7 +307,8 @@ #define PT_GNU_EH_FRAME (PT_LOOS + 0x474e550) /* Frame unwind information */ #define PT_SUNW_EH_FRAME PT_GNU_EH_FRAME /* Solaris uses the same value */ -#define PT_GNU_STACK (PT_LOOS + 0x474e551) /* Stack flags */ +#define PT_GNU_ATTR (PT_LOOS + 0x474e551) /* Attribute info */ +#define PT_GNU_STACK PT_GNU_ATTR /* Stack flags */ #define PT_GNU_RELRO (PT_LOOS + 0x474e552) /* Read-only after relocation */ /* Program segment permissions, in program header p_flags field. */ -- 2.7.4