[PATCH] D56058: [ORC][MIPS] Setup t9 register and call function through this register

Simon Atanasyan via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Dec 23 04:14:11 PST 2018


atanasyan created this revision.
atanasyan added reviewers: lhames, erceg95.
Herald added subscribers: arichardson, sdardis.

MIPS ABI states that every function must be called through jalr $t9. In other words, a function expect that t9 register points to the beginning of its code. A function uses this register to calculate offset to the Global Offset Table and save it to the `gp` register.

  lui   $gp, %hi(_gp_disp)
  addiu $gp, %lo(_gp_disp)
  addu  $gp, $gp, $t9

If `t9` and as a result `$gp` point to the wrong place the following code loads incorrect value from GOT and passes control to invalid code.

  lw    $v0,%call16(foo)($gp)
  jalr  $t9

OrcMips32 and OrcMips64 writeResolverCode methods pass control to the resolved address, but do not setup `$t9` before the call. The `t9` holds value of the beginning of `resolver` code so any attempts to call routines via GOT failed.

This change fixes the problem. The `OrcLazy/hidden-visibility.ll` test starts to pass correctly. Before the change it fails on MIPS because the `exitOnLazyCallThroughFailure` called from the resolver code could not call libc routine `exit` via GOT.


Repository:
  rL LLVM

https://reviews.llvm.org/D56058

Files:
  include/llvm/ExecutionEngine/Orc/OrcABISupport.h
  lib/ExecutionEngine/Orc/OrcABISupport.cpp


Index: lib/ExecutionEngine/Orc/OrcABISupport.cpp
===================================================================
--- lib/ExecutionEngine/Orc/OrcABISupport.cpp
+++ lib/ExecutionEngine/Orc/OrcABISupport.cpp
@@ -610,23 +610,19 @@
       0x8fa40008,                    // 0xe8: lw $a0,8($sp)
       0x27bd0068,                    // 0xec: addiu $sp,$sp,104
       0x0300f825,                    // 0xf0: move $ra, $t8
-      0x00000000                     // 0xf4: jr $v0/v1
+      0x00000000,                    // 0xf4: move $t9, $v0/v1
+      0x03200008                     // 0xf8: jr $t9
   };
 
   const unsigned ReentryFnAddrOffset = 0x7c;   // JIT re-entry fn addr lui
   const unsigned CallbackMgrAddrOffset = 0x6c; // Callback manager addr lui
-  const unsigned offsett = 0xf4;
+  const unsigned Offsett = 0xf4;
 
   memcpy(ResolverMem, ResolverCode, sizeof(ResolverCode));
 
-  //Depending on endian return value will be in v0 or v1.
-  uint32_t JumpV0 = 0x00400008;
-  uint32_t JumpV1 = 0x00600008;
-
-  if(isBigEndian == true)
-    memcpy(ResolverMem + offsett, &JumpV1, sizeof(JumpV1));
-  else
-    memcpy(ResolverMem + offsett, &JumpV0, sizeof(JumpV0));
+  // Depending on endian return value will be in v0 or v1.
+  uint32_t MoveVxT9 = isBigEndian ? 0x0060c825 : 0x0040c825;
+  memcpy(ResolverMem + Offsett, &MoveVxT9, sizeof(MoveVxT9));
 
   uint64_t CallMgrAddr = reinterpret_cast<uint64_t>(CallbackMgr);
   uint32_t CallMgrLUi = 0x3c040000 | (((CallMgrAddr + 0x8000) >> 16) & 0xFFFF);
@@ -814,7 +810,8 @@
       0xdfa30008,                     // 0x10c: ld v1, 8(sp)
       0x67bd00d0,                     // 0x110: daddiu $sp,$sp,208
       0x0300f825,                     // 0x114: move $ra, $t8
-      0x00400008                      // 0x118: jr $v0
+      0x0040c825,                     // 0x118: move $t9, $v0
+      0x03200008                      // 0x11c: jr $t9
   };
 
   const unsigned ReentryFnAddrOffset = 0x8c;   // JIT re-entry fn addr lui
Index: include/llvm/ExecutionEngine/Orc/OrcABISupport.h
===================================================================
--- include/llvm/ExecutionEngine/Orc/OrcABISupport.h
+++ include/llvm/ExecutionEngine/Orc/OrcABISupport.h
@@ -245,7 +245,7 @@
 public:
   static const unsigned PointerSize = 4;
   static const unsigned TrampolineSize = 20;
-  static const unsigned ResolverCodeSize = 0xf8;
+  static const unsigned ResolverCodeSize = 0xfc;
   using IndirectStubsInfo = GenericIndirectStubsInfo<16>;
 
   using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
@@ -287,7 +287,7 @@
 public:
   static const unsigned PointerSize = 8;
   static const unsigned TrampolineSize = 40;
-  static const unsigned ResolverCodeSize = 0x11C;
+  static const unsigned ResolverCodeSize = 0x120;
 
   using IndirectStubsInfo = GenericIndirectStubsInfo<32>;
   using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D56058.179437.patch
Type: text/x-patch
Size: 2893 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20181223/c13d76a4/attachment.bin>


More information about the llvm-commits mailing list