[lld] f7b752d - [lld-macho] Set the SG_READ_ONLY flag on __DATA_CONST
Daniel Bertalan via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 31 08:22:58 PDT 2022
Author: Daniel Bertalan
Date: 2022-08-31T17:04:20+02:00
New Revision: f7b752d27766ecf0241edfbdc4d7142fc40e7621
URL: https://github.com/llvm/llvm-project/commit/f7b752d27766ecf0241edfbdc4d7142fc40e7621
DIFF: https://github.com/llvm/llvm-project/commit/f7b752d27766ecf0241edfbdc4d7142fc40e7621.diff
LOG: [lld-macho] Set the SG_READ_ONLY flag on __DATA_CONST
This flag instructs dyld to make the segment read-only after fixups have
been performed.
I'm not sure why this flag is needed, as on macOS 13 beta at least,
__DATA_CONST is read-only even without this flag; but ld64 sets it as
well.
Differential Revision: https://reviews.llvm.org/D133010
Added:
Modified:
lld/MachO/OutputSegment.cpp
lld/MachO/OutputSegment.h
lld/MachO/Writer.cpp
lld/test/MachO/builtin-rename.s
llvm/include/llvm/BinaryFormat/MachO.h
llvm/tools/llvm-objdump/MachODump.cpp
Removed:
################################################################################
diff --git a/lld/MachO/OutputSegment.cpp b/lld/MachO/OutputSegment.cpp
index 91770f58b805a..fa56c1314fff6 100644
--- a/lld/MachO/OutputSegment.cpp
+++ b/lld/MachO/OutputSegment.cpp
@@ -44,6 +44,12 @@ static uint32_t maxProt(StringRef name) {
return initProt(name);
}
+static uint32_t flags(StringRef name) {
+ // If we ever implement shared cache output support, SG_READ_ONLY should not
+ // be used for dylibs that can be placed in it.
+ return name == segment_names::dataConst ? SG_READ_ONLY : 0;
+}
+
size_t OutputSegment::numNonHiddenSections() const {
size_t count = 0;
for (const OutputSection *osec : sections)
@@ -185,6 +191,7 @@ OutputSegment *macho::getOrCreateOutputSegment(StringRef name) {
segRef->name = name;
segRef->maxProt = maxProt(name);
segRef->initProt = initProt(name);
+ segRef->flags = flags(name);
outputSegments.push_back(segRef);
return segRef;
diff --git a/lld/MachO/OutputSegment.h b/lld/MachO/OutputSegment.h
index a1b6cef9e2c7c..7a0c4a2065a15 100644
--- a/lld/MachO/OutputSegment.h
+++ b/lld/MachO/OutputSegment.h
@@ -55,6 +55,7 @@ class OutputSegment {
StringRef name;
uint32_t maxProt = 0;
uint32_t initProt = 0;
+ uint32_t flags = 0;
uint8_t index;
llvm::TinyPtrVector<Defined *> segmentStartSymbols;
diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp
index 01054fe773b1f..89b14e15b3996 100644
--- a/lld/MachO/Writer.cpp
+++ b/lld/MachO/Writer.cpp
@@ -246,6 +246,7 @@ template <class LP> class LCSegment final : public LoadCommand {
c->vmsize = seg->vmSize;
c->filesize = seg->fileSize;
c->nsects = seg->numNonHiddenSections();
+ c->flags = seg->flags;
for (const OutputSection *osec : seg->getSections()) {
if (osec->isHidden())
diff --git a/lld/test/MachO/builtin-rename.s b/lld/test/MachO/builtin-rename.s
index dc9b7f8f75105..22b2479c02048 100644
--- a/lld/test/MachO/builtin-rename.s
+++ b/lld/test/MachO/builtin-rename.s
@@ -53,6 +53,23 @@
# YDATA-DAG: __DATA_CONST,__objc_protolist __DATA__objc_protolist
# YDATA-DAG: __DATA_CONST,__nl_symbol_ptr __IMPORT__pointers
+## Check that the SG_READ_ONLY flag is set on __DATA_CONST.
+# RUN: llvm-otool -v -l %t/ydata | \
+# RUN: FileCheck %s --check-prefix=FLAGS
+
+# FLAGS-LABEL: Load command 2
+# FLAGS-NEXT: cmd LC_SEGMENT_64
+# FLAGS-NEXT: cmdsize
+# FLAGS-NEXT: segname __DATA_CONST
+# FLAGS-NEXT: vmaddr
+# FLAGS-NEXT: vmsize
+# FLAGS-NEXT: fileoff
+# FLAGS-NEXT: filesize
+# FLAGS-NEXT: maxprot rw-
+# FLAGS-NEXT: initprot rw-
+# FLAGS-NEXT: nsects 13
+# FLAGS-NEXT: flags SG_READ_ONLY
+
## LLD doesn't support defining symbols in synthetic sections, so we test them
## via this slightly more awkward route.
# RUN: llvm-readobj --section-headers %t/ydata | \
diff --git a/llvm/include/llvm/BinaryFormat/MachO.h b/llvm/include/llvm/BinaryFormat/MachO.h
index 8627ed68bf09c..04be767250e61 100644
--- a/llvm/include/llvm/BinaryFormat/MachO.h
+++ b/llvm/include/llvm/BinaryFormat/MachO.h
@@ -107,6 +107,7 @@ enum : uint32_t {
SG_FVMLIB = 0x2u,
SG_NORELOC = 0x4u,
SG_PROTECTED_VERSION_1 = 0x8u,
+ SG_READ_ONLY = 0x10u,
// Constant masks for the "flags" field in llvm::MachO::section and
// llvm::MachO::section_64
diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp
index f615fbf4d81c5..a5d611e99b38e 100644
--- a/llvm/tools/llvm-objdump/MachODump.cpp
+++ b/llvm/tools/llvm-objdump/MachODump.cpp
@@ -8858,6 +8858,12 @@ static void PrintSegmentCommand(uint32_t cmd, uint32_t cmdsize,
outs() << " PROTECTED_VERSION_1";
flags &= ~MachO::SG_PROTECTED_VERSION_1;
}
+ if (flags & MachO::SG_READ_ONLY) {
+ // Apple's otool prints the SG_ prefix for this flag, but not for the
+ // others.
+ outs() << " SG_READ_ONLY";
+ flags &= ~MachO::SG_READ_ONLY;
+ }
if (flags)
outs() << format(" 0x%08" PRIx32, flags) << " (unknown flags)\n";
else
More information about the llvm-commits
mailing list