.Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME)
.Case("PT_GNU_STACK", PT_GNU_STACK)
.Case("PT_GNU_RELRO", PT_GNU_RELRO)
+ .Case("PT_OPENBSD_MUTABLE", PT_OPENBSD_MUTABLE)
.Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE)
.Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED)
.Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA)
{".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.rel.ro.",
".bss.", ".init_array.", ".fini_array.", ".ctors.", ".dtors.", ".tbss.",
".gcc_except_table.", ".tdata.", ".ARM.exidx.", ".ARM.extab.",
- ".openbsd.randomdata."})
+ ".openbsd.randomdata.", ".openbsd.mutable." })
if (isSectionPrefix(v, s->name))
return v.drop_back();
addHdr(PT_GNU_EH_FRAME, part.ehFrameHdr->getParent()->getPhdrFlags())
->add(part.ehFrameHdr->getParent());
+ // PT_OPENBSD_MUTABLE is an OpenBSD-specific feature. That makes
+ // the dynamic linker fill the segment with zero data, like bss, but
+ // it can be treated differently.
+ if (OutputSection *cmd = findSection(".openbsd.mutable", partNo))
+ addHdr(PT_OPENBSD_MUTABLE, cmd->getPhdrFlags())->add(cmd);
+
// PT_OPENBSD_RANDOMIZE is an OpenBSD-specific feature. That makes
// the dynamic linker fill the segment with random data.
if (OutputSection *cmd = findSection(".openbsd.randomdata", partNo))
PT_GNU_RELRO = 0x6474e552, // Read-only after relocation.
PT_GNU_PROPERTY = 0x6474e553, // .note.gnu.property notes sections.
+ PT_OPENBSD_MUTABLE = 0x65a3dbe5, // Like bss, but not immutable.
PT_OPENBSD_RANDOMIZE = 0x65a3dbe6, // Fill with random data.
PT_OPENBSD_WXNEEDED = 0x65a3dbe7, // Program does W^X violations.
PT_OPENBSD_BOOTDATA = 0x65a41be6, // Section for boot arguments.
case PT_OPENBSD_RANDOMIZE: pt = "OPENBSD_RANDOMIZE"; break;
case PT_OPENBSD_WXNEEDED: pt = "OPENBSD_WXNEEDED"; break;
case PT_OPENBSD_BOOTDATA: pt = "OPENBSD_BOOTDATA"; break;
+ case PT_OPENBSD_MUTABLE: pt = "OPENBSD_MUTABLE"; break;
default: pt = NULL; break;
}
return pt;
return _bfd_elf_make_section_from_phdr (abfd, hdr, index,
"openbsd_wxneeded");
+ case PT_OPENBSD_MUTABLE:
+ return _bfd_elf_make_section_from_phdr (abfd, hdr, index,
+ "openbsd_mutable");
default:
/* Check for any processor-specific program segment types. */
bed = get_elf_backend_data (abfd);
bfd_boolean writable;
int tls_count = 0;
asection *first_tls = NULL;
- asection *dynsec, *eh_frame_hdr, *randomdata;
+ asection *dynsec, *eh_frame_hdr, *randomdata, *mutabledata;
bfd_size_type amt;
if (elf_tdata (abfd)->segment_map != NULL)
pm = &m->next;
}
+ /* If there is a .openbsd.mutable section, throw in a PT_OPENBSD_MUTABLE
+ segment. */
+ mutabledata = bfd_get_section_by_name (abfd, ".openbsd.mutable");
+ if (mutabledata != NULL && (mutabledata->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_MUTABLE;
+ m->count = 1;
+ m->sections[0] = mutabledata->output_section;
+
+ *pm = m;
+ pm = &m->next;
+ }
+
if (elf_tdata (abfd)->relro)
{
amt = sizeof (struct elf_segment_map);
++segs;
}
+ if (bfd_get_section_by_name (abfd, ".openbsd.mutable") != NULL)
+ {
+ /* We need a PT_OPENBSD_MUTABLE segment. */
+ ++segs;
+ }
+
if (elf_tdata (abfd)->eh_frame_hdr)
{
/* We need a PT_GNU_EH_FRAME segment. */
return "OPENBSD_WXNEEDED";
case PT_OPENBSD_BOOTDATA:
return "OPENBSD_BOOTDATA";
+ case PT_OPENBSD_MUTABLE:
+ return "OPENBSD_MUTABLE";
default:
if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
#define PT_OPENBSD_RANDOMIZE 0x65a3dbe6 /* Fill with random data. */
#define PT_OPENBSD_WXNEEDED 0x65a3dbe7 /* Program does W^X violations */
#define PT_OPENBSD_BOOTDATA 0x65a41be6 /* Section for boot arguments */
+#define PT_OPENBSD_MUTABLE 0x65a3dbe5 /* Section for boot arguments */
/* Program segment permissions, in program header p_flags field. */
$$ = exp_intop (0x65a3dbe7);
else if (strcmp (s, "PT_OPENBSD_BOOTDATA") == 0)
$$ = exp_intop (0x65a41be6);
+ else if (strcmp (s, "PT_OPENBSD_MUTABLE") == 0)
+ $$ = exp_intop (0x65a3dbe5);
else
{
einfo (_("\
case PT_GNU_EH_FRAME: pt = "EH_FRAME"; break;
case PT_GNU_STACK: pt = "STACK"; break;
case PT_OPENBSD_RANDOMIZE: pt = "OPENBSD_RANDOMIZE"; break;
+ case PT_OPENBSD_MUTABLE: pt = "OPENBSD_MUTABLE"; break;
default: sprintf (buf, "0x%lx", p->p_type); pt = buf; break;
}
fprintf (f, "%8s off 0x", pt);
return _bfd_elf_make_section_from_phdr (abfd, hdr, index,
"openbsd_randomize");
+ case PT_OPENBSD_MUTABLE:
+ return _bfd_elf_make_section_from_phdr (abfd, hdr, index,
+ "openbsd_mutable");
+
default:
/* Check for any processor-specific program segment types.
If no handler for them, default to making "segment" sections. */
bfd_boolean writable;
int tls_count = 0;
asection *first_tls = NULL;
- asection *dynsec, *eh_frame_hdr, *randomdata;
+ asection *dynsec, *eh_frame_hdr, *randomdata, *mutabledata;
bfd_size_type amt;
if (elf_tdata (abfd)->segment_map != NULL)
pm = &m->next;
}
+ /* If there is a .openbsd.mutable section, throw in a PT_OPENBSD_MUTABLE
+ segment. */
+ mutabledata = bfd_get_section_by_name (abfd, ".openbsd.mutable");
+ if (mutabledata != NULL && (mutabledata->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_MUTABLE;
+ m->count = 1;
+ m->sections[0] = mutabledata->output_section;
+
+ *pm = m;
+ pm = &m->next;
+ }
+
free (sections);
sections = NULL;
++segs;
}
+ if (bfd_get_section_by_name (abfd, ".openbsd.mutable") != NULL)
+ {
+ /* We need a PT_OPENBSD_MUTABLE segment. */
+ ++segs;
+ }
+
if (elf_tdata (abfd)->eh_frame_hdr)
{
/* We need a PT_GNU_EH_FRAME segment. */
return "GNU_EH_FRAME";
case PT_GNU_STACK: return "STACK";
case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
+ case PT_OPENBSD_MUTABLE: return "OPENBSD_MUTABLE";
default:
if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
#define PT_GNU_STACK (PT_LOOS + 0x474e551)
#define PT_OPENBSD_RANDOMIZE 0x65a3dbe6
+#define PT_OPENBSD_MUTABLE 0x65a3dbe5
/* Program segment permissions, in program header p_flags field. */
$$ = exp_intop (0x6474e551);
else if (strcmp (s, "PT_OPENBSD_RANDOMIZE") == 0)
$$ = exp_intop (0x65a3dbe6);
+ else if (strcmp (s, "PT_OPENBSD_MUTABLE") == 0)
+ $$ = exp_intop (0x65a3dbe5);
else
{
einfo (_("\