[haiku-commits] r37415 - in haiku/trunk: headers/private/system src/system/kernel

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 6 Jul 2010 23:47:08 +0200 (CEST)

Author: bonefish
Date: 2010-07-06 23:47:08 +0200 (Tue, 06 Jul 2010)
New Revision: 37415
Changeset: http://dev.haiku-os.org/changeset/37415/haiku

Modified:
   haiku/trunk/headers/private/system/elf32.h
   haiku/trunk/src/system/kernel/elf.cpp
Log:
Patch by Lucian Adrian Grijincu: Added support for loading kernel modules
with only a single readable/writable/executable text+data segment.


Modified: haiku/trunk/headers/private/system/elf32.h
===================================================================
--- haiku/trunk/headers/private/system/elf32.h  2010-07-06 21:31:04 UTC (rev 
37414)
+++ haiku/trunk/headers/private/system/elf32.h  2010-07-06 21:47:08 UTC (rev 
37415)
@@ -367,7 +367,7 @@
 inline bool
 Elf32_Phdr::IsExecutable() const
 {
-       return (p_flags & PF_PROTECTION_MASK) == (PF_READ | PF_EXECUTE);
+       return (p_flags & PF_EXECUTE) != 0;
 }
 
 

Modified: haiku/trunk/src/system/kernel/elf.cpp
===================================================================
--- haiku/trunk/src/system/kernel/elf.cpp       2010-07-06 21:31:04 UTC (rev 
37414)
+++ haiku/trunk/src/system/kernel/elf.cpp       2010-07-06 21:47:08 UTC (rev 
37415)
@@ -1965,6 +1965,8 @@
        size_t reservedSize;
        status_t status;
        ssize_t length;
+       bool textSectionWritable = false;
+       int executableHeaderCount = 0;
 
        TRACE(("elf_load_kspace: entry path '%s'\n", path));
 
@@ -2066,6 +2068,9 @@
                        B_PAGE_SIZE);
                if (end > reservedSize)
                        reservedSize = end;
+
+               if (programHeaders[i].IsExecutable())
+                       executableHeaderCount++;
        }
 
        // Check whether the segments have an unreasonable amount of unused 
space
@@ -2105,7 +2110,16 @@
                }
 
                // we're here, so it must be a PT_LOAD segment
-               if (programHeaders[i].IsReadWrite()) {
+
+               // Usually add-ons have two PT_LOAD headers: one for .data one 
or .text.
+               // x86 and PPC may differ in permission bits for .data's 
PT_LOAD header
+               // x86 is usually RW, PPC is RWE
+
+               // Some add-ons may have .text and .data concatenated in a 
single
+               // PT_LOAD RWE header and we must map that to .text.
+               if (programHeaders[i].IsReadWrite()
+                       && (!programHeaders[i].IsExecutable()
+                               || executableHeaderCount > 1)) {
                        // this is the writable segment
                        if (image->data_region.size != 0) {
                                // we've already created this segment
@@ -2122,6 +2136,9 @@
                        }
                        region = &image->text_region;
 
+                       // some programs may have .text and .data concatenated 
in a
+                       // single PT_LOAD section which is 
readable/writable/executable
+                       textSectionWritable = programHeaders[i].IsReadWrite();
                        snprintf(regionName, B_OS_NAME_LENGTH, "%s_text", 
fileName);
                } else {
                        dprintf("%s: weird program header flags 0x%lx\n", 
fileName,
@@ -2191,9 +2208,12 @@
                goto error5;
 
        // We needed to read in the contents of the "text" area, but
-       // now we can protect it read-only/execute
+       // now we can protect it read-only/execute, unless this is a
+       // special image with concatenated .text and .data, when it
+       // will also need write access.
        set_area_protection(image->text_region.id,
-               B_KERNEL_READ_AREA | B_KERNEL_EXECUTE_AREA);
+               B_KERNEL_READ_AREA | B_KERNEL_EXECUTE_AREA
+               | (textSectionWritable ? B_KERNEL_WRITE_AREA : 0));
 
        // There might be a hole between the two segments, and we don't need to
        // reserve this any longer


Other related posts:

  • » [haiku-commits] r37415 - in haiku/trunk: headers/private/system src/system/kernel - ingo_weinhold