/* TRUE if output program should be marked to request W^X permission */
bfd_boolean wxneeded;
+ /* TRUE if output program should be marked to stop branch target CFI enforcement */
+ bfd_boolean nobtcfi;
+
/* Symbol version definitions in external objects. */
Elf_Internal_Verdef *verdef;
case PT_GNU_RELRO: pt = "RELRO"; break;
case PT_OPENBSD_RANDOMIZE: pt = "OPENBSD_RANDOMIZE"; break;
case PT_OPENBSD_WXNEEDED: pt = "OPENBSD_WXNEEDED"; break;
+ case PT_OPENBSD_NOBTCFI: pt = "PT_OPENBSD_NOBTCFI"; break;
case PT_OPENBSD_BOOTDATA: pt = "OPENBSD_BOOTDATA"; break;
case PT_OPENBSD_MUTABLE: pt = "OPENBSD_MUTABLE"; break;
default: pt = NULL; break;
return _bfd_elf_make_section_from_phdr (abfd, hdr, index,
"openbsd_wxneeded");
+ case PT_OPENBSD_NOBTCFI:
+ return _bfd_elf_make_section_from_phdr (abfd, hdr, index,
+ "openbsd_nobtcfi");
+
case PT_OPENBSD_MUTABLE:
return _bfd_elf_make_section_from_phdr (abfd, hdr, index,
"openbsd_mutable");
pm = &m->next;
}
+ if (elf_tdata (abfd)->nobtcfi)
+ {
+ 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_NOBTCFI;
+ m->p_flags = 1;
+ m->p_flags_valid = 1;
+
+ *pm = m;
+ 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");
++segs;
}
+ if (elf_tdata (abfd)->nobtcfi)
+ {
+ /* We need a PT_OPENBSD_NOBTCFI segment. */
+ ++segs;
+ }
+
for (s = abfd->sections; s != NULL; s = s->next)
{
if ((s->flags & SEC_LOAD) != 0
return "OPENBSD_BOOTDATA";
case PT_OPENBSD_MUTABLE:
return "OPENBSD_MUTABLE";
+ case PT_OPENBSD_NOBTCFI:
+ return "OPENBSD_NOBTCFI";
default:
if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
/* TRUE if output program should be marked to request W^X permission */
unsigned int wxneeded: 1;
+ /* TRUE if output program should be marked to stop branch target CFI enforcement */
+ unsigned int nobtcfi: 1;
+
/* TRUE if ok to have version with no definition. */
unsigned int allow_undefined_version: 1;
#define PT_OPENBSD_RANDOMIZE 0x65a3dbe6 /* Fill with random data. */
#define PT_OPENBSD_WXNEEDED 0x65a3dbe7 /* Program does W^X violations */
+#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 */
link_info.relro = FALSE;
else if (strcmp (optarg, "wxneeded") == 0)
link_info.wxneeded = TRUE;
+ else if (strcmp (optarg, "nobtcfi") == 0)
+ link_info.nobtcfi = TRUE;
else if (strcmp (optarg, "notext") == 0)
link_info.allow_textrel = TRUE;
else if (strcmp (optarg, "text") == 0)
indicating it is expected to perform W^X violating operations later
(such as calling mprotect(2) or mmap(2) with both PROT_WRITE and PROT_EXEC).
+@item nobtcfi
+Marks the executable with a @code{PT_OPENBSD_NOBTCFI} segment header,
+indicating it is expected the binary is missing BTI/IBT instructions and
+thus the system should not enforce them as required.
+
@end table
Other keywords are ignored for Solaris compatibility.
$$ = exp_intop (0x65a3dbe6);
else if (strcmp (s, "PT_OPENBSD_WXNEEDED") == 0)
$$ = exp_intop (0x65a3dbe7);
+ else if (strcmp (s, "PT_OPENBSD_NOBTCFI") == 0)
+ $$ = exp_intop (0x65a3dbe8);
else if (strcmp (s, "PT_OPENBSD_BOOTDATA") == 0)
$$ = exp_intop (0x65a41be6);
else if (strcmp (s, "PT_OPENBSD_MUTABLE") == 0)