1 /*
   2  * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2014, Red Hat Inc. All rights reserved.
   4  * Copyright (c) 2015, Linaro Ltd. All rights reserved.
   5  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   6  *
   7  * This code is free software; you can redistribute it and/or modify it
   8  * under the terms of the GNU General Public License version 2 only, as
   9  * published by the Free Software Foundation.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  *
  25  */
  26 
  27 #include "precompiled.hpp"
  28 #include "asm/macroAssembler.hpp"
  29 #include "code/relocInfo.hpp"
  30 #include "nativeInst_aarch32.hpp"
  31 #include "oops/oop.inline.hpp"
  32 #include "runtime/safepoint.hpp"
  33 
  34 void Relocation::pd_set_data_value(address x, intptr_t o, bool verify_only) {
  35   if (verify_only)
  36     return;
  37 
  38   int bytes = 0;
  39 
  40   NativeInstruction *ni = NativeInstruction::from(addr());
  41   if (ni->is_mov_const_reg()) {
  42     NativeMovConstReg *nm = NativeMovConstReg::from(addr());
  43     nm->set_data((uintptr_t) x);
  44     bytes = nm->next_instruction_address() - nm->addr();
  45   } else {
  46     ShouldNotReachHere();
  47   }
  48 
  49   ICache::invalidate_range(addr(), bytes);
  50 }
  51 
  52 address Relocation::pd_call_destination(address orig_addr) {
  53   intptr_t adj = 0;
  54   if (orig_addr != NULL) {
  55     // We just moved this call instruction from orig_addr to addr().
  56     // This means its target will appear to have grown by addr() - orig_addr.
  57     adj = -( addr() - orig_addr );
  58   }
  59 
  60   NativeInstruction *ni = NativeInstruction::from(addr());
  61 
  62   if (ni->is_call()) {
  63     return NativeCall::from(addr())->destination();
  64   } else if (ni->is_jump()) {
  65     return NativeJump::from(addr())->jump_destination();
  66   }
  67 
  68   ShouldNotReachHere();
  69 
  70   return NULL;
  71 }
  72 
  73 void Relocation::pd_set_call_destination(address x) {
  74   assert(addr() != x, "call instruction in an infinite loop"); // FIXME what's wrong to _generate_ loop?
  75   NativeInstruction *ni = NativeInstruction::from(addr());
  76 
  77   if (ni->is_call()) {
  78     NativeCall::from(addr())->set_destination(x);
  79   } else if (ni->is_jump()) {
  80     NativeJump::from(addr())->set_jump_destination(x);
  81   } else {
  82     ShouldNotReachHere();
  83   }
  84 
  85   assert(pd_call_destination(addr()) == x, "fail in reloc");
  86 }
  87 
  88 address* Relocation::pd_address_in_code() {
  89   ShouldNotCallThis();
  90   return NULL;
  91 }
  92 
  93 address Relocation::pd_get_address_from_code() {
  94   ShouldNotCallThis();
  95   return NULL;
  96 }
  97 
  98 void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
  99   NativeInstruction *ni = NativeInstruction::from(addr());
 100   if (ni->is_mov_const_reg()) {
 101     address old_addr = old_addr_for(addr(), src, dest);
 102     NativeMovConstReg *nm2 = NativeMovConstReg::from(old_addr);
 103     NativeMovConstReg::from(addr())->set_data(nm2->data());
 104   }
 105 }
 106 
 107 void poll_return_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest)  {
 108   NativeInstruction *ni = NativeInstruction::from(addr());
 109   if (ni->is_mov_const_reg()) {
 110     address old_addr = old_addr_for(addr(), src, dest);
 111     NativeMovConstReg *nm2 = NativeMovConstReg::from(old_addr);
 112     NativeMovConstReg::from(addr())->set_data(nm2->data());
 113   }
 114 }
 115 
 116 void metadata_Relocation::pd_fix_value(address x) {
 117 }