forked from OSchip/llvm-project
[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
This commit is contained in:
parent
eaede4b5b7
commit
f7b752d277
|
@ -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;
|
||||
|
|
|
@ -55,6 +55,7 @@ public:
|
|||
StringRef name;
|
||||
uint32_t maxProt = 0;
|
||||
uint32_t initProt = 0;
|
||||
uint32_t flags = 0;
|
||||
uint8_t index;
|
||||
|
||||
llvm::TinyPtrVector<Defined *> segmentStartSymbols;
|
||||
|
|
|
@ -246,6 +246,7 @@ public:
|
|||
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())
|
||||
|
|
|
@ -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 | \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue