1 /* 2 * Copyright (c) 2016, 2017, 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 26 package jdk.tools.jaotc.amd64; 27 28 import static jdk.vm.ci.amd64.AMD64.rax; 29 import static jdk.vm.ci.amd64.AMD64.rbx; 30 import static jdk.vm.ci.amd64.AMD64.rip; 31 32 import jdk.tools.jaotc.StubInformation; 33 import jdk.tools.jaotc.ELFMacroAssembler; 34 import org.graalvm.compiler.asm.amd64.AMD64Address; 35 import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler; 36 37 import jdk.vm.ci.code.TargetDescription; 38 39 public final class AMD64ELFMacroAssembler extends AMD64MacroAssembler implements ELFMacroAssembler { 40 41 private int currentEndOfInstruction; 42 43 public AMD64ELFMacroAssembler(TargetDescription target) { 44 super(target); 45 } 46 47 @Override 48 public int currentEndOfInstruction() { 49 return currentEndOfInstruction; 50 } 51 52 @Override 53 public byte[] getPLTJumpCode() { 54 // The main dispatch instruction 55 // jmpq *0x00000000(%rip) 56 jmp(new AMD64Address(rip, 0)); 57 currentEndOfInstruction = position(); 58 59 // Align to 8 bytes 60 align(8); 61 62 return close(true); 63 } 64 65 @Override 66 public byte[] getPLTStaticEntryCode(StubInformation stub) { 67 // The main dispatch instruction 68 // jmpq *0x00000000(%rip) 69 jmp(new AMD64Address(rip, 0)); 70 stub.setDispatchJumpOffset(position()); 71 72 // C2I stub used to call interpreter. 73 // mov 0x00000000(%rip),%rbx Loading Method* 74 movq(rbx, new AMD64Address(rip, 0)); 75 stub.setMovOffset(position()); 76 77 // jmpq *0x00000000(%rip) [c2i addr] 78 jmp(new AMD64Address(rip, 0)); 79 stub.setC2IJumpOffset(position()); 80 81 // Call to VM runtime to resolve the call. 82 // jmpq *0x00000000(%rip) 83 stub.setResolveJumpStart(position()); 84 jmp(new AMD64Address(rip, 0)); 85 stub.setResolveJumpOffset(position()); 86 currentEndOfInstruction = position(); 87 88 // Align to 8 bytes 89 align(8); 90 stub.setSize(position()); 91 92 return close(true); 93 } 94 95 @Override 96 public byte[] getPLTVirtualEntryCode(StubInformation stub) { 97 // Klass loading instruction 98 // mov 0x00000000(%rip),%rax 99 movq(rax, new AMD64Address(rip, 0)); 100 stub.setMovOffset(position()); 101 102 // The main dispatch instruction 103 // jmpq *0x00000000(%rip) 104 jmp(new AMD64Address(rip, 0)); 105 stub.setDispatchJumpOffset(position()); 106 107 // Call to VM runtime to resolve the call. 108 // jmpq *0x00000000(%rip) 109 stub.setResolveJumpStart(position()); 110 jmp(new AMD64Address(rip, 0)); 111 stub.setResolveJumpOffset(position()); 112 currentEndOfInstruction = position(); 113 114 // Align to 8 bytes 115 align(8); 116 stub.setSize(position()); 117 118 return close(true); 119 } 120 121 }