Bug 1535194 - Always check error return from BufferOffset::diffB. r=luke a=pascalc
authorLars T Hansen <lhansen@mozilla.com>
Thu, 14 Mar 2019 16:10:58 +0100
changeset 526026 e964138e796b526597daac4125a79dca43233c6e
parent 526025 cc0d59ec03cfabb3b2c3e0aa8f92c9628bfb99bc
child 526027 97b3d94e492d245ce71546550af6a6b6e54917b2
push id2032
push userffxbld-merge
push dateMon, 13 May 2019 09:36:57 +0000
treeherdermozilla-release@455c1065dcbe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke, pascalc
bugs1535194
milestone67.0
Bug 1535194 - Always check error return from BufferOffset::diffB. r=luke a=pascalc We were missing error checks at two points. In one case an error return is meaningful; in another case it is not, as the problem should have been guarded against at a higher level by emitting far jump islands soon enough during pasteup of compiled code. Differential Revision: https://phabricator.services.mozilla.com/D23506
js/src/jit/arm/Assembler-arm.cpp
js/src/jit/arm/MacroAssembler-arm.cpp
--- a/js/src/jit/arm/Assembler-arm.cpp
+++ b/js/src/jit/arm/Assembler-arm.cpp
@@ -1822,17 +1822,22 @@ BufferOffset Assembler::as_b(BOffImm off
 BufferOffset Assembler::as_b(Label* l, Condition c) {
   if (l->bound()) {
     // Note only one instruction is emitted here, the NOP is overwritten.
     BufferOffset ret = allocBranchInst();
     if (oom()) {
       return BufferOffset();
     }
 
-    as_b(BufferOffset(l).diffB<BOffImm>(ret), c, ret);
+    BOffImm off = BufferOffset(l).diffB<BOffImm>(ret);
+    if (off.isInvalid()) {
+      m_buffer.fail_bail();
+      return BufferOffset();
+    }
+    as_b(off, c, ret);
 #ifdef JS_DISASM_ARM
     spewBranch(m_buffer.getInstOrNull(ret), refLabel(l));
 #endif
     return ret;
   }
 
   if (oom()) {
     return BufferOffset();
--- a/js/src/jit/arm/MacroAssembler-arm.cpp
+++ b/js/src/jit/arm/MacroAssembler-arm.cpp
@@ -4237,17 +4237,20 @@ CodeOffset MacroAssembler::callWithPatch
   // The caller ensures that the call is always in range using thunks (below)
   // as necessary.
   as_bl(BOffImm(), Always, /* documentation */ nullptr);
   return CodeOffset(currentOffset());
 }
 
 void MacroAssembler::patchCall(uint32_t callerOffset, uint32_t calleeOffset) {
   BufferOffset inst(callerOffset - 4);
-  as_bl(BufferOffset(calleeOffset).diffB<BOffImm>(inst), Always, inst);
+  BOffImm off = BufferOffset(calleeOffset).diffB<BOffImm>(inst);
+  MOZ_RELEASE_ASSERT(!off.isInvalid(),
+                     "Failed to insert necessary far jump islands");
+  as_bl(off, Always, inst);
 }
 
 CodeOffset MacroAssembler::farJumpWithPatch() {
   static_assert(32 * 1024 * 1024 - JumpImmediateRange >
                     wasm::MaxFuncs * 3 * sizeof(Instruction),
                 "always enough space for thunks");
 
   // The goal of the thunk is to be able to jump to any address without the