diff options
Diffstat (limited to 'bfd/elf.c')
-rw-r--r-- | bfd/elf.c | 32 |
1 files changed, 32 insertions, 0 deletions
@@ -1673,6 +1673,7 @@ get_segment_type (unsigned int p_type) case PT_GNU_EH_FRAME: pt = "EH_FRAME"; break; case PT_GNU_STACK: pt = "STACK"; break; case PT_GNU_RELRO: pt = "RELRO"; break; + case PT_GNU_SFRAME: pt = "SFRAME"; break; default: pt = NULL; break; } return pt; @@ -3081,6 +3082,10 @@ bfd_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int hdr_index) case PT_GNU_RELRO: return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "relro"); + case PT_GNU_SFRAME: + return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, + "sframe"); + default: /* Check for any processor-specific program segment types. */ bed = get_elf_backend_data (abfd); @@ -4450,6 +4455,12 @@ get_program_header_size (bfd *abfd, struct bfd_link_info *info) ++segs; } + if (elf_sframe (abfd)) + { + /* We need a PT_GNU_SFRAME segment. */ + ++segs; + } + s = bfd_get_section_by_name (abfd, NOTE_GNU_PROPERTY_SECTION_NAME); if (s != NULL && s->size != 0) @@ -4715,6 +4726,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, asection *first_tls = NULL; asection *first_mbind = NULL; asection *dynsec, *eh_frame_hdr; + asection *sframe; size_t amt; bfd_vma addr_mask, wrap_to = 0; /* Bytes. */ bfd_size_type phdr_size; /* Octets/bytes. */ @@ -5210,6 +5222,26 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, pm = &m->next; } + /* If there is a .sframe section, throw in a PT_GNU_SFRAME + segment. */ + sframe = elf_sframe (abfd); + if (sframe != NULL + && (sframe->output_section->flags & SEC_LOAD) != 0 + && sframe->size != 0) + { + 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_SFRAME; + m->count = 1; + m->sections[0] = sframe->output_section; + + *pm = m; + pm = &m->next; + } + if (elf_stack_flags (abfd)) { amt = sizeof (struct elf_segment_map); |