[lld] r259966 - Set max segment protection level.

Pete Cooper via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 5 16:51:16 PST 2016


Author: pete
Date: Fri Feb  5 18:51:16 2016
New Revision: 259966

URL: http://llvm.org/viewvc/llvm-project?rev=259966&view=rev
Log:
Set max segment protection level.

The initial segment protection was also being used to set the maximum
segment protection level.  Instead, the maximum should be set according
to the architecture we are linking.  For example on Mac OS it should be
RWX on most pages, but on iOS is often on R_X.

rdar://problem/24515136

Added:
    lld/trunk/test/mach-o/seg-protection-arm64.yaml
    lld/trunk/test/mach-o/seg-protection-x86_64.yaml
Modified:
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h?rev=259966&r1=259965&r2=259966&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h Fri Feb  5 18:51:16 2016
@@ -172,7 +172,8 @@ struct Segment {
   StringRef     name;
   Hex64         address;
   Hex64         size;
-  VMProtect     access;
+  VMProtect     init_access;
+  VMProtect     max_access;
 };
 
 /// Only used in normalized final linked images to specify on which dylibs

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp?rev=259966&r1=259965&r2=259966&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp Fri Feb  5 18:51:16 2016
@@ -570,7 +570,7 @@ void MachOFileLayout::buildFileOffsets()
                   llvm::dbgs() << "buildFileOffsets()\n");
   for (const Segment &sg : _file.segments) {
     _segInfo[&sg].fileOffset = fileOffset;
-    if ((_seg1addr == INT64_MAX) && sg.access)
+    if ((_seg1addr == INT64_MAX) && sg.init_access)
       _seg1addr = sg.address;
     DEBUG_WITH_TYPE("MachOFileLayout",
                   llvm::dbgs() << "  segment=" << sg.name
@@ -578,7 +578,7 @@ void MachOFileLayout::buildFileOffsets()
 
     uint32_t segFileSize = 0;
     // A segment that is not zero-fill must use a least one page of disk space.
-    if (sg.access)
+    if (sg.init_access)
       segFileSize = _file.pageSize;
     for (const Section *s : _segInfo[&sg].sections) {
       uint32_t sectOffset = s->address - sg.address;
@@ -711,8 +711,8 @@ std::error_code MachOFileLayout::writeSe
       cmd->vmsize   = llvm::alignTo(linkeditSize, _file.pageSize);
       cmd->fileoff  = _startOfLinkEdit;
       cmd->filesize = linkeditSize;
-      cmd->initprot = seg.access;
-      cmd->maxprot  = seg.access;
+      cmd->initprot = seg.init_access;
+      cmd->maxprot  = seg.max_access;
       cmd->nsects   = 0;
       cmd->flags    = 0;
       if (_swap)
@@ -731,8 +731,8 @@ std::error_code MachOFileLayout::writeSe
     cmd->vmsize   = seg.size;
     cmd->fileoff  = segInfo.fileOffset;
     cmd->filesize = segInfo.fileSize;
-    cmd->maxprot  = seg.access;
-    cmd->initprot = seg.access;
+    cmd->initprot = seg.init_access;
+    cmd->maxprot  = seg.max_access;
     cmd->nsects   = segInfo.sections.size();
     cmd->flags    = 0;
     if (_swap)

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp?rev=259966&r1=259965&r2=259966&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp Fri Feb  5 18:51:16 2016
@@ -92,13 +92,15 @@ struct SegmentInfo {
   StringRef                  name;
   uint64_t                   address;
   uint64_t                   size;
-  uint32_t                   access;
+  uint32_t                   init_access;
+  uint32_t                   max_access;
   std::vector<SectionInfo*>  sections;
   uint32_t                   normalizedSegmentIndex;
 };
 
 SegmentInfo::SegmentInfo(StringRef n)
- : name(n), address(0), size(0), access(0), normalizedSegmentIndex(0) {
+ : name(n), address(0), size(0), init_access(0), max_access(0),
+   normalizedSegmentIndex(0) {
 }
 
 class Util {
@@ -432,12 +434,38 @@ SegmentInfo *Util::segmentForName(String
       return si;
   }
   auto *info = new (_allocator) SegmentInfo(segName);
+
+  // Set the initial segment protection.
   if (segName.equals("__TEXT"))
-    info->access = VM_PROT_READ | VM_PROT_EXECUTE;
-  else if (segName.equals("__DATA"))
-    info->access = VM_PROT_READ | VM_PROT_WRITE;
+    info->init_access = VM_PROT_READ | VM_PROT_EXECUTE;
   else if (segName.equals("__PAGEZERO"))
-    info->access = 0;
+    info->init_access = 0;
+  else if (segName.equals("__LINKEDIT"))
+    info->init_access = VM_PROT_READ;
+  else {
+    // All others default to read-write
+    info->init_access = VM_PROT_READ | VM_PROT_WRITE;
+  }
+
+  // Set max segment protection
+  // Note, its overkill to use a switch statement here, but makes it so much
+  // easier to use switch coverage to catch new cases.
+  switch (_ctx.os()) {
+    case lld::MachOLinkingContext::OS::unknown:
+    case lld::MachOLinkingContext::OS::macOSX:
+    case lld::MachOLinkingContext::OS::iOS_simulator:
+      if (segName.equals("__PAGEZERO")) {
+        info->max_access = 0;
+        break;
+      }
+      // All others default to all
+      info->max_access = VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE;
+      break;
+    case lld::MachOLinkingContext::OS::iOS:
+      // iPhoneOS always uses same protection for max and initial
+      info->max_access = info->init_access;
+      break;
+  }
   _segmentInfos.push_back(info);
   return info;
 }
@@ -589,7 +617,8 @@ void Util::copySegmentInfo(NormalizedFil
     seg.name    = sgi->name;
     seg.address = sgi->address;
     seg.size    = sgi->size;
-    seg.access  = sgi->access;
+    seg.init_access  = sgi->init_access;
+    seg.max_access  = sgi->max_access;
     file.segments.push_back(seg);
   }
 }

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp?rev=259966&r1=259965&r2=259966&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp Fri Feb  5 18:51:16 2016
@@ -504,10 +504,11 @@ struct ScalarTraits<VMProtect> {
 template <>
 struct MappingTraits<Segment> {
   static void mapping(IO &io, Segment& seg) {
-    io.mapRequired("name",      seg.name);
-    io.mapRequired("address",   seg.address);
-    io.mapRequired("size",      seg.size);
-    io.mapRequired("access",    seg.access);
+    io.mapRequired("name",            seg.name);
+    io.mapRequired("address",         seg.address);
+    io.mapRequired("size",            seg.size);
+    io.mapRequired("init-access",     seg.init_access);
+    io.mapRequired("max-access",      seg.max_access);
   }
 };
 

Added: lld/trunk/test/mach-o/seg-protection-arm64.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/seg-protection-arm64.yaml?rev=259966&view=auto
==============================================================================
--- lld/trunk/test/mach-o/seg-protection-arm64.yaml (added)
+++ lld/trunk/test/mach-o/seg-protection-arm64.yaml Fri Feb  5 18:51:16 2016
@@ -0,0 +1,78 @@
+# RUN: lld -flavor darwin -arch arm64 %s %p/Inputs/hello-world-arm64.yaml -o %t && llvm-objdump -private-headers %t | FileCheck %s
+
+--- !mach-o
+arch:            arm64
+file-type:       MH_OBJECT
+flags:           [ MH_SUBSECTIONS_VIA_SYMBOLS ]
+has-UUID:        false
+OS:              unknown
+sections:
+  - segment:         __TEXT
+    section:         __text
+    type:            S_REGULAR
+    attributes:      [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
+    address:         0x0000000000000000
+    content:         [ 0x00, 0x00 ]
+global-symbols:
+  - name:            _main
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x0000000000000000
+  - name:            start
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x0000000000000001
+
+...
+
+# CHECK: Load command 0
+# CHECK:       cmd LC_SEGMENT_64
+# CHECK:   cmdsize 72
+# CHECK:   segname __PAGEZERO
+# CHECK:    vmaddr
+# CHECK:    vmsize
+# CHECK:   fileoff
+# CHECK:  filesize
+# CHECK:   maxprot ---
+# CHECK:   initprot ---
+# CHECK:    nsects 0
+# CHECK:     flags (none)
+# CHECK: Load command 1
+# CHECK:       cmd LC_SEGMENT_64
+# CHECK:   cmdsize 152
+# CHECK:   segname __TEXT
+# CHECK:    vmaddr
+# CHECK:    vmsize
+# CHECK:   fileoff
+# CHECK:  filesize
+# CHECK:   maxprot r-x
+# CHECK:   initprot r-x
+# CHECK:    nsects 1
+# CHECK:     flags (none)
+# CHECK: Section
+# CHECK:   sectname __text
+# CHECK:    segname __TEXT
+# CHECK:       addr
+# CHECK:       size
+# CHECK:     offset
+# CHECK:      align 2^0 (1)
+# CHECK:     reloff 0
+# CHECK:     nreloc 0
+# CHECK:       type S_REGULAR
+# CHECK: attributes PURE_INSTRUCTIONS SOME_INSTRUCTIONS
+# CHECK:  reserved1 0
+# CHECK:  reserved2 0
+# CHECK: Load command 2
+# CHECK:       cmd LC_SEGMENT_64
+# CHECK:   cmdsize 72
+# CHECK:   segname __LINKEDIT
+# CHECK:    vmaddr
+# CHECK:    vmsize
+# CHECK:   fileoff
+# CHECK:  filesize
+# CHECK:   maxprot r--
+# CHECK:   initprot r--
+# CHECK:    nsects 0
+# CHECK:     flags (none)

Added: lld/trunk/test/mach-o/seg-protection-x86_64.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/seg-protection-x86_64.yaml?rev=259966&view=auto
==============================================================================
--- lld/trunk/test/mach-o/seg-protection-x86_64.yaml (added)
+++ lld/trunk/test/mach-o/seg-protection-x86_64.yaml Fri Feb  5 18:51:16 2016
@@ -0,0 +1,78 @@
+# RUN: lld -flavor darwin -arch x86_64 %s %p/Inputs/hello-world-x86_64.yaml -o %t && llvm-objdump -private-headers %t | FileCheck %s
+
+--- !mach-o
+arch:            x86_64
+file-type:       MH_OBJECT
+flags:           [ MH_SUBSECTIONS_VIA_SYMBOLS ]
+has-UUID:        false
+OS:              unknown
+sections:
+  - segment:         __TEXT
+    section:         __text
+    type:            S_REGULAR
+    attributes:      [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
+    address:         0x0000000000000000
+    content:         [ 0x00, 0x00 ]
+global-symbols:
+  - name:            _main
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x0000000000000000
+  - name:            start
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x0000000000000001
+
+...
+
+# CHECK: Load command 0
+# CHECK:       cmd LC_SEGMENT_64
+# CHECK:   cmdsize 72
+# CHECK:   segname __PAGEZERO
+# CHECK:    vmaddr
+# CHECK:    vmsize
+# CHECK:   fileoff
+# CHECK:  filesize
+# CHECK:   maxprot ---
+# CHECK:   initprot ---
+# CHECK:    nsects 0
+# CHECK:     flags (none)
+# CHECK: Load command 1
+# CHECK:       cmd LC_SEGMENT_64
+# CHECK:   cmdsize 152
+# CHECK:   segname __TEXT
+# CHECK:    vmaddr
+# CHECK:    vmsize
+# CHECK:   fileoff
+# CHECK:  filesize
+# CHECK:   maxprot rwx
+# CHECK:   initprot r-x
+# CHECK:    nsects 1
+# CHECK:     flags (none)
+# CHECK: Section
+# CHECK:   sectname __text
+# CHECK:    segname __TEXT
+# CHECK:       addr
+# CHECK:       size
+# CHECK:     offset
+# CHECK:      align 2^0 (1)
+# CHECK:     reloff 0
+# CHECK:     nreloc 0
+# CHECK:       type S_REGULAR
+# CHECK: attributes PURE_INSTRUCTIONS SOME_INSTRUCTIONS
+# CHECK:  reserved1 0
+# CHECK:  reserved2 0
+# CHECK: Load command 2
+# CHECK:       cmd LC_SEGMENT_64
+# CHECK:   cmdsize 72
+# CHECK:   segname __LINKEDIT
+# CHECK:    vmaddr
+# CHECK:    vmsize
+# CHECK:   fileoff
+# CHECK:  filesize
+# CHECK:   maxprot rwx
+# CHECK:   initprot r--
+# CHECK:    nsects 0
+# CHECK:     flags (none)




More information about the llvm-commits mailing list