1 /*
   2  * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "assembler_arm.inline.hpp"
  27 #include "code/codeCache.hpp"
  28 #include "memory/resourceArea.hpp"
  29 #include "nativeInst_arm.hpp"
  30 #include "compressedOops.inline.hpp"
  31 #include "oops/klass.inline.hpp"
  32 #include "oops/oop.hpp"
  33 #include "runtime/handles.hpp"
  34 #include "runtime/sharedRuntime.hpp"
  35 #include "runtime/stubRoutines.hpp"
  36 #include "utilities/ostream.hpp"
  37 #ifdef COMPILER1
  38 #include "c1/c1_Runtime1.hpp"
  39 #endif
  40 
  41 void RawNativeInstruction::verify() {
  42   // make sure code pattern is actually an instruction address
  43   address addr = instruction_address();
  44   if (addr == NULL || ((intptr_t)addr & (instruction_size - 1)) != 0) {
  45     fatal("not an instruction address");
  46   }
  47 }
  48 
  49 void NativeMovRegMem::set_offset(int x) {
  50   int scale = get_offset_scale();
  51   assert((x & right_n_bits(scale)) == 0, "offset should be aligned");
  52   guarantee((x >> 24) == 0, "encoding constraint");
  53 
  54   if (Assembler::is_unsigned_imm_in_range(x, 12, scale)) {
  55     set_unsigned_imm(x, 12, get_offset_scale(), 10);
  56     return;
  57   }
  58 
  59   // If offset is too large to be placed into single ldr/str instruction, we replace
  60   //   ldr/str  Rt, [Rn, #offset]
  61   //   nop
  62   // with
  63   //   add  LR, Rn, #offset_hi
  64   //   ldr/str  Rt, [LR, #offset_lo]
  65 
  66   // Note: Rtemp cannot be used as a temporary register as it could be used
  67   // for value being stored (see LIR_Assembler::reg2mem).
  68   // Patchable NativeMovRegMem instructions are generated in LIR_Assembler::mem2reg and LIR_Assembler::reg2mem
  69   // which do not use LR, so it is free. Also, it does not conflict with LR usages in c1_LIRGenerator_arm.cpp.
  70   const int tmp = LR->encoding();
  71   const int rn = (encoding() >> 5) & 0x1f;
  72 
  73   NativeInstruction* next = nativeInstruction_at(next_raw_instruction_address());
  74   assert(next->is_nop(), "must be");
  75 
  76   next->set_encoding((encoding() & 0xffc0001f) | Assembler::encode_unsigned_imm((x & 0xfff), 12, scale, 10) | tmp << 5);
  77   this->set_encoding(0x91400000 | Assembler::encode_unsigned_imm((x >> 12), 12, 0, 10) | rn << 5 | tmp);
  78 }
  79 
  80 intptr_t NativeMovConstReg::_data() const {
  81 #ifdef COMPILER2
  82   if (is_movz()) {
  83     // narrow constant or ic call cached value
  84     RawNativeInstruction* ni = next_raw();
  85     assert(ni->is_movk(), "movz;movk expected");
  86     uint lo16 = (encoding() >> 5) & 0xffff;
  87     intptr_t hi = 0;
  88     int i = 0;
  89     while (ni->is_movk() && i < 3) {
  90       uint hi16 = (ni->encoding() >> 5) & 0xffff;
  91       int shift = ((ni->encoding() >> 21) & 0x3) << 4;
  92       hi |= (intptr_t)hi16 << shift;
  93       ni = ni->next_raw();
  94       ++i;
  95     }
  96     return lo16 | hi;
  97   }
  98 #endif
  99   return (intptr_t)(nativeLdrLiteral_at(instruction_address())->literal_value());
 100 }
 101 
 102 static void raw_set_data(RawNativeInstruction* si, intptr_t x, oop* oop_addr, Metadata** metadata_addr) {
 103 #ifdef COMPILER2
 104   if (si->is_movz()) {
 105     // narrow constant or ic call cached value
 106     uintptr_t nx = 0;
 107     int val_size = 32;
 108     if (oop_addr != NULL) {
 109       narrowOop encoded_oop = CompressedOops::encode(*oop_addr);
 110       nx = encoded_oop;
 111     } else if (metadata_addr != NULL) {
 112       assert((*metadata_addr)->is_klass(), "expected Klass");
 113       narrowKlass encoded_k = Klass::encode_klass((Klass *)*metadata_addr);
 114       nx = encoded_k;
 115     } else {
 116       nx = x;
 117       val_size = 64;
 118     }
 119     RawNativeInstruction* ni = si->next_raw();
 120     uint lo16 = nx & 0xffff;
 121     int shift = 16;
 122     int imm16 = 0xffff << 5;
 123     si->set_encoding((si->encoding() & ~imm16) | (lo16 << 5));
 124     while (shift < val_size) {
 125       assert(ni->is_movk(), "movk expected");
 126       assert((((ni->encoding() >> 21) & 0x3) << 4) == shift, "wrong shift");
 127       uint hi16 = (nx >> shift) & 0xffff;
 128       ni->set_encoding((ni->encoding() & ~imm16) | (hi16 << 5));
 129       shift += 16;
 130       ni = ni->next_raw();
 131     }
 132     return;
 133   }
 134 #endif
 135 
 136   assert(si->is_ldr_literal(), "should be");
 137 
 138   if (oop_addr == NULL && metadata_addr == NULL) {
 139     // A static ldr_literal without oop_relocation
 140     nativeLdrLiteral_at(si->instruction_address())->set_literal_value((address)x);
 141   } else {
 142     // Oop is loaded from oops section
 143     address addr = oop_addr != NULL ? (address)oop_addr : (address)metadata_addr;
 144     int offset = addr - si->instruction_address();
 145 
 146     assert((((intptr_t)addr) & 0x7) == 0, "target address should be aligned");
 147     assert((offset & 0x3) == 0, "offset should be aligned");
 148 
 149     guarantee(Assembler::is_offset_in_range(offset, 19), "offset is not in range");
 150     nativeLdrLiteral_at(si->instruction_address())->set_literal_address(si->instruction_address() + offset);
 151   }
 152 }
 153 
 154 void NativeMovConstReg::set_data(intptr_t x) {
 155   // Find and replace the oop corresponding to this instruction in oops section
 156   oop* oop_addr = NULL;
 157   Metadata** metadata_addr = NULL;
 158   CodeBlob* cb = CodeCache::find_blob(instruction_address());
 159   {
 160     nmethod* nm = cb->as_nmethod_or_null();
 161     if (nm != NULL) {
 162       RelocIterator iter(nm, instruction_address(), next_raw()->instruction_address());
 163       while (iter.next()) {
 164         if (iter.type() == relocInfo::oop_type) {
 165           oop_addr = iter.oop_reloc()->oop_addr();
 166           *oop_addr = cast_to_oop(x);
 167           break;
 168         } else if (iter.type() == relocInfo::metadata_type) {
 169           metadata_addr = iter.metadata_reloc()->metadata_addr();
 170           *metadata_addr = (Metadata*)x;
 171           break;
 172         }
 173       }
 174     }
 175   }
 176   raw_set_data(adjust(this), x, oop_addr,  metadata_addr);
 177 }
 178 
 179 void NativeJump::check_verified_entry_alignment(address entry, address verified_entry) {
 180 }
 181 
 182 void NativeJump::patch_verified_entry(address entry, address verified_entry, address dest) {
 183   assert(dest == SharedRuntime::get_handle_wrong_method_stub(), "should be");
 184 
 185   NativeInstruction* instr = nativeInstruction_at(verified_entry);
 186   assert(instr->is_nop() || instr->encoding() == zombie_illegal_instruction, "required for MT-safe patching");
 187   instr->set_encoding(zombie_illegal_instruction);
 188 }
 189 
 190 void NativeGeneralJump::replace_mt_safe(address instr_addr, address code_buffer) {
 191   assert (nativeInstruction_at(instr_addr)->is_b(), "MT-safe patching of arbitrary instructions is not allowed");
 192   assert (nativeInstruction_at(code_buffer)->is_nop(), "MT-safe patching of arbitrary instructions is not allowed");
 193   nativeInstruction_at(instr_addr)->set_encoding(*(int*)code_buffer);
 194 }
 195 
 196 void NativeGeneralJump::insert_unconditional(address code_pos, address entry) {
 197   // Insert at code_pos unconditional B instruction jumping to entry
 198   intx offset = entry - code_pos;
 199   assert (Assembler::is_offset_in_range(offset, 26), "offset is out of range");
 200 
 201   NativeInstruction* instr = nativeInstruction_at(code_pos);
 202   assert (instr->is_b() || instr->is_nop(), "MT-safe patching of arbitrary instructions is not allowed");
 203 
 204   instr->set_encoding(0x5 << 26 | Assembler::encode_offset(offset, 26, 0));
 205 }
 206 
 207 static address call_for(address return_address) {
 208   CodeBlob* cb = CodeCache::find_blob(return_address);
 209   nmethod* nm = cb->as_nmethod_or_null();
 210   if (nm == NULL) {
 211     ShouldNotReachHere();
 212     return NULL;
 213   }
 214 
 215   // Look back 8 instructions (for LIR_Assembler::ic_call and MacroAssembler::patchable_call)
 216   address begin = return_address - 8*NativeInstruction::instruction_size;
 217   if (begin < nm->code_begin()) {
 218     begin = nm->code_begin();
 219   }
 220   RelocIterator iter(nm, begin, return_address);
 221   while (iter.next()) {
 222     Relocation* reloc = iter.reloc();
 223     if (reloc->is_call()) {
 224       address call = reloc->addr();
 225       if (nativeInstruction_at(call)->is_call()) {
 226         if (nativeCall_at(call)->return_address() == return_address) {
 227           return call;
 228         }
 229       }
 230     }
 231   }
 232 
 233   return NULL;
 234 }
 235 
 236 bool NativeCall::is_call_before(address return_address) {
 237   return (call_for(return_address) != NULL);
 238 }
 239 
 240 NativeCall* nativeCall_before(address return_address) {
 241   assert(NativeCall::is_call_before(return_address), "must be");
 242   return nativeCall_at(call_for(return_address));
 243 }