diff --git a/bfd/elf.c b/bfd/elf.c index 0208e05..7126e5e 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -1158,6 +1158,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_OPENBSD_RANDOMIZE: pt = "OPENBSD_RANDOMIZE"; break; default: pt = NULL; break; } return pt; @@ -2502,6 +2503,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_OPENBSD_RANDOMIZE: + return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, + "openbsd_randomize"); + default: /* Check for any processor-specific program segment types. */ bed = get_elf_backend_data (abfd); @@ -3565,6 +3570,12 @@ get_program_header_size (bfd *abfd, struct bfd_link_info *info) ++segs; } + if (bfd_get_section_by_name (abfd, ".openbsd.randomdata") != NULL) + { + /* We need a PT_OPENBSD_RANDOMIZE segment. */ + ++segs; + } + if (info != NULL && info->relro) { /* We need a PT_GNU_RELRO segment. */ @@ -3788,7 +3799,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info) bfd_boolean writable; int tls_count = 0; asection *first_tls = NULL; - asection *dynsec, *eh_frame_hdr; + asection *dynsec, *eh_frame_hdr, *randomdata; bfd_size_type amt; bfd_vma addr_mask, wrap_to = 0; @@ -4155,6 +4166,24 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info) pm = &m->next; } + /* If there is a .openbsd.randomdata section, throw in a + PT_OPENBSD_RANDOMIZE segment. */ + randomdata = bfd_get_section_by_name (abfd, ".openbsd.randomdata"); + if (randomdata != NULL && (randomdata->flags & SEC_LOAD) != 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_OPENBSD_RANDOMIZE; + m->count = 1; + m->sections[0] = randomdata; + + *pm = m; + pm = &m->next; + } + if (info != NULL && info->relro) { for (m = mfirst; m != NULL; m = m->next) diff --git a/binutils/readelf.c b/binutils/readelf.c index 5423c7f..4562bcb 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -2829,6 +2829,8 @@ get_segment_type (unsigned long p_type) return "GNU_EH_FRAME"; case PT_GNU_STACK: return "GNU_STACK"; case PT_GNU_RELRO: return "GNU_RELRO"; + case PT_OPENBSD_RANDOMIZE: + return "OPENBSD_RANDOMIZE"; default: if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC)) diff --git a/include/elf/common.h b/include/elf/common.h index 1c681d5..8f6dda0 100644 --- a/include/elf/common.h +++ b/include/elf/common.h @@ -434,6 +434,7 @@ #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_RELRO (PT_LOOS + 0x474e552) /* Read-only after relocation */ +#define PT_OPENBSD_RANDOMIZE (PT_LOOS + 0x5a3dbe6) /* Init with random bytes */ /* Program segment permissions, in program header p_flags field. */ diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc index 51a655e..4274f37 100644 --- a/ld/scripttempl/elf.sc +++ b/ld/scripttempl/elf.sc @@ -532,6 +532,12 @@ cat <