122 lines
4.5 KiB
Text
122 lines
4.5 KiB
Text
Index: lld/ELF/Writer.cpp
|
|
--- lld/ELF/Writer.cpp.orig
|
|
+++ lld/ELF/Writer.cpp
|
|
@@ -243,6 +243,7 @@ void elf::addReservedSymbols() {
|
|
};
|
|
|
|
ElfSym::bss = add("__bss_start", 0);
|
|
+ ElfSym::data = add("__data_start", 0);
|
|
ElfSym::end1 = add("end", -1);
|
|
ElfSym::end2 = add("_end", -1);
|
|
ElfSym::etext1 = add("etext", -1);
|
|
@@ -494,6 +495,12 @@ template <class ELFT> void elf::createSyntheticSection
|
|
in.ibtPlt = std::make_unique<IBTPltSection>();
|
|
add(*in.ibtPlt);
|
|
}
|
|
+#ifdef __OpenBSD__
|
|
+ else if (config->emachine == EM_X86_64) {
|
|
+ in.ibtPlt = std::make_unique<IBTPltSection>();
|
|
+ add(*in.ibtPlt);
|
|
+ }
|
|
+#endif
|
|
|
|
if (config->emachine == EM_PPC)
|
|
in.plt = std::make_unique<PPC32GlinkSection>();
|
|
@@ -665,7 +672,7 @@ static bool shouldKeepInSymtab(const Defined &sym) {
|
|
// * --discard-locals is used.
|
|
// * The symbol is in a SHF_MERGE section, which is normally the reason for
|
|
// the assembler keeping the .L symbol.
|
|
- if (sym.getName().starts_with(".L") &&
|
|
+ if ((sym.getName().startswith(".L") || sym.getName().empty()) &&
|
|
(config->discard == DiscardPolicy::Locals ||
|
|
(sym.section && (sym.section->flags & SHF_MERGE))))
|
|
return false;
|
|
@@ -811,7 +818,11 @@ static bool isRelroSection(const OutputSection *sec) {
|
|
// However, if "-z now" is given, the lazy symbol resolution is
|
|
// disabled, which enables us to put it into RELRO.
|
|
if (sec == in.gotPlt->getParent())
|
|
+#ifndef __OpenBSD__
|
|
return config->zNow;
|
|
+#else
|
|
+ return true; /* kbind(2) means we can always put these in RELRO */
|
|
+#endif
|
|
|
|
// .dynamic section contains data for the dynamic linker, and
|
|
// there's no need to write to it at runtime, so it's better to put
|
|
@@ -1083,6 +1094,9 @@ template <class ELFT> void Writer<ELFT>::setReservedSy
|
|
ElfSym::bss->section = sbss ? sbss : findSection(".bss");
|
|
}
|
|
|
|
+ if (ElfSym::data)
|
|
+ ElfSym::data->section = findSection(".data");
|
|
+
|
|
// Setup MIPS _gp_disp/__gnu_local_gp symbols which should
|
|
// be equal to the _gp symbol's value.
|
|
if (ElfSym::mipsGp) {
|
|
@@ -2398,11 +2412,22 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(
|
|
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))
|
|
addHdr(PT_OPENBSD_RANDOMIZE, cmd->getPhdrFlags())->add(cmd);
|
|
|
|
+ // PT_OPENBSD_SYSCALLS is an OpenBSD-specific feature. That makes
|
|
+ // the kernel and dynamic linker register system call sites.
|
|
+ if (OutputSection *cmd = findSection(".openbsd.syscalls", partNo))
|
|
+ addHdr(PT_OPENBSD_SYSCALLS, cmd->getPhdrFlags())->add(cmd);
|
|
+
|
|
if (config->zGnustack != GnuStackKind::None) {
|
|
// PT_GNU_STACK is a special section to tell the loader to make the
|
|
// pages for the stack non-executable. If you really want an executable
|
|
@@ -2421,6 +2446,11 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(
|
|
if (config->zWxneeded)
|
|
addHdr(PT_OPENBSD_WXNEEDED, PF_X);
|
|
|
|
+ // PT_OPENBSD_NOBTCFI is an OpenBSD-specific header to mark that the
|
|
+ // executable is expected to violate branch-target CFI checks.
|
|
+ if (config->zNoBtCfi)
|
|
+ addHdr(PT_OPENBSD_NOBTCFI, PF_X);
|
|
+
|
|
if (OutputSection *cmd = findSection(".note.gnu.property", partNo))
|
|
addHdr(PT_GNU_PROPERTY, PF_R)->add(cmd);
|
|
|
|
@@ -2513,6 +2543,31 @@ template <class ELFT> void Writer<ELFT>::fixSectionAli
|
|
};
|
|
}
|
|
};
|
|
+
|
|
+#ifdef __OpenBSD__
|
|
+ // On i386, produce binaries that are compatible with our W^X implementation
|
|
+ if (config->emachine == EM_386) {
|
|
+ auto NXAlign = [](OutputSection *Cmd) {
|
|
+ if (Cmd && !Cmd->addrExpr)
|
|
+ Cmd->addrExpr = [=] {
|
|
+ return alignTo(script->getDot(), 0x20000000);
|
|
+ };
|
|
+ };
|
|
+
|
|
+ for (Partition &part : partitions) {
|
|
+ PhdrEntry *firstRW = nullptr;
|
|
+ for (PhdrEntry *P : part.phdrs) {
|
|
+ if (P->p_type == PT_LOAD && (P->p_flags & PF_W)) {
|
|
+ firstRW = P;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (firstRW)
|
|
+ NXAlign(firstRW->firstSec);
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
|
|
for (Partition &part : partitions) {
|
|
prev = nullptr;
|