From 0eeb2d97112c0deaf8c7741564316068f923b40d Mon Sep 17 00:00:00 2001 From: kettenis Date: Thu, 7 Dec 2023 21:57:34 +0000 Subject: [PATCH] Collect .openbsd.syscalls sections into a new PT_OPENBSD_SYSCALLS segment. This will be used soon to pin system calls to designated call sites. ok deraadt@ --- gnu/usr.bin/binutils-2.17/bfd/elf.c | 37 +++++++++++++++++++ gnu/usr.bin/binutils-2.17/binutils/readelf.c | 2 + .../binutils-2.17/include/elf/common.h | 1 + gnu/usr.bin/binutils-2.17/ld/ldgram.y | 2 + 4 files changed, 42 insertions(+) diff --git a/gnu/usr.bin/binutils-2.17/bfd/elf.c b/gnu/usr.bin/binutils-2.17/bfd/elf.c index 01d3b3445b3..b23e3a66e97 100644 --- a/gnu/usr.bin/binutils-2.17/bfd/elf.c +++ b/gnu/usr.bin/binutils-2.17/bfd/elf.c @@ -1105,6 +1105,7 @@ get_segment_type (unsigned int p_type) case PT_OPENBSD_NOBTCFI: pt = "OPENBSD_NOBTCFI"; break; case PT_OPENBSD_BOOTDATA: pt = "OPENBSD_BOOTDATA"; break; case PT_OPENBSD_MUTABLE: pt = "OPENBSD_MUTABLE"; break; + case PT_OPENBSD_SYSCALLS: pt = "OPENBSD_SYSCALLS"; break; default: pt = NULL; break; } return pt; @@ -2654,6 +2655,11 @@ bfd_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int index) case PT_OPENBSD_MUTABLE: return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "openbsd_mutable"); + + case PT_OPENBSD_SYSCALLS: + return _bfd_elf_make_section_from_phdr (abfd, hdr, index, + "openbsd_syscalls"); + default: /* Check for any processor-specific program segment types. */ bed = get_elf_backend_data (abfd); @@ -3659,6 +3665,7 @@ map_sections_to_segments (bfd *abfd) int tls_count = 0; asection *first_tls = NULL; asection *dynsec, *eh_frame_hdr, *randomdata, *mutabledata; + asection *syscalls; bfd_size_type amt; if (elf_tdata (abfd)->segment_map != NULL) @@ -4044,6 +4051,24 @@ map_sections_to_segments (bfd *abfd) pm = &m->next; } + /* If there is a .openbsd.syscalls section, throw in a PT_OPENBSD_SYSCALLS + segment. */ + syscalls = bfd_get_section_by_name (abfd, ".openbsd.syscalls"); + if (syscalls != NULL && (syscalls->flags & SEC_LOAD) == 0) + { + amt = sizeof (struct elf_segment_map); + m = bfd_zalloc (abfd, amt); + if (m == NULL) + goto error_return; + m->next = NULL; + m->p_type = PT_OPENBSD_SYSCALLS; + m->count = 1; + m->sections[0] = syscalls->output_section; + + *pm = m; + pm = &m->next; + } + if (elf_tdata (abfd)->relro) { amt = sizeof (struct elf_segment_map); @@ -4594,6 +4619,12 @@ assign_file_positions_for_segments (bfd *abfd, struct bfd_link_info *link_info) else if (p->p_type == PT_NOTE && (flags & SEC_HAS_CONTENTS) != 0) p->p_filesz += sec->size; + else if (p->p_type == PT_OPENBSD_SYSCALLS) + { + sec->filepos = off; + off += sec->size; + p->p_filesz += sec->size; + } /* .tbss is special. It doesn't contribute to p_memsz of normal segments. */ @@ -4796,6 +4827,12 @@ get_program_header_size (bfd *abfd) ++segs; } + if (bfd_get_section_by_name (abfd, ".openbsd.syscalls") != NULL) + { + /* We need a PT_OPENBSD_SYSCALLS segment. */ + ++segs; + } + if (elf_tdata (abfd)->eh_frame_hdr) { /* We need a PT_GNU_EH_FRAME segment. */ diff --git a/gnu/usr.bin/binutils-2.17/binutils/readelf.c b/gnu/usr.bin/binutils-2.17/binutils/readelf.c index 262a0b3967c..eacb32ff28c 100644 --- a/gnu/usr.bin/binutils-2.17/binutils/readelf.c +++ b/gnu/usr.bin/binutils-2.17/binutils/readelf.c @@ -2713,6 +2713,8 @@ get_segment_type (unsigned long p_type) return "OPENBSD_MUTABLE"; case PT_OPENBSD_NOBTCFI: return "OPENBSD_NOBTCFI"; + case PT_OPENBSD_SYSCALLS: + return "OPENBSD_SYSCALLS"; default: if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC)) diff --git a/gnu/usr.bin/binutils-2.17/include/elf/common.h b/gnu/usr.bin/binutils-2.17/include/elf/common.h index a494372473a..1fe2ce9ae17 100644 --- a/gnu/usr.bin/binutils-2.17/include/elf/common.h +++ b/gnu/usr.bin/binutils-2.17/include/elf/common.h @@ -315,6 +315,7 @@ #define PT_OPENBSD_NOBTCFI 0x65a3dbe8 /* no branch target CFI */ #define PT_OPENBSD_BOOTDATA 0x65a41be6 /* Section for boot arguments */ #define PT_OPENBSD_MUTABLE 0x65a3dbe5 /* Like bss, but not immutable */ +#define PT_OPENBSD_SYSCALLS 0x65a3dbe9 /* System call sites */ /* Program segment permissions, in program header p_flags field. */ diff --git a/gnu/usr.bin/binutils-2.17/ld/ldgram.y b/gnu/usr.bin/binutils-2.17/ld/ldgram.y index 5ed2a5fc752..60097ab1323 100644 --- a/gnu/usr.bin/binutils-2.17/ld/ldgram.y +++ b/gnu/usr.bin/binutils-2.17/ld/ldgram.y @@ -1101,6 +1101,8 @@ phdr_type: $$ = exp_intop (0x65a41be6); else if (strcmp (s, "PT_OPENBSD_MUTABLE") == 0) $$ = exp_intop (0x65a3dbe5); + else if (strcmp (s, "PT_OPENBSD_SYSCALLS") == 0) + $$ = exp_intop (0x65a3dbe9); else { einfo (_("\ -- 2.20.1