[ORC][MIPS] Setup t9 register and call function through this register
authorSimon Atanasyan <simon@atanasyan.com>
Sat, 12 Jan 2019 11:12:04 +0000 (11:12 +0000)
committerSimon Atanasyan <simon@atanasyan.com>
Sat, 12 Jan 2019 11:12:04 +0000 (11:12 +0000)
commitf903f782e706c62918d7a205701d46f701972012
tree3c18c2c5ce7c730f8d7af55ced2c707edafb6852
parenta21e2bd682a41487fc2ce9284818fcaad8e20069
[ORC][MIPS] Setup t9 register and call function through this register

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.

Differential Revision: http://reviews.llvm.org/D56058

llvm-svn: 351000
llvm/include/llvm/ExecutionEngine/Orc/OrcABISupport.h
llvm/lib/ExecutionEngine/Orc/OrcABISupport.cpp