Title: [222549] trunk/Source
Revision
222549
Author
[email protected]
Date
2017-09-26 22:05:27 -0700 (Tue, 26 Sep 2017)

Log Message

Put g_gigacageBasePtr into its own page and make it read-only
https://bugs.webkit.org/show_bug.cgi?id=174972

Reviewed by Michael Saboff.
        
Source/bmalloc:

This puts the gigacage base pointers into their own page and makes that page read-only.

* bmalloc/Gigacage.cpp:
(Gigacage::ensureGigacage):
(Gigacage::disablePrimitiveGigacage):
(Gigacage::addPrimitiveDisableCallback):
* bmalloc/Gigacage.h:
(Gigacage::basePtr):
(Gigacage::basePtrs):

Source/_javascript_Core:

C++ code doesn't have to know about this change. That includes C++ code that generates JIT code.
        
But the offline assembler now needs to know about how to load from offsets of global variables.
This turned out to be easy to support by extending the existing _expression_ support.

* llint/LowLevelInterpreter64.asm:
* offlineasm/ast.rb:
* offlineasm/parser.rb:
* offlineasm/transform.rb:
* offlineasm/x86.rb:

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (222548 => 222549)


--- trunk/Source/_javascript_Core/ChangeLog	2017-09-27 03:17:31 UTC (rev 222548)
+++ trunk/Source/_javascript_Core/ChangeLog	2017-09-27 05:05:27 UTC (rev 222549)
@@ -1,3 +1,21 @@
+2017-09-26  Filip Pizlo  <[email protected]>
+
+        Put g_gigacageBasePtr into its own page and make it read-only
+        https://bugs.webkit.org/show_bug.cgi?id=174972
+
+        Reviewed by Michael Saboff.
+        
+        C++ code doesn't have to know about this change. That includes C++ code that generates JIT code.
+        
+        But the offline assembler now needs to know about how to load from offsets of global variables.
+        This turned out to be easy to support by extending the existing _expression_ support.
+
+        * llint/LowLevelInterpreter64.asm:
+        * offlineasm/ast.rb:
+        * offlineasm/parser.rb:
+        * offlineasm/transform.rb:
+        * offlineasm/x86.rb:
+
 2017-09-26  Commit Queue  <[email protected]>
 
         Unreviewed, rolling out r222518.

Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm (222548 => 222549)


--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm	2017-09-27 03:17:31 UTC (rev 222548)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm	2017-09-27 05:05:27 UTC (rev 222549)
@@ -1209,7 +1209,7 @@
 
 macro loadPropertyAtVariableOffset(propertyOffsetAsInt, objectAndStorage, value)
     bilt propertyOffsetAsInt, firstOutOfLineOffset, .isInline
-    loadCaged(_g_jsValueGigacageBasePtr, constexpr JSVALUE_GIGACAGE_MASK, JSObject::m_butterfly[objectAndStorage], objectAndStorage, value)
+    loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::jsValue, constexpr JSVALUE_GIGACAGE_MASK, JSObject::m_butterfly[objectAndStorage], objectAndStorage, value)
     negi propertyOffsetAsInt
     sxi2q propertyOffsetAsInt, propertyOffsetAsInt
     jmp .ready
@@ -1222,7 +1222,7 @@
 
 macro storePropertyAtVariableOffset(propertyOffsetAsInt, objectAndStorage, value, scratch)
     bilt propertyOffsetAsInt, firstOutOfLineOffset, .isInline
-    loadCaged(_g_jsValueGigacageBasePtr, constexpr JSVALUE_GIGACAGE_MASK, JSObject::m_butterfly[objectAndStorage], objectAndStorage, scratch)
+    loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::jsValue, constexpr JSVALUE_GIGACAGE_MASK, JSObject::m_butterfly[objectAndStorage], objectAndStorage, scratch)
     negi propertyOffsetAsInt
     sxi2q propertyOffsetAsInt, propertyOffsetAsInt
     jmp .ready
@@ -1298,7 +1298,7 @@
     btiz t2, IsArray, .opGetArrayLengthSlow
     btiz t2, IndexingShapeMask, .opGetArrayLengthSlow
     loadisFromInstruction(1, t1)
-    loadCaged(_g_jsValueGigacageBasePtr, constexpr JSVALUE_GIGACAGE_MASK, JSObject::m_butterfly[t3], t0, t2)
+    loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::jsValue, constexpr JSVALUE_GIGACAGE_MASK, JSObject::m_butterfly[t3], t0, t2)
     loadi -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], t0
     bilt t0, 0, .opGetArrayLengthSlow
     orq tagTypeNumber, t0
@@ -1481,7 +1481,7 @@
     loadisFromInstruction(3, t3)
     loadConstantOrVariableInt32(t3, t1, .opGetByValSlow)
     sxi2q t1, t1
-    loadCaged(_g_jsValueGigacageBasePtr, constexpr JSVALUE_GIGACAGE_MASK, JSObject::m_butterfly[t0], t3, t5)
+    loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::jsValue, constexpr JSVALUE_GIGACAGE_MASK, JSObject::m_butterfly[t0], t3, t5)
     andi IndexingShapeMask, t2
     bieq t2, Int32Shape, .opGetByValIsContiguous
     bineq t2, ContiguousShape, .opGetByValNotContiguous
@@ -1528,7 +1528,7 @@
     bia t2, LastArrayType - FirstArrayType, .opGetByValSlow
     
     # Sweet, now we know that we have a typed array. Do some basic things now.
-    loadCaged(_g_primitiveGigacageBasePtr, constexpr PRIMITIVE_GIGACAGE_MASK, JSArrayBufferView::m_vector[t0], t3, t5)
+    loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr PRIMITIVE_GIGACAGE_MASK, JSArrayBufferView::m_vector[t0], t3, t5)
     biaeq t1, JSArrayBufferView::m_length[t0], .opGetByValSlow
     
     # Now bisect through the various types. Note that we can treat Uint8ArrayType and
@@ -1619,7 +1619,7 @@
     loadisFromInstruction(2, t0)
     loadConstantOrVariableInt32(t0, t3, .opPutByValSlow)
     sxi2q t3, t3
-    loadCaged(_g_jsValueGigacageBasePtr, constexpr JSVALUE_GIGACAGE_MASK, JSObject::m_butterfly[t1], t0, t5)
+    loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::jsValue, constexpr JSVALUE_GIGACAGE_MASK, JSObject::m_butterfly[t1], t0, t5)
     andi IndexingShapeMask, t2
     bineq t2, Int32Shape, .opPutByValNotInt32
     contiguousPutByVal(

Modified: trunk/Source/_javascript_Core/offlineasm/ast.rb (222548 => 222549)


--- trunk/Source/_javascript_Core/offlineasm/ast.rb	2017-09-27 03:17:31 UTC (rev 222548)
+++ trunk/Source/_javascript_Core/offlineasm/ast.rb	2017-09-27 05:05:27 UTC (rev 222549)
@@ -1110,12 +1110,20 @@
 
 class LabelReference < Node
     attr_reader :label
+    attr_accessor :offset
     
     def initialize(codeOrigin, label)
         super(codeOrigin)
         @label = label
+        @offset = 0
     end
     
+    def plusOffset(additionalOffset)
+        result = LabelReference.new(codeOrigin, label)
+        result.offset = @offset + additionalOffset
+        result
+    end
+    
     def children
         [@label]
     end

Modified: trunk/Source/_javascript_Core/offlineasm/parser.rb (222548 => 222549)


--- trunk/Source/_javascript_Core/offlineasm/parser.rb	2017-09-27 03:17:31 UTC (rev 222548)
+++ trunk/Source/_javascript_Core/offlineasm/parser.rb	2017-09-27 05:05:27 UTC (rev 222549)
@@ -516,7 +516,7 @@
     end
     
     def couldBeExpression
-        @tokens[@idx] == "-" or @tokens[@idx] == "~" or @tokens[@idx] == "sizeof" or @tokens[@idx] == "constexpr" or isInteger(@tokens[@idx]) or isString(@tokens[@idx]) or isVariable(@tokens[@idx]) or @tokens[@idx] == "("
+        @tokens[@idx] == "-" or @tokens[@idx] == "~" or @tokens[@idx] == "sizeof" or @tokens[@idx] == "constexpr" or isInteger(@tokens[@idx]) or isString(@tokens[@idx]) or isVariable(@tokens[@idx]) or isLabel(@tokens[@idx]) or @tokens[@idx] == "("
     end
     
     def parseExpressionAdd
@@ -574,10 +574,6 @@
             end
         elsif @tokens[@idx] == "["
             parseAddress(Immediate.new(@tokens[@idx].codeOrigin, 0))
-        elsif isLabel @tokens[@idx]
-            result = LabelReference.new(@tokens[@idx].codeOrigin, Label.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string))
-            @idx += 1
-            result
         elsif isLocalLabel @tokens[@idx]
             result = LocalLabelReference.new(@tokens[@idx].codeOrigin, LocalLabel.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string))
             @idx += 1

Modified: trunk/Source/_javascript_Core/offlineasm/transform.rb (222548 => 222549)


--- trunk/Source/_javascript_Core/offlineasm/transform.rb	2017-09-27 03:17:31 UTC (rev 222548)
+++ trunk/Source/_javascript_Core/offlineasm/transform.rb	2017-09-27 05:05:27 UTC (rev 222549)
@@ -312,6 +312,10 @@
     def fold
         @left = @left.fold
         @right = @right.fold
+        
+        return right.plusOffset(@left.value) if @left.is_a? Immediate and @right.is_a? LabelReference
+        return left.plusOffset(@right.value) if @left.is_a? LabelReference and @right.is_a? Immediate
+        
         return self unless @left.is_a? Immediate
         return self unless @right.is_a? Immediate
         Immediate.new(codeOrigin, @left.value + @right.value)
@@ -322,6 +326,9 @@
     def fold
         @left = @left.fold
         @right = @right.fold
+        
+        return left.plusOffset([email protected]) if @left.is_a? LabelReference and @right.is_a? Immediate
+        
         return self unless @left.is_a? Immediate
         return self unless @right.is_a? Immediate
         Immediate.new(codeOrigin, @left.value - @right.value)

Modified: trunk/Source/_javascript_Core/offlineasm/x86.rb (222548 => 222549)


--- trunk/Source/_javascript_Core/offlineasm/x86.rb	2017-09-27 03:17:31 UTC (rev 222548)
+++ trunk/Source/_javascript_Core/offlineasm/x86.rb	2017-09-27 05:05:27 UTC (rev 222549)
@@ -466,7 +466,7 @@
         # FIXME: Implement this on platforms that aren't Mach-O.
         # https://bugs.webkit.org/show_bug.cgi?id=175104
         $asm.puts "movq #{asmLabel}@GOTPCREL(%rip), #{dst.x86Operand(:ptr)}"
-        "(#{dst.x86Operand(kind)})"
+        "#{offset}(#{dst.x86Operand(kind)})"
     end
 end
 

Modified: trunk/Source/bmalloc/ChangeLog (222548 => 222549)


--- trunk/Source/bmalloc/ChangeLog	2017-09-27 03:17:31 UTC (rev 222548)
+++ trunk/Source/bmalloc/ChangeLog	2017-09-27 05:05:27 UTC (rev 222549)
@@ -1,3 +1,20 @@
+2017-09-26  Filip Pizlo  <[email protected]>
+
+        Put g_gigacageBasePtr into its own page and make it read-only
+        https://bugs.webkit.org/show_bug.cgi?id=174972
+
+        Reviewed by Michael Saboff.
+        
+        This puts the gigacage base pointers into their own page and makes that page read-only.
+
+        * bmalloc/Gigacage.cpp:
+        (Gigacage::ensureGigacage):
+        (Gigacage::disablePrimitiveGigacage):
+        (Gigacage::addPrimitiveDisableCallback):
+        * bmalloc/Gigacage.h:
+        (Gigacage::basePtr):
+        (Gigacage::basePtrs):
+
 2017-09-04  Adrian Perez de Castro  <[email protected]>
 
         Unreviewed build fix for Clang with libc++

Modified: trunk/Source/bmalloc/bmalloc/Gigacage.cpp (222548 => 222549)


--- trunk/Source/bmalloc/bmalloc/Gigacage.cpp	2017-09-27 03:17:31 UTC (rev 222548)
+++ trunk/Source/bmalloc/bmalloc/Gigacage.cpp	2017-09-27 05:05:27 UTC (rev 222549)
@@ -33,18 +33,44 @@
 #include <cstdio>
 #include <mutex>
 
-// FIXME: Ask dyld to put this in its own page, and mprotect the page after we ensure the gigacage.
-// https://bugs.webkit.org/show_bug.cgi?id=174972
-void* g_primitiveGigacageBasePtr;
-void* g_jsValueGigacageBasePtr;
-void* g_stringGigacageBasePtr;
+char g_gigacageBasePtrs[GIGACAGE_BASE_PTRS_SIZE] __attribute__((aligned(GIGACAGE_BASE_PTRS_SIZE)));
 
 using namespace bmalloc;
 
 namespace Gigacage {
 
-static bool s_isDisablingPrimitiveGigacageDisabled;
+namespace {
 
+bool s_isDisablingPrimitiveGigacageDisabled;
+
+void protectGigacageBasePtrs()
+{
+    uintptr_t basePtrs = reinterpret_cast<uintptr_t>(g_gigacageBasePtrs);
+    // We might only get page size alignment, but that's also the minimum we need.
+    RELEASE_BASSERT(!(basePtrs & (vmPageSize() - 1)));
+    mprotect(g_gigacageBasePtrs, GIGACAGE_BASE_PTRS_SIZE, PROT_READ);
+}
+
+void unprotectGigacageBasePtrs()
+{
+    mprotect(g_gigacageBasePtrs, GIGACAGE_BASE_PTRS_SIZE, PROT_READ | PROT_WRITE);
+}
+
+class UnprotectGigacageBasePtrsScope {
+public:
+    UnprotectGigacageBasePtrsScope()
+    {
+        unprotectGigacageBasePtrs();
+    }
+    
+    ~UnprotectGigacageBasePtrsScope()
+    {
+        protectGigacageBasePtrs();
+    }
+};
+
+} // anonymous namespce
+
 struct Callback {
     Callback() { }
     
@@ -86,6 +112,8 @@
                     
                     vmDeallocatePhysicalPages(basePtr(kind), totalSize(kind));
                 });
+            
+            protectGigacageBasePtrs();
         });
 #endif // GIGACAGE_ENABLED
 }
@@ -93,7 +121,7 @@
 void disablePrimitiveGigacage()
 {
     ensureGigacage();
-    if (!g_primitiveGigacageBasePtr) {
+    if (!basePtrs().primitive) {
         // It was never enabled. That means that we never even saved any callbacks. Or, we had already disabled
         // it before, and already called the callbacks.
         return;
@@ -104,13 +132,14 @@
     for (Callback& callback : callbacks.callbacks)
         callback.function(callback.argument);
     callbacks.callbacks.shrink(0);
-    g_primitiveGigacageBasePtr = nullptr;
+    UnprotectGigacageBasePtrsScope unprotectScope;
+    basePtrs().primitive = nullptr;
 }
 
 void addPrimitiveDisableCallback(void (*function)(void*), void* argument)
 {
     ensureGigacage();
-    if (!g_primitiveGigacageBasePtr) {
+    if (!basePtrs().primitive) {
         // It was already disabled or we were never able to enable it.
         function(argument);
         return;

Modified: trunk/Source/bmalloc/bmalloc/Gigacage.h (222548 => 222549)


--- trunk/Source/bmalloc/bmalloc/Gigacage.h	2017-09-27 03:17:31 UTC (rev 222548)
+++ trunk/Source/bmalloc/bmalloc/Gigacage.h	2017-09-27 05:05:27 UTC (rev 222549)
@@ -57,12 +57,18 @@
 #define GIGACAGE_ENABLED 0
 #endif
 
-extern "C" BEXPORT void* g_primitiveGigacageBasePtr;
-extern "C" BEXPORT void* g_jsValueGigacageBasePtr;
-extern "C" BEXPORT void* g_stringGigacageBasePtr;
+#define GIGACAGE_BASE_PTRS_SIZE 8192
 
+extern "C" BEXPORT char g_gigacageBasePtrs[GIGACAGE_BASE_PTRS_SIZE] __attribute__((aligned(GIGACAGE_BASE_PTRS_SIZE)));
+
 namespace Gigacage {
 
+struct BasePtrs {
+    void* primitive;
+    void* jsValue;
+    void* string;
+};
+
 enum Kind {
     Primitive,
     JSValue,
@@ -97,20 +103,30 @@
     return nullptr;
 }
 
-BINLINE void*& basePtr(Kind kind)
+BINLINE void*& basePtr(BasePtrs& basePtrs, Kind kind)
 {
     switch (kind) {
     case Primitive:
-        return g_primitiveGigacageBasePtr;
+        return basePtrs.primitive;
     case JSValue:
-        return g_jsValueGigacageBasePtr;
+        return basePtrs.jsValue;
     case String:
-        return g_stringGigacageBasePtr;
+        return basePtrs.string;
     }
     BCRASH();
-    return g_primitiveGigacageBasePtr;
+    return basePtrs.primitive;
 }
 
+BINLINE BasePtrs& basePtrs()
+{
+    return *reinterpret_cast<BasePtrs*>(g_gigacageBasePtrs);
+}
+
+BINLINE void*& basePtr(Kind kind)
+{
+    return basePtr(basePtrs(), kind);
+}
+
 BINLINE size_t size(Kind kind)
 {
     switch (kind) {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to