8078521: AARCH64: Add AArch64 SA support
Add AArch64 SA support Reviewed-by: dsamersoff, dholmes
This commit is contained in:
parent
0d85af8161
commit
50746b15a9
@ -58,6 +58,7 @@ sun.jvm.hotspot.debugger.cdbg.basic.x86 \
|
|||||||
sun.jvm.hotspot.debugger.dummy \
|
sun.jvm.hotspot.debugger.dummy \
|
||||||
sun.jvm.hotspot.debugger.linux \
|
sun.jvm.hotspot.debugger.linux \
|
||||||
sun.jvm.hotspot.debugger.linux.amd64 \
|
sun.jvm.hotspot.debugger.linux.amd64 \
|
||||||
|
sun.jvm.hotspot.debugger.linux.aarch64 \
|
||||||
sun.jvm.hotspot.debugger.linux.ppc64 \
|
sun.jvm.hotspot.debugger.linux.ppc64 \
|
||||||
sun.jvm.hotspot.debugger.linux.x86 \
|
sun.jvm.hotspot.debugger.linux.x86 \
|
||||||
sun.jvm.hotspot.debugger.posix \
|
sun.jvm.hotspot.debugger.posix \
|
||||||
@ -65,6 +66,7 @@ sun.jvm.hotspot.debugger.posix.elf \
|
|||||||
sun.jvm.hotspot.debugger.ppc64 \
|
sun.jvm.hotspot.debugger.ppc64 \
|
||||||
sun.jvm.hotspot.debugger.proc \
|
sun.jvm.hotspot.debugger.proc \
|
||||||
sun.jvm.hotspot.debugger.proc.amd64 \
|
sun.jvm.hotspot.debugger.proc.amd64 \
|
||||||
|
sun.jvm.hotspot.debugger.proc.aarch64 \
|
||||||
sun.jvm.hotspot.debugger.proc.ppc64 \
|
sun.jvm.hotspot.debugger.proc.ppc64 \
|
||||||
sun.jvm.hotspot.debugger.proc.sparc \
|
sun.jvm.hotspot.debugger.proc.sparc \
|
||||||
sun.jvm.hotspot.debugger.proc.x86 \
|
sun.jvm.hotspot.debugger.proc.x86 \
|
||||||
@ -91,11 +93,13 @@ sun.jvm.hotspot.oops \
|
|||||||
sun.jvm.hotspot.prims \
|
sun.jvm.hotspot.prims \
|
||||||
sun.jvm.hotspot.runtime \
|
sun.jvm.hotspot.runtime \
|
||||||
sun.jvm.hotspot.runtime.amd64 \
|
sun.jvm.hotspot.runtime.amd64 \
|
||||||
|
sun.jvm.hotspot.runtime.aarch64 \
|
||||||
sun.jvm.hotspot.runtime.bsd \
|
sun.jvm.hotspot.runtime.bsd \
|
||||||
sun.jvm.hotspot.runtime.bsd_amd64 \
|
sun.jvm.hotspot.runtime.bsd_amd64 \
|
||||||
sun.jvm.hotspot.runtime.bsd_x86 \
|
sun.jvm.hotspot.runtime.bsd_x86 \
|
||||||
sun.jvm.hotspot.runtime.linux \
|
sun.jvm.hotspot.runtime.linux \
|
||||||
sun.jvm.hotspot.runtime.linux_amd64 \
|
sun.jvm.hotspot.runtime.linux_amd64 \
|
||||||
|
sun.jvm.hotspot.runtime.linux_aarch64 \
|
||||||
sun.jvm.hotspot.runtime.linux_ppc64 \
|
sun.jvm.hotspot.runtime.linux_ppc64 \
|
||||||
sun.jvm.hotspot.runtime.linux_sparc \
|
sun.jvm.hotspot.runtime.linux_sparc \
|
||||||
sun.jvm.hotspot.runtime.linux_x86 \
|
sun.jvm.hotspot.runtime.linux_x86 \
|
||||||
@ -149,16 +153,19 @@ sun/jvm/hotspot/debugger/dummy/*.java \
|
|||||||
sun/jvm/hotspot/debugger/linux/*.java \
|
sun/jvm/hotspot/debugger/linux/*.java \
|
||||||
sun/jvm/hotspot/debugger/linux/ppc64/*.java \
|
sun/jvm/hotspot/debugger/linux/ppc64/*.java \
|
||||||
sun/jvm/hotspot/debugger/linux/x86/*.java \
|
sun/jvm/hotspot/debugger/linux/x86/*.java \
|
||||||
|
sun/jvm/hotspot/debugger/linux/aarch64/*.java \
|
||||||
sun/jvm/hotspot/debugger/posix/*.java \
|
sun/jvm/hotspot/debugger/posix/*.java \
|
||||||
sun/jvm/hotspot/debugger/posix/elf/*.java \
|
sun/jvm/hotspot/debugger/posix/elf/*.java \
|
||||||
sun/jvm/hotspot/debugger/ppc64/*.java \
|
sun/jvm/hotspot/debugger/ppc64/*.java \
|
||||||
sun/jvm/hotspot/debugger/proc/*.java \
|
sun/jvm/hotspot/debugger/proc/*.java \
|
||||||
sun/jvm/hotspot/debugger/proc/amd64/*.java \
|
sun/jvm/hotspot/debugger/proc/amd64/*.java \
|
||||||
|
sun/jvm/hotspot/debugger/proc/aarch64/*.java \
|
||||||
sun/jvm/hotspot/debugger/proc/ppc64/*.java \
|
sun/jvm/hotspot/debugger/proc/ppc64/*.java \
|
||||||
sun/jvm/hotspot/debugger/proc/sparc/*.java \
|
sun/jvm/hotspot/debugger/proc/sparc/*.java \
|
||||||
sun/jvm/hotspot/debugger/proc/x86/*.java \
|
sun/jvm/hotspot/debugger/proc/x86/*.java \
|
||||||
sun/jvm/hotspot/debugger/remote/*.java \
|
sun/jvm/hotspot/debugger/remote/*.java \
|
||||||
sun/jvm/hotspot/debugger/remote/amd64/*.java \
|
sun/jvm/hotspot/debugger/remote/amd64/*.java \
|
||||||
|
sun/jvm/hotspot/debugger/remote/aarch64/*.java \
|
||||||
sun/jvm/hotspot/debugger/remote/ppc64/*.java \
|
sun/jvm/hotspot/debugger/remote/ppc64/*.java \
|
||||||
sun/jvm/hotspot/debugger/remote/sparc/*.java \
|
sun/jvm/hotspot/debugger/remote/sparc/*.java \
|
||||||
sun/jvm/hotspot/debugger/remote/x86/*.java \
|
sun/jvm/hotspot/debugger/remote/x86/*.java \
|
||||||
@ -178,11 +185,13 @@ sun/jvm/hotspot/opto/*.java \
|
|||||||
sun/jvm/hotspot/prims/*.java \
|
sun/jvm/hotspot/prims/*.java \
|
||||||
sun/jvm/hotspot/runtime/*.java \
|
sun/jvm/hotspot/runtime/*.java \
|
||||||
sun/jvm/hotspot/runtime/amd64/*.java \
|
sun/jvm/hotspot/runtime/amd64/*.java \
|
||||||
|
sun/jvm/hotspot/runtime/aarch64/*.java \
|
||||||
sun/jvm/hotspot/runtime/bsd/*.java \
|
sun/jvm/hotspot/runtime/bsd/*.java \
|
||||||
sun/jvm/hotspot/runtime/bsd_amd64/*.java \
|
sun/jvm/hotspot/runtime/bsd_amd64/*.java \
|
||||||
sun/jvm/hotspot/runtime/bsd_x86/*.java \
|
sun/jvm/hotspot/runtime/bsd_x86/*.java \
|
||||||
sun/jvm/hotspot/runtime/linux/*.java \
|
sun/jvm/hotspot/runtime/linux/*.java \
|
||||||
sun/jvm/hotspot/runtime/linux_amd64/*.java \
|
sun/jvm/hotspot/runtime/linux_amd64/*.java \
|
||||||
|
sun/jvm/hotspot/runtime/linux_aarch64/*.java \
|
||||||
sun/jvm/hotspot/runtime/linux_ppc64/*.java \
|
sun/jvm/hotspot/runtime/linux_ppc64/*.java \
|
||||||
sun/jvm/hotspot/runtime/linux_sparc/*.java \
|
sun/jvm/hotspot/runtime/linux_sparc/*.java \
|
||||||
sun/jvm/hotspot/runtime/linux_x86/*.java \
|
sun/jvm/hotspot/runtime/linux_x86/*.java \
|
||||||
|
@ -53,6 +53,10 @@
|
|||||||
#include "sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext.h"
|
#include "sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef aarch64
|
||||||
|
#include "sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
static jfieldID p_ps_prochandle_ID = 0;
|
static jfieldID p_ps_prochandle_ID = 0;
|
||||||
static jfieldID threadList_ID = 0;
|
static jfieldID threadList_ID = 0;
|
||||||
static jfieldID loadObjectList_ID = 0;
|
static jfieldID loadObjectList_ID = 0;
|
||||||
@ -368,7 +372,7 @@ JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLo
|
|||||||
#define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG
|
#define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG
|
||||||
#endif
|
#endif
|
||||||
#ifdef aarch64
|
#ifdef aarch64
|
||||||
#define NPRGREG 32
|
#define NPRGREG sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext_NPRGREG
|
||||||
#endif
|
#endif
|
||||||
#if defined(sparc) || defined(sparcv9)
|
#if defined(sparc) || defined(sparcv9)
|
||||||
#define NPRGREG sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_NPRGREG
|
#define NPRGREG sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_NPRGREG
|
||||||
@ -473,6 +477,13 @@ JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLo
|
|||||||
|
|
||||||
#define REG_INDEX(reg) sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext_##reg
|
#define REG_INDEX(reg) sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext_##reg
|
||||||
|
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 31; i++)
|
||||||
|
regs[i] = gregs.regs[i];
|
||||||
|
regs[REG_INDEX(SP)] = gregs.sp;
|
||||||
|
regs[REG_INDEX(PC)] = gregs.pc;
|
||||||
|
}
|
||||||
#endif /* aarch64 */
|
#endif /* aarch64 */
|
||||||
|
|
||||||
#ifdef ppc64
|
#ifdef ppc64
|
||||||
|
@ -53,14 +53,15 @@ $(ARCH)/LinuxDebuggerLocal.o: LinuxDebuggerLocal.c
|
|||||||
$(JAVAH) -jni -classpath ../../../build/classes -d $(ARCH) \
|
$(JAVAH) -jni -classpath ../../../build/classes -d $(ARCH) \
|
||||||
sun.jvm.hotspot.debugger.x86.X86ThreadContext \
|
sun.jvm.hotspot.debugger.x86.X86ThreadContext \
|
||||||
sun.jvm.hotspot.debugger.sparc.SPARCThreadContext \
|
sun.jvm.hotspot.debugger.sparc.SPARCThreadContext \
|
||||||
sun.jvm.hotspot.debugger.amd64.AMD64ThreadContext
|
sun.jvm.hotspot.debugger.amd64.AMD64ThreadContext \
|
||||||
|
sun.jvm.hotspot.debugger.aarch64.AARCH64ThreadContext
|
||||||
$(GCC) $(CFLAGS) $< -o $@
|
$(GCC) $(CFLAGS) $< -o $@
|
||||||
|
|
||||||
$(ARCH)/sadis.o: ../../share/native/sadis.c
|
$(ARCH)/sadis.o: ../../share/native/sadis.c
|
||||||
$(JAVAH) -jni -classpath ../../../build/classes -d $(ARCH) \
|
$(JAVAH) -jni -classpath ../../../build/classes -d $(ARCH) \
|
||||||
sun.jvm.hotspot.asm.Disassembler
|
sun.jvm.hotspot.asm.Disassembler
|
||||||
$(GCC) $(CFLAGS) $< -o $@
|
$(GCC) $(CFLAGS) $< -o $@
|
||||||
|
|
||||||
$(ARCH)/%.o: %.c
|
$(ARCH)/%.o: %.c
|
||||||
$(GCC) $(CFLAGS) $< -o $@
|
$(GCC) $(CFLAGS) $< -o $@
|
||||||
|
|
||||||
|
@ -983,19 +983,15 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener {
|
|||||||
curFrame.getFP(),
|
curFrame.getFP(),
|
||||||
anno));
|
anno));
|
||||||
} else {
|
} else {
|
||||||
if (VM.getVM().getCPU().equals("x86") || VM.getVM().getCPU().equals("amd64")) {
|
// For C2, which has null frame pointers on x86/amd64/aarch64
|
||||||
// For C2, which has null frame pointers on x86/amd64
|
CodeBlob cb = VM.getVM().getCodeCache().findBlob(curFrame.getPC());
|
||||||
CodeBlob cb = VM.getVM().getCodeCache().findBlob(curFrame.getPC());
|
Address sp = curFrame.getSP();
|
||||||
Address sp = curFrame.getSP();
|
if (Assert.ASSERTS_ENABLED) {
|
||||||
if (Assert.ASSERTS_ENABLED) {
|
Assert.that(cb.getFrameSize() > 0, "CodeBlob must have non-zero frame size");
|
||||||
Assert.that(cb.getFrameSize() > 0, "CodeBlob must have non-zero frame size");
|
|
||||||
}
|
|
||||||
annoPanel.addAnnotation(new Annotation(sp,
|
|
||||||
sp.addOffsetTo(cb.getFrameSize()),
|
|
||||||
anno));
|
|
||||||
} else {
|
|
||||||
Assert.that(VM.getVM().getCPU().equals("ia64"), "only ia64 should reach here");
|
|
||||||
}
|
}
|
||||||
|
annoPanel.addAnnotation(new Annotation(sp,
|
||||||
|
sp.addOffsetTo(cb.getFrameSize()),
|
||||||
|
anno));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add interpreter frame annotations
|
// Add interpreter frame annotations
|
||||||
|
@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright (c) 2015, Red Hat Inc.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sun.jvm.hotspot.debugger.aarch64;
|
||||||
|
|
||||||
|
import java.lang.annotation.Native;
|
||||||
|
|
||||||
|
import sun.jvm.hotspot.debugger.*;
|
||||||
|
import sun.jvm.hotspot.debugger.cdbg.*;
|
||||||
|
|
||||||
|
/** Specifies the thread context on aarch64 platforms; only a sub-portion
|
||||||
|
* of the context is guaranteed to be present on all operating
|
||||||
|
* systems. */
|
||||||
|
|
||||||
|
public abstract class AARCH64ThreadContext implements ThreadContext {
|
||||||
|
// Taken from /usr/include/asm/sigcontext.h on Linux/AARCH64.
|
||||||
|
|
||||||
|
// NOTE: the indices for the various registers must be maintained as
|
||||||
|
// listed across various operating systems. However, only a small
|
||||||
|
// subset of the registers' values are guaranteed to be present (and
|
||||||
|
// must be present for the SA's stack walking to work)
|
||||||
|
|
||||||
|
// One instance of the Native annotation is enough to trigger header generation
|
||||||
|
// for this file.
|
||||||
|
@Native
|
||||||
|
public static final int R0 = 0;
|
||||||
|
public static final int R1 = 1;
|
||||||
|
public static final int R2 = 2;
|
||||||
|
public static final int R3 = 3;
|
||||||
|
public static final int R4 = 4;
|
||||||
|
public static final int R5 = 5;
|
||||||
|
public static final int R6 = 6;
|
||||||
|
public static final int R7 = 7;
|
||||||
|
public static final int R8 = 8;
|
||||||
|
public static final int R9 = 9;
|
||||||
|
public static final int R10 = 10;
|
||||||
|
public static final int R11 = 11;
|
||||||
|
public static final int R12 = 12;
|
||||||
|
public static final int R13 = 13;
|
||||||
|
public static final int R14 = 14;
|
||||||
|
public static final int R15 = 15;
|
||||||
|
public static final int R16 = 16;
|
||||||
|
public static final int R17 = 17;
|
||||||
|
public static final int R18 = 18;
|
||||||
|
public static final int R19 = 19;
|
||||||
|
public static final int R20 = 20;
|
||||||
|
public static final int R21 = 21;
|
||||||
|
public static final int R22 = 22;
|
||||||
|
public static final int R23 = 23;
|
||||||
|
public static final int R24 = 24;
|
||||||
|
public static final int R25 = 25;
|
||||||
|
public static final int R26 = 26;
|
||||||
|
public static final int R27 = 27;
|
||||||
|
public static final int R28 = 28;
|
||||||
|
public static final int FP = 29;
|
||||||
|
public static final int LR = 30;
|
||||||
|
public static final int SP = 31;
|
||||||
|
public static final int PC = 32;
|
||||||
|
|
||||||
|
public static final int NPRGREG = 33;
|
||||||
|
|
||||||
|
private long[] data;
|
||||||
|
|
||||||
|
public AARCH64ThreadContext() {
|
||||||
|
data = new long[NPRGREG];
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNumRegisters() {
|
||||||
|
return NPRGREG;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRegisterName(int index) {
|
||||||
|
switch (index) {
|
||||||
|
case LR: return "lr";
|
||||||
|
case SP: return "sp";
|
||||||
|
case PC: return "pc";
|
||||||
|
default:
|
||||||
|
return "r" + index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRegister(int index, long value) {
|
||||||
|
data[index] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getRegister(int index) {
|
||||||
|
return data[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
public CFrame getTopFrame(Debugger dbg) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** This can't be implemented in this class since we would have to
|
||||||
|
* tie the implementation to, for example, the debugging system */
|
||||||
|
public abstract void setRegisterAsAddress(int index, Address value);
|
||||||
|
|
||||||
|
/** This can't be implemented in this class since we would have to
|
||||||
|
* tie the implementation to, for example, the debugging system */
|
||||||
|
public abstract Address getRegisterAsAddress(int index);
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright (c) 2015, Red Hat Inc.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -31,12 +32,14 @@ import sun.jvm.hotspot.debugger.*;
|
|||||||
import sun.jvm.hotspot.debugger.cdbg.*;
|
import sun.jvm.hotspot.debugger.cdbg.*;
|
||||||
import sun.jvm.hotspot.debugger.x86.*;
|
import sun.jvm.hotspot.debugger.x86.*;
|
||||||
import sun.jvm.hotspot.debugger.amd64.*;
|
import sun.jvm.hotspot.debugger.amd64.*;
|
||||||
|
import sun.jvm.hotspot.debugger.aarch64.*;
|
||||||
import sun.jvm.hotspot.debugger.sparc.*;
|
import sun.jvm.hotspot.debugger.sparc.*;
|
||||||
import sun.jvm.hotspot.debugger.ppc64.*;
|
import sun.jvm.hotspot.debugger.ppc64.*;
|
||||||
import sun.jvm.hotspot.debugger.linux.x86.*;
|
import sun.jvm.hotspot.debugger.linux.x86.*;
|
||||||
import sun.jvm.hotspot.debugger.linux.amd64.*;
|
import sun.jvm.hotspot.debugger.linux.amd64.*;
|
||||||
import sun.jvm.hotspot.debugger.linux.sparc.*;
|
import sun.jvm.hotspot.debugger.linux.sparc.*;
|
||||||
import sun.jvm.hotspot.debugger.linux.ppc64.*;
|
import sun.jvm.hotspot.debugger.linux.ppc64.*;
|
||||||
|
import sun.jvm.hotspot.debugger.linux.aarch64.*;
|
||||||
import sun.jvm.hotspot.utilities.*;
|
import sun.jvm.hotspot.utilities.*;
|
||||||
|
|
||||||
class LinuxCDebugger implements CDebugger {
|
class LinuxCDebugger implements CDebugger {
|
||||||
@ -106,6 +109,13 @@ class LinuxCDebugger implements CDebugger {
|
|||||||
Address pc = context.getRegisterAsAddress(PPC64ThreadContext.PC);
|
Address pc = context.getRegisterAsAddress(PPC64ThreadContext.PC);
|
||||||
if (pc == null) return null;
|
if (pc == null) return null;
|
||||||
return new LinuxPPC64CFrame(dbg, sp, pc, LinuxDebuggerLocal.getAddressSize());
|
return new LinuxPPC64CFrame(dbg, sp, pc, LinuxDebuggerLocal.getAddressSize());
|
||||||
|
} else if (cpu.equals("aarch64")) {
|
||||||
|
AARCH64ThreadContext context = (AARCH64ThreadContext) thread.getContext();
|
||||||
|
Address fp = context.getRegisterAsAddress(AARCH64ThreadContext.FP);
|
||||||
|
if (fp == null) return null;
|
||||||
|
Address pc = context.getRegisterAsAddress(AARCH64ThreadContext.PC);
|
||||||
|
if (pc == null) return null;
|
||||||
|
return new LinuxAARCH64CFrame(dbg, fp, pc);
|
||||||
} else {
|
} else {
|
||||||
// Runtime exception thrown by LinuxThreadContextFactory if unknown cpu
|
// Runtime exception thrown by LinuxThreadContextFactory if unknown cpu
|
||||||
ThreadContext context = (ThreadContext) thread.getContext();
|
ThreadContext context = (ThreadContext) thread.getContext();
|
||||||
|
@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright (c) 2015, Red Hat Inc.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sun.jvm.hotspot.debugger.linux.aarch64;
|
||||||
|
|
||||||
|
import sun.jvm.hotspot.debugger.*;
|
||||||
|
import sun.jvm.hotspot.debugger.aarch64.*;
|
||||||
|
import sun.jvm.hotspot.debugger.linux.*;
|
||||||
|
import sun.jvm.hotspot.debugger.cdbg.*;
|
||||||
|
import sun.jvm.hotspot.debugger.cdbg.basic.*;
|
||||||
|
|
||||||
|
final public class LinuxAARCH64CFrame extends BasicCFrame {
|
||||||
|
public LinuxAARCH64CFrame(LinuxDebugger dbg, Address fp, Address pc) {
|
||||||
|
super(dbg.getCDebugger());
|
||||||
|
this.fp = fp;
|
||||||
|
this.pc = pc;
|
||||||
|
this.dbg = dbg;
|
||||||
|
}
|
||||||
|
|
||||||
|
// override base class impl to avoid ELF parsing
|
||||||
|
public ClosestSymbol closestSymbolToPC() {
|
||||||
|
// try native lookup in debugger.
|
||||||
|
return dbg.lookup(dbg.getAddressValue(pc()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Address pc() {
|
||||||
|
return pc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Address localVariableBase() {
|
||||||
|
return fp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CFrame sender(ThreadProxy thread) {
|
||||||
|
AARCH64ThreadContext context = (AARCH64ThreadContext) thread.getContext();
|
||||||
|
Address rsp = context.getRegisterAsAddress(AARCH64ThreadContext.SP);
|
||||||
|
|
||||||
|
if ((fp == null) || fp.lessThan(rsp)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check alignment of fp
|
||||||
|
if (dbg.getAddressValue(fp) % (2 * ADDRESS_SIZE) != 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Address nextFP = fp.getAddressAt(0 * ADDRESS_SIZE);
|
||||||
|
if (nextFP == null || nextFP.lessThanOrEqual(fp)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Address nextPC = fp.getAddressAt(1 * ADDRESS_SIZE);
|
||||||
|
if (nextPC == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new LinuxAARCH64CFrame(dbg, nextFP, nextPC);
|
||||||
|
}
|
||||||
|
|
||||||
|
// package/class internals only
|
||||||
|
private static final int ADDRESS_SIZE = 8;
|
||||||
|
private Address pc;
|
||||||
|
private Address sp;
|
||||||
|
private Address fp;
|
||||||
|
private LinuxDebugger dbg;
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright (c) 2015, Red Hat Inc.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sun.jvm.hotspot.debugger.linux.aarch64;
|
||||||
|
|
||||||
|
import sun.jvm.hotspot.debugger.*;
|
||||||
|
import sun.jvm.hotspot.debugger.aarch64.*;
|
||||||
|
import sun.jvm.hotspot.debugger.linux.*;
|
||||||
|
|
||||||
|
public class LinuxAARCH64ThreadContext extends AARCH64ThreadContext {
|
||||||
|
private LinuxDebugger debugger;
|
||||||
|
|
||||||
|
public LinuxAARCH64ThreadContext(LinuxDebugger debugger) {
|
||||||
|
super();
|
||||||
|
this.debugger = debugger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRegisterAsAddress(int index, Address value) {
|
||||||
|
setRegister(index, debugger.getAddressValue(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Address getRegisterAsAddress(int index) {
|
||||||
|
return debugger.newAddress(getRegister(index));
|
||||||
|
}
|
||||||
|
}
|
@ -31,11 +31,13 @@ import java.lang.reflect.*;
|
|||||||
import sun.jvm.hotspot.debugger.*;
|
import sun.jvm.hotspot.debugger.*;
|
||||||
import sun.jvm.hotspot.debugger.cdbg.*;
|
import sun.jvm.hotspot.debugger.cdbg.*;
|
||||||
import sun.jvm.hotspot.debugger.proc.amd64.*;
|
import sun.jvm.hotspot.debugger.proc.amd64.*;
|
||||||
|
import sun.jvm.hotspot.debugger.proc.aarch64.*;
|
||||||
import sun.jvm.hotspot.debugger.proc.sparc.*;
|
import sun.jvm.hotspot.debugger.proc.sparc.*;
|
||||||
import sun.jvm.hotspot.debugger.proc.ppc64.*;
|
import sun.jvm.hotspot.debugger.proc.ppc64.*;
|
||||||
import sun.jvm.hotspot.debugger.proc.x86.*;
|
import sun.jvm.hotspot.debugger.proc.x86.*;
|
||||||
import sun.jvm.hotspot.debugger.ppc64.*;
|
import sun.jvm.hotspot.debugger.ppc64.*;
|
||||||
import sun.jvm.hotspot.debugger.amd64.*;
|
import sun.jvm.hotspot.debugger.amd64.*;
|
||||||
|
import sun.jvm.hotspot.debugger.aarch64.*;
|
||||||
import sun.jvm.hotspot.debugger.sparc.*;
|
import sun.jvm.hotspot.debugger.sparc.*;
|
||||||
import sun.jvm.hotspot.debugger.x86.*;
|
import sun.jvm.hotspot.debugger.x86.*;
|
||||||
import sun.jvm.hotspot.utilities.*;
|
import sun.jvm.hotspot.utilities.*;
|
||||||
@ -88,6 +90,10 @@ public class ProcDebuggerLocal extends DebuggerBase implements ProcDebugger {
|
|||||||
threadFactory = new ProcAMD64ThreadFactory(this);
|
threadFactory = new ProcAMD64ThreadFactory(this);
|
||||||
pcRegIndex = AMD64ThreadContext.RIP;
|
pcRegIndex = AMD64ThreadContext.RIP;
|
||||||
fpRegIndex = AMD64ThreadContext.RBP;
|
fpRegIndex = AMD64ThreadContext.RBP;
|
||||||
|
} else if (cpu.equals("aarch64")) {
|
||||||
|
threadFactory = new ProcAARCH64ThreadFactory(this);
|
||||||
|
pcRegIndex = AARCH64ThreadContext.PC;
|
||||||
|
fpRegIndex = AARCH64ThreadContext.FP;
|
||||||
} else if (cpu.equals("ppc64")) {
|
} else if (cpu.equals("ppc64")) {
|
||||||
threadFactory = new ProcPPC64ThreadFactory(this);
|
threadFactory = new ProcPPC64ThreadFactory(this);
|
||||||
pcRegIndex = PPC64ThreadContext.PC;
|
pcRegIndex = PPC64ThreadContext.PC;
|
||||||
|
@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright (c) 2015, Red Hat Inc.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sun.jvm.hotspot.debugger.proc.aarch64;
|
||||||
|
|
||||||
|
import sun.jvm.hotspot.debugger.*;
|
||||||
|
import sun.jvm.hotspot.debugger.aarch64.*;
|
||||||
|
import sun.jvm.hotspot.debugger.proc.*;
|
||||||
|
import sun.jvm.hotspot.utilities.*;
|
||||||
|
|
||||||
|
public class ProcAARCH64Thread implements ThreadProxy {
|
||||||
|
private ProcDebugger debugger;
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
public ProcAARCH64Thread(ProcDebugger debugger, Address addr) {
|
||||||
|
this.debugger = debugger;
|
||||||
|
|
||||||
|
// FIXME: the size here should be configurable. However, making it
|
||||||
|
// so would produce a dependency on the "types" package from the
|
||||||
|
// debugger package, which is not desired.
|
||||||
|
this.id = (int) addr.getCIntegerAt(0, 4, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProcAARCH64Thread(ProcDebugger debugger, long id) {
|
||||||
|
this.debugger = debugger;
|
||||||
|
this.id = (int) id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ThreadContext getContext() throws IllegalThreadStateException {
|
||||||
|
ProcAARCH64ThreadContext context = new ProcAARCH64ThreadContext(debugger);
|
||||||
|
long[] regs = debugger.getThreadIntegerRegisterSet(id);
|
||||||
|
if (Assert.ASSERTS_ENABLED) {
|
||||||
|
Assert.that(regs.length == AARCH64ThreadContext.NPRGREG, "size mismatch");
|
||||||
|
}
|
||||||
|
for (int i = 0; i < regs.length; i++) {
|
||||||
|
context.setRegister(i, regs[i]);
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canSetContext() throws DebuggerException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContext(ThreadContext context)
|
||||||
|
throws IllegalThreadStateException, DebuggerException {
|
||||||
|
throw new DebuggerException("Unimplemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return "t@" + id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if ((obj == null) || !(obj instanceof ProcAARCH64Thread)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (((ProcAARCH64Thread) obj).id == id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright (c) 2015, Red Hat Inc.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sun.jvm.hotspot.debugger.proc.aarch64;
|
||||||
|
|
||||||
|
import sun.jvm.hotspot.debugger.*;
|
||||||
|
import sun.jvm.hotspot.debugger.aarch64.*;
|
||||||
|
import sun.jvm.hotspot.debugger.proc.*;
|
||||||
|
|
||||||
|
public class ProcAARCH64ThreadContext extends AARCH64ThreadContext {
|
||||||
|
private ProcDebugger debugger;
|
||||||
|
|
||||||
|
public ProcAARCH64ThreadContext(ProcDebugger debugger) {
|
||||||
|
super();
|
||||||
|
this.debugger = debugger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRegisterAsAddress(int index, Address value) {
|
||||||
|
setRegister(index, debugger.getAddressValue(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Address getRegisterAsAddress(int index) {
|
||||||
|
return debugger.newAddress(getRegister(index));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright (c) 2015, Red Hat Inc.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sun.jvm.hotspot.debugger.proc.aarch64;
|
||||||
|
|
||||||
|
import sun.jvm.hotspot.debugger.*;
|
||||||
|
import sun.jvm.hotspot.debugger.proc.*;
|
||||||
|
|
||||||
|
public class ProcAARCH64ThreadFactory implements ProcThreadFactory {
|
||||||
|
private ProcDebugger debugger;
|
||||||
|
|
||||||
|
public ProcAARCH64ThreadFactory(ProcDebugger debugger) {
|
||||||
|
this.debugger = debugger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ThreadProxy createThreadWrapper(Address threadIdentifierAddr) {
|
||||||
|
return new ProcAARCH64Thread(debugger, threadIdentifierAddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ThreadProxy createThreadWrapper(long id) {
|
||||||
|
return new ProcAARCH64Thread(debugger, id);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright (c) 2015, Red Hat Inc.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sun.jvm.hotspot.debugger.remote.aarch64;
|
||||||
|
|
||||||
|
import sun.jvm.hotspot.debugger.*;
|
||||||
|
import sun.jvm.hotspot.debugger.aarch64.*;
|
||||||
|
import sun.jvm.hotspot.debugger.remote.*;
|
||||||
|
import sun.jvm.hotspot.utilities.*;
|
||||||
|
|
||||||
|
public class RemoteAARCH64Thread extends RemoteThread {
|
||||||
|
public RemoteAARCH64Thread(RemoteDebuggerClient debugger, Address addr) {
|
||||||
|
super(debugger, addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RemoteAARCH64Thread(RemoteDebuggerClient debugger, long id) {
|
||||||
|
super(debugger, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ThreadContext getContext() throws IllegalThreadStateException {
|
||||||
|
RemoteAARCH64ThreadContext context = new RemoteAARCH64ThreadContext(debugger);
|
||||||
|
long[] regs = (addr != null)? debugger.getThreadIntegerRegisterSet(addr) :
|
||||||
|
debugger.getThreadIntegerRegisterSet(id);
|
||||||
|
if (Assert.ASSERTS_ENABLED) {
|
||||||
|
Assert.that(regs.length == AARCH64ThreadContext.NPRGREG, "size of register set must match");
|
||||||
|
}
|
||||||
|
for (int i = 0; i < regs.length; i++) {
|
||||||
|
context.setRegister(i, regs[i]);
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright (c) 2015, Red Hat Inc.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sun.jvm.hotspot.debugger.remote.aarch64;
|
||||||
|
|
||||||
|
import sun.jvm.hotspot.debugger.*;
|
||||||
|
import sun.jvm.hotspot.debugger.aarch64.*;
|
||||||
|
import sun.jvm.hotspot.debugger.remote.*;
|
||||||
|
|
||||||
|
public class RemoteAARCH64ThreadContext extends AARCH64ThreadContext {
|
||||||
|
private RemoteDebuggerClient debugger;
|
||||||
|
|
||||||
|
public RemoteAARCH64ThreadContext(RemoteDebuggerClient debugger) {
|
||||||
|
super();
|
||||||
|
this.debugger = debugger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRegisterAsAddress(int index, Address value) {
|
||||||
|
setRegister(index, debugger.getAddressValue(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Address getRegisterAsAddress(int index) {
|
||||||
|
return debugger.newAddress(getRegister(index));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright (c) 2015, Red Hat Inc.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sun.jvm.hotspot.debugger.remote.aarch64;
|
||||||
|
|
||||||
|
import sun.jvm.hotspot.debugger.*;
|
||||||
|
import sun.jvm.hotspot.debugger.remote.*;
|
||||||
|
|
||||||
|
public class RemoteAARCH64ThreadFactory implements RemoteThreadFactory {
|
||||||
|
private RemoteDebuggerClient debugger;
|
||||||
|
|
||||||
|
public RemoteAARCH64ThreadFactory(RemoteDebuggerClient debugger) {
|
||||||
|
this.debugger = debugger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ThreadProxy createThreadWrapper(Address threadIdentifierAddr) {
|
||||||
|
return new RemoteAARCH64Thread(debugger, threadIdentifierAddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ThreadProxy createThreadWrapper(long id) {
|
||||||
|
return new RemoteAARCH64Thread(debugger, id);
|
||||||
|
}
|
||||||
|
}
|
@ -35,6 +35,7 @@ import sun.jvm.hotspot.runtime.win32_amd64.Win32AMD64JavaThreadPDAccess;
|
|||||||
import sun.jvm.hotspot.runtime.win32_x86.Win32X86JavaThreadPDAccess;
|
import sun.jvm.hotspot.runtime.win32_x86.Win32X86JavaThreadPDAccess;
|
||||||
import sun.jvm.hotspot.runtime.linux_x86.LinuxX86JavaThreadPDAccess;
|
import sun.jvm.hotspot.runtime.linux_x86.LinuxX86JavaThreadPDAccess;
|
||||||
import sun.jvm.hotspot.runtime.linux_amd64.LinuxAMD64JavaThreadPDAccess;
|
import sun.jvm.hotspot.runtime.linux_amd64.LinuxAMD64JavaThreadPDAccess;
|
||||||
|
import sun.jvm.hotspot.runtime.linux_aarch64.LinuxAARCH64JavaThreadPDAccess;
|
||||||
import sun.jvm.hotspot.runtime.linux_ppc64.LinuxPPC64JavaThreadPDAccess;
|
import sun.jvm.hotspot.runtime.linux_ppc64.LinuxPPC64JavaThreadPDAccess;
|
||||||
import sun.jvm.hotspot.runtime.linux_sparc.LinuxSPARCJavaThreadPDAccess;
|
import sun.jvm.hotspot.runtime.linux_sparc.LinuxSPARCJavaThreadPDAccess;
|
||||||
import sun.jvm.hotspot.runtime.bsd_x86.BsdX86JavaThreadPDAccess;
|
import sun.jvm.hotspot.runtime.bsd_x86.BsdX86JavaThreadPDAccess;
|
||||||
@ -91,6 +92,8 @@ public class Threads {
|
|||||||
access = new LinuxSPARCJavaThreadPDAccess();
|
access = new LinuxSPARCJavaThreadPDAccess();
|
||||||
} else if (cpu.equals("ppc64")) {
|
} else if (cpu.equals("ppc64")) {
|
||||||
access = new LinuxPPC64JavaThreadPDAccess();
|
access = new LinuxPPC64JavaThreadPDAccess();
|
||||||
|
} else if (cpu.equals("aarch64")) {
|
||||||
|
access = new LinuxAARCH64JavaThreadPDAccess();
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
access = (JavaThreadPDAccess)
|
access = (JavaThreadPDAccess)
|
||||||
|
@ -0,0 +1,244 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright (c) 2015, Red Hat Inc.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sun.jvm.hotspot.runtime.aarch64;
|
||||||
|
|
||||||
|
import sun.jvm.hotspot.debugger.*;
|
||||||
|
import sun.jvm.hotspot.debugger.aarch64.*;
|
||||||
|
import sun.jvm.hotspot.code.*;
|
||||||
|
import sun.jvm.hotspot.interpreter.*;
|
||||||
|
import sun.jvm.hotspot.runtime.*;
|
||||||
|
import sun.jvm.hotspot.runtime.aarch64.*;
|
||||||
|
|
||||||
|
/** <P> Should be able to be used on all aarch64 platforms we support
|
||||||
|
(Linux/aarch64) to implement JavaThread's "currentFrameGuess()"
|
||||||
|
functionality. Input is an AARCH64ThreadContext; output is SP, FP,
|
||||||
|
and PC for an AARCH64Frame. Instantiation of the AARCH64Frame is
|
||||||
|
left to the caller, since we may need to subclass AARCH64Frame to
|
||||||
|
support signal handler frames on Unix platforms. </P>
|
||||||
|
|
||||||
|
<P> Algorithm is to walk up the stack within a given range (say,
|
||||||
|
512K at most) looking for a plausible PC and SP for a Java frame,
|
||||||
|
also considering those coming in from the context. If we find a PC
|
||||||
|
that belongs to the VM (i.e., in generated code like the
|
||||||
|
interpreter or CodeCache) then we try to find an associated FP.
|
||||||
|
We repeat this until we either find a complete frame or run out of
|
||||||
|
stack to look at. </P> */
|
||||||
|
|
||||||
|
public class AARCH64CurrentFrameGuess {
|
||||||
|
private AARCH64ThreadContext context;
|
||||||
|
private JavaThread thread;
|
||||||
|
private Address spFound;
|
||||||
|
private Address fpFound;
|
||||||
|
private Address pcFound;
|
||||||
|
|
||||||
|
private static final boolean DEBUG = System.getProperty("sun.jvm.hotspot.runtime.aarch64.AARCH64Frame.DEBUG")
|
||||||
|
!= null;
|
||||||
|
|
||||||
|
public AARCH64CurrentFrameGuess(AARCH64ThreadContext context,
|
||||||
|
JavaThread thread) {
|
||||||
|
this.context = context;
|
||||||
|
this.thread = thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns false if not able to find a frame within a reasonable range. */
|
||||||
|
public boolean run(long regionInBytesToSearch) {
|
||||||
|
Address sp = context.getRegisterAsAddress(AARCH64ThreadContext.SP);
|
||||||
|
Address pc = context.getRegisterAsAddress(AARCH64ThreadContext.PC);
|
||||||
|
Address fp = context.getRegisterAsAddress(AARCH64ThreadContext.FP);
|
||||||
|
if (sp == null) {
|
||||||
|
// Bail out if no last java frame either
|
||||||
|
if (thread.getLastJavaSP() != null) {
|
||||||
|
setValues(thread.getLastJavaSP(), thread.getLastJavaFP(), null);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Address end = sp.addOffsetTo(regionInBytesToSearch);
|
||||||
|
VM vm = VM.getVM();
|
||||||
|
|
||||||
|
setValues(null, null, null); // Assume we're not going to find anything
|
||||||
|
|
||||||
|
if (vm.isJavaPCDbg(pc)) {
|
||||||
|
if (vm.isClientCompiler()) {
|
||||||
|
// If the topmost frame is a Java frame, we are (pretty much)
|
||||||
|
// guaranteed to have a viable FP. We should be more robust
|
||||||
|
// than this (we have the potential for losing entire threads'
|
||||||
|
// stack traces) but need to see how much work we really have
|
||||||
|
// to do here. Searching the stack for an (SP, FP) pair is
|
||||||
|
// hard since it's easy to misinterpret inter-frame stack
|
||||||
|
// pointers as base-of-frame pointers; we also don't know the
|
||||||
|
// sizes of C1 frames (not registered in the nmethod) so can't
|
||||||
|
// derive them from SP.
|
||||||
|
|
||||||
|
setValues(sp, fp, pc);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
if (vm.getInterpreter().contains(pc)) {
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.println("CurrentFrameGuess: choosing interpreter frame: sp = " +
|
||||||
|
sp + ", fp = " + fp + ", pc = " + pc);
|
||||||
|
}
|
||||||
|
setValues(sp, fp, pc);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For the server compiler, FP is not guaranteed to be valid
|
||||||
|
// for compiled code. In addition, an earlier attempt at a
|
||||||
|
// non-searching algorithm (see below) failed because the
|
||||||
|
// stack pointer from the thread context was pointing
|
||||||
|
// (considerably) beyond the ostensible end of the stack, into
|
||||||
|
// garbage; walking from the topmost frame back caused a crash.
|
||||||
|
//
|
||||||
|
// This algorithm takes the current PC as a given and tries to
|
||||||
|
// find the correct corresponding SP by walking up the stack
|
||||||
|
// and repeatedly performing stackwalks (very inefficient).
|
||||||
|
//
|
||||||
|
// FIXME: there is something wrong with stackwalking across
|
||||||
|
// adapter frames...this is likely to be the root cause of the
|
||||||
|
// failure with the simpler algorithm below.
|
||||||
|
|
||||||
|
for (long offset = 0;
|
||||||
|
offset < regionInBytesToSearch;
|
||||||
|
offset += vm.getAddressSize()) {
|
||||||
|
try {
|
||||||
|
Address curSP = sp.addOffsetTo(offset);
|
||||||
|
Frame frame = new AARCH64Frame(curSP, null, pc);
|
||||||
|
RegisterMap map = thread.newRegisterMap(false);
|
||||||
|
while (frame != null) {
|
||||||
|
if (frame.isEntryFrame() && frame.entryFrameIsFirst()) {
|
||||||
|
// We were able to traverse all the way to the
|
||||||
|
// bottommost Java frame.
|
||||||
|
// This sp looks good. Keep it.
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.println("CurrentFrameGuess: Choosing sp = " + curSP + ", pc = " + pc);
|
||||||
|
}
|
||||||
|
setValues(curSP, null, pc);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
frame = frame.sender(map);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.println("CurrentFrameGuess: Exception " + e + " at offset " + offset);
|
||||||
|
}
|
||||||
|
// Bad SP. Try another.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Were not able to find a plausible SP to go with this PC.
|
||||||
|
// Bail out.
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Original algorithm which does not work because SP was
|
||||||
|
// pointing beyond where it should have:
|
||||||
|
|
||||||
|
// For the server compiler, FP is not guaranteed to be valid
|
||||||
|
// for compiled code. We see whether the PC is in the
|
||||||
|
// interpreter and take care of that, otherwise we run code
|
||||||
|
// (unfortunately) duplicated from AARCH64Frame.senderForCompiledFrame.
|
||||||
|
|
||||||
|
CodeCache cc = vm.getCodeCache();
|
||||||
|
if (cc.contains(pc)) {
|
||||||
|
CodeBlob cb = cc.findBlob(pc);
|
||||||
|
|
||||||
|
// See if we can derive a frame pointer from SP and PC
|
||||||
|
// NOTE: This is the code duplicated from AARCH64Frame
|
||||||
|
Address saved_fp = null;
|
||||||
|
int llink_offset = cb.getLinkOffset();
|
||||||
|
if (llink_offset >= 0) {
|
||||||
|
// Restore base-pointer, since next frame might be an interpreter frame.
|
||||||
|
Address fp_addr = sp.addOffsetTo(VM.getVM().getAddressSize() * llink_offset);
|
||||||
|
saved_fp = fp_addr.getAddressAt(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
setValues(sp, saved_fp, pc);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If the current program counter was not known to us as a Java
|
||||||
|
// PC, we currently assume that we are in the run-time system
|
||||||
|
// and attempt to look to thread-local storage for saved SP and
|
||||||
|
// FP. Note that if these are null (because we were, in fact,
|
||||||
|
// in Java code, i.e., vtable stubs or similar, and the SA
|
||||||
|
// didn't have enough insight into the target VM to understand
|
||||||
|
// that) then we are going to lose the entire stack trace for
|
||||||
|
// the thread, which is sub-optimal. FIXME.
|
||||||
|
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.println("CurrentFrameGuess: choosing last Java frame: sp = " +
|
||||||
|
thread.getLastJavaSP() + ", fp = " + thread.getLastJavaFP());
|
||||||
|
}
|
||||||
|
if (thread.getLastJavaSP() == null) {
|
||||||
|
return false; // No known Java frames on stack
|
||||||
|
}
|
||||||
|
|
||||||
|
// The runtime has a nasty habit of not saving fp in the frame
|
||||||
|
// anchor, leaving us to grovel about in the stack to find a
|
||||||
|
// plausible address. Fortunately, this only happens in
|
||||||
|
// compiled code; there we always have a valid PC, and we always
|
||||||
|
// push LR and FP onto the stack as a pair, with FP at the lower
|
||||||
|
// address.
|
||||||
|
pc = thread.getLastJavaPC();
|
||||||
|
fp = thread.getLastJavaFP();
|
||||||
|
sp = thread.getLastJavaSP();
|
||||||
|
|
||||||
|
if (fp == null) {
|
||||||
|
CodeCache cc = vm.getCodeCache();
|
||||||
|
if (cc.contains(pc)) {
|
||||||
|
CodeBlob cb = cc.findBlob(pc);
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.println("FP is null. Found blob frame size " + cb.getFrameSize());
|
||||||
|
}
|
||||||
|
// See if we can derive a frame pointer from SP and PC
|
||||||
|
long link_offset = cb.getFrameSize() - 2 * VM.getVM().getAddressSize();
|
||||||
|
if (link_offset >= 0) {
|
||||||
|
fp = sp.addOffsetTo(link_offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setValues(sp, fp, null);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Address getSP() { return spFound; }
|
||||||
|
public Address getFP() { return fpFound; }
|
||||||
|
/** May be null if getting values from thread-local storage; take
|
||||||
|
care to call the correct AARCH64Frame constructor to recover this if
|
||||||
|
necessary */
|
||||||
|
public Address getPC() { return pcFound; }
|
||||||
|
|
||||||
|
private void setValues(Address sp, Address fp, Address pc) {
|
||||||
|
spFound = sp;
|
||||||
|
fpFound = fp;
|
||||||
|
pcFound = pc;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,555 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright (c) 2015, Red Hat Inc.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sun.jvm.hotspot.runtime.aarch64;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import sun.jvm.hotspot.code.*;
|
||||||
|
import sun.jvm.hotspot.compiler.*;
|
||||||
|
import sun.jvm.hotspot.debugger.*;
|
||||||
|
import sun.jvm.hotspot.oops.*;
|
||||||
|
import sun.jvm.hotspot.runtime.*;
|
||||||
|
import sun.jvm.hotspot.types.*;
|
||||||
|
import sun.jvm.hotspot.utilities.*;
|
||||||
|
|
||||||
|
/** Specialization of and implementation of abstract methods of the
|
||||||
|
Frame class for the aarch64 family of CPUs. */
|
||||||
|
|
||||||
|
public class AARCH64Frame extends Frame {
|
||||||
|
private static final boolean DEBUG;
|
||||||
|
static {
|
||||||
|
DEBUG = System.getProperty("sun.jvm.hotspot.runtime.aarch64.AARCH64Frame.DEBUG") != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// All frames
|
||||||
|
private static final int LINK_OFFSET = 0;
|
||||||
|
private static final int RETURN_ADDR_OFFSET = 1;
|
||||||
|
private static final int SENDER_SP_OFFSET = 2;
|
||||||
|
|
||||||
|
// Interpreter frames
|
||||||
|
private static final int INTERPRETER_FRAME_MIRROR_OFFSET = 2; // for native calls only
|
||||||
|
private static final int INTERPRETER_FRAME_SENDER_SP_OFFSET = -1;
|
||||||
|
private static final int INTERPRETER_FRAME_LAST_SP_OFFSET = INTERPRETER_FRAME_SENDER_SP_OFFSET - 1;
|
||||||
|
private static final int INTERPRETER_FRAME_METHOD_OFFSET = INTERPRETER_FRAME_LAST_SP_OFFSET - 1;
|
||||||
|
private static int INTERPRETER_FRAME_MDX_OFFSET; // Non-core builds only
|
||||||
|
private static int INTERPRETER_FRAME_CACHE_OFFSET;
|
||||||
|
private static int INTERPRETER_FRAME_LOCALS_OFFSET;
|
||||||
|
private static int INTERPRETER_FRAME_BCX_OFFSET;
|
||||||
|
private static int INTERPRETER_FRAME_INITIAL_SP_OFFSET;
|
||||||
|
private static int INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET;
|
||||||
|
private static int INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET;
|
||||||
|
|
||||||
|
// Entry frames
|
||||||
|
private static int ENTRY_FRAME_CALL_WRAPPER_OFFSET = -8;
|
||||||
|
|
||||||
|
// Native frames
|
||||||
|
private static final int NATIVE_FRAME_INITIAL_PARAM_OFFSET = 2;
|
||||||
|
|
||||||
|
private static VMReg fp = new VMReg(29);
|
||||||
|
|
||||||
|
static {
|
||||||
|
VM.registerVMInitializedObserver(new Observer() {
|
||||||
|
public void update(Observable o, Object data) {
|
||||||
|
initialize(VM.getVM().getTypeDataBase());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static synchronized void initialize(TypeDataBase db) {
|
||||||
|
INTERPRETER_FRAME_MDX_OFFSET = INTERPRETER_FRAME_METHOD_OFFSET - 1;
|
||||||
|
INTERPRETER_FRAME_CACHE_OFFSET = INTERPRETER_FRAME_MDX_OFFSET - 1;
|
||||||
|
INTERPRETER_FRAME_LOCALS_OFFSET = INTERPRETER_FRAME_CACHE_OFFSET - 1;
|
||||||
|
INTERPRETER_FRAME_BCX_OFFSET = INTERPRETER_FRAME_LOCALS_OFFSET - 1;
|
||||||
|
INTERPRETER_FRAME_INITIAL_SP_OFFSET = INTERPRETER_FRAME_BCX_OFFSET - 1;
|
||||||
|
INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET = INTERPRETER_FRAME_INITIAL_SP_OFFSET;
|
||||||
|
INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET = INTERPRETER_FRAME_INITIAL_SP_OFFSET;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// an additional field beyond sp and pc:
|
||||||
|
Address raw_fp; // frame pointer
|
||||||
|
private Address raw_unextendedSP;
|
||||||
|
|
||||||
|
private AARCH64Frame() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private void adjustForDeopt() {
|
||||||
|
if ( pc != null) {
|
||||||
|
// Look for a deopt pc and if it is deopted convert to original pc
|
||||||
|
CodeBlob cb = VM.getVM().getCodeCache().findBlob(pc);
|
||||||
|
if (cb != null && cb.isJavaMethod()) {
|
||||||
|
NMethod nm = (NMethod) cb;
|
||||||
|
if (pc.equals(nm.deoptHandlerBegin())) {
|
||||||
|
if (Assert.ASSERTS_ENABLED) {
|
||||||
|
Assert.that(this.getUnextendedSP() != null, "null SP in Java frame");
|
||||||
|
}
|
||||||
|
// adjust pc if frame is deoptimized.
|
||||||
|
pc = this.getUnextendedSP().getAddressAt(nm.origPCOffset());
|
||||||
|
deoptimized = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public AARCH64Frame(Address raw_sp, Address raw_fp, Address pc) {
|
||||||
|
this.raw_sp = raw_sp;
|
||||||
|
this.raw_unextendedSP = raw_sp;
|
||||||
|
this.raw_fp = raw_fp;
|
||||||
|
this.pc = pc;
|
||||||
|
adjustUnextendedSP();
|
||||||
|
|
||||||
|
// Frame must be fully constructed before this call
|
||||||
|
adjustForDeopt();
|
||||||
|
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.println("AARCH64Frame(sp, fp, pc): " + this);
|
||||||
|
dumpStack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public AARCH64Frame(Address raw_sp, Address raw_fp) {
|
||||||
|
this.raw_sp = raw_sp;
|
||||||
|
this.raw_unextendedSP = raw_sp;
|
||||||
|
this.raw_fp = raw_fp;
|
||||||
|
this.pc = raw_sp.getAddressAt(-1 * VM.getVM().getAddressSize());
|
||||||
|
adjustUnextendedSP();
|
||||||
|
|
||||||
|
// Frame must be fully constructed before this call
|
||||||
|
adjustForDeopt();
|
||||||
|
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.println("AARCH64Frame(sp, fp): " + this);
|
||||||
|
dumpStack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public AARCH64Frame(Address raw_sp, Address raw_unextendedSp, Address raw_fp, Address pc) {
|
||||||
|
this.raw_sp = raw_sp;
|
||||||
|
this.raw_unextendedSP = raw_unextendedSp;
|
||||||
|
this.raw_fp = raw_fp;
|
||||||
|
this.pc = pc;
|
||||||
|
adjustUnextendedSP();
|
||||||
|
|
||||||
|
// Frame must be fully constructed before this call
|
||||||
|
adjustForDeopt();
|
||||||
|
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.println("AARCH64Frame(sp, unextendedSP, fp, pc): " + this);
|
||||||
|
dumpStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object clone() {
|
||||||
|
AARCH64Frame frame = new AARCH64Frame();
|
||||||
|
frame.raw_sp = raw_sp;
|
||||||
|
frame.raw_unextendedSP = raw_unextendedSP;
|
||||||
|
frame.raw_fp = raw_fp;
|
||||||
|
frame.pc = pc;
|
||||||
|
frame.deoptimized = deoptimized;
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object arg) {
|
||||||
|
if (arg == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(arg instanceof AARCH64Frame)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
AARCH64Frame other = (AARCH64Frame) arg;
|
||||||
|
|
||||||
|
return (AddressOps.equal(getSP(), other.getSP()) &&
|
||||||
|
AddressOps.equal(getUnextendedSP(), other.getUnextendedSP()) &&
|
||||||
|
AddressOps.equal(getFP(), other.getFP()) &&
|
||||||
|
AddressOps.equal(getPC(), other.getPC()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
if (raw_sp == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return raw_sp.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return "sp: " + (getSP() == null? "null" : getSP().toString()) +
|
||||||
|
", unextendedSP: " + (getUnextendedSP() == null? "null" : getUnextendedSP().toString()) +
|
||||||
|
", fp: " + (getFP() == null? "null" : getFP().toString()) +
|
||||||
|
", pc: " + (pc == null? "null" : pc.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// accessors for the instance variables
|
||||||
|
public Address getFP() { return raw_fp; }
|
||||||
|
public Address getSP() { return raw_sp; }
|
||||||
|
public Address getID() { return raw_sp; }
|
||||||
|
|
||||||
|
// FIXME: not implemented yet
|
||||||
|
public boolean isSignalHandlerFrameDbg() { return false; }
|
||||||
|
public int getSignalNumberDbg() { return 0; }
|
||||||
|
public String getSignalNameDbg() { return null; }
|
||||||
|
|
||||||
|
public boolean isInterpretedFrameValid() {
|
||||||
|
if (Assert.ASSERTS_ENABLED) {
|
||||||
|
Assert.that(isInterpretedFrame(), "Not an interpreted frame");
|
||||||
|
}
|
||||||
|
|
||||||
|
// These are reasonable sanity checks
|
||||||
|
if (getFP() == null || getFP().andWithMask(0x3) != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getSP() == null || getSP().andWithMask(0x3) != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getFP().addOffsetTo(INTERPRETER_FRAME_INITIAL_SP_OFFSET * VM.getVM().getAddressSize()).lessThan(getSP())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// These are hacks to keep us out of trouble.
|
||||||
|
// The problem with these is that they mask other problems
|
||||||
|
if (getFP().lessThanOrEqual(getSP())) {
|
||||||
|
// this attempts to deal with unsigned comparison above
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getFP().minus(getSP()) > 4096 * VM.getVM().getAddressSize()) {
|
||||||
|
// stack frames shouldn't be large.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: not applicable in current system
|
||||||
|
// void patch_pc(Thread* thread, address pc);
|
||||||
|
|
||||||
|
public Frame sender(RegisterMap regMap, CodeBlob cb) {
|
||||||
|
AARCH64RegisterMap map = (AARCH64RegisterMap) regMap;
|
||||||
|
|
||||||
|
if (Assert.ASSERTS_ENABLED) {
|
||||||
|
Assert.that(map != null, "map must be set");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default is we done have to follow them. The sender_for_xxx will
|
||||||
|
// update it accordingly
|
||||||
|
map.setIncludeArgumentOops(false);
|
||||||
|
|
||||||
|
if (isEntryFrame()) return senderForEntryFrame(map);
|
||||||
|
if (isInterpretedFrame()) return senderForInterpreterFrame(map);
|
||||||
|
|
||||||
|
if(cb == null) {
|
||||||
|
cb = VM.getVM().getCodeCache().findBlob(getPC());
|
||||||
|
} else {
|
||||||
|
if (Assert.ASSERTS_ENABLED) {
|
||||||
|
Assert.that(cb.equals(VM.getVM().getCodeCache().findBlob(getPC())), "Must be the same");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cb != null) {
|
||||||
|
return senderForCompiledFrame(map, cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must be native-compiled frame, i.e. the marshaling code for native
|
||||||
|
// methods that exists in the core system.
|
||||||
|
return new AARCH64Frame(getSenderSP(), getLink(), getSenderPC());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Frame senderForEntryFrame(AARCH64RegisterMap map) {
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.println("senderForEntryFrame");
|
||||||
|
}
|
||||||
|
if (Assert.ASSERTS_ENABLED) {
|
||||||
|
Assert.that(map != null, "map must be set");
|
||||||
|
}
|
||||||
|
// Java frame called from C; skip all C frames and return top C
|
||||||
|
// frame of that chunk as the sender
|
||||||
|
AARCH64JavaCallWrapper jcw = (AARCH64JavaCallWrapper) getEntryFrameCallWrapper();
|
||||||
|
if (Assert.ASSERTS_ENABLED) {
|
||||||
|
Assert.that(!entryFrameIsFirst(), "next Java fp must be non zero");
|
||||||
|
Assert.that(jcw.getLastJavaSP().greaterThan(getSP()), "must be above this frame on stack");
|
||||||
|
}
|
||||||
|
AARCH64Frame fr;
|
||||||
|
if (jcw.getLastJavaPC() != null) {
|
||||||
|
fr = new AARCH64Frame(jcw.getLastJavaSP(), jcw.getLastJavaFP(), jcw.getLastJavaPC());
|
||||||
|
} else {
|
||||||
|
fr = new AARCH64Frame(jcw.getLastJavaSP(), jcw.getLastJavaFP());
|
||||||
|
}
|
||||||
|
map.clear();
|
||||||
|
if (Assert.ASSERTS_ENABLED) {
|
||||||
|
Assert.that(map.getIncludeArgumentOops(), "should be set by clear");
|
||||||
|
}
|
||||||
|
return fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// frame::adjust_unextended_sp
|
||||||
|
private void adjustUnextendedSP() {
|
||||||
|
// If we are returning to a compiled MethodHandle call site, the
|
||||||
|
// saved_fp will in fact be a saved value of the unextended SP. The
|
||||||
|
// simplest way to tell whether we are returning to such a call site
|
||||||
|
// is as follows:
|
||||||
|
|
||||||
|
CodeBlob cb = cb();
|
||||||
|
NMethod senderNm = (cb == null) ? null : cb.asNMethodOrNull();
|
||||||
|
if (senderNm != null) {
|
||||||
|
// If the sender PC is a deoptimization point, get the original
|
||||||
|
// PC. For MethodHandle call site the unextended_sp is stored in
|
||||||
|
// saved_fp.
|
||||||
|
if (senderNm.isDeoptMhEntry(getPC())) {
|
||||||
|
// DEBUG_ONLY(verifyDeoptMhOriginalPc(senderNm, getFP()));
|
||||||
|
raw_unextendedSP = getFP();
|
||||||
|
}
|
||||||
|
else if (senderNm.isDeoptEntry(getPC())) {
|
||||||
|
// DEBUG_ONLY(verifyDeoptOriginalPc(senderNm, raw_unextendedSp));
|
||||||
|
}
|
||||||
|
else if (senderNm.isMethodHandleReturn(getPC())) {
|
||||||
|
raw_unextendedSP = getFP();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Frame senderForInterpreterFrame(AARCH64RegisterMap map) {
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.println("senderForInterpreterFrame");
|
||||||
|
}
|
||||||
|
Address unextendedSP = addressOfStackSlot(INTERPRETER_FRAME_SENDER_SP_OFFSET).getAddressAt(0);
|
||||||
|
Address sp = addressOfStackSlot(SENDER_SP_OFFSET);
|
||||||
|
// We do not need to update the callee-save register mapping because above
|
||||||
|
// us is either another interpreter frame or a converter-frame, but never
|
||||||
|
// directly a compiled frame.
|
||||||
|
// 11/24/04 SFG. With the removal of adapter frames this is no longer true.
|
||||||
|
// However c2 no longer uses callee save register for java calls so there
|
||||||
|
// are no callee register to find.
|
||||||
|
|
||||||
|
if (map.getUpdateMap())
|
||||||
|
updateMapWithSavedLink(map, addressOfStackSlot(LINK_OFFSET));
|
||||||
|
|
||||||
|
return new AARCH64Frame(sp, unextendedSP, getLink(), getSenderPC());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateMapWithSavedLink(RegisterMap map, Address savedFPAddr) {
|
||||||
|
map.setLocation(fp, savedFPAddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Frame senderForCompiledFrame(AARCH64RegisterMap map, CodeBlob cb) {
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.println("senderForCompiledFrame");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// NOTE: some of this code is (unfortunately) duplicated AARCH64CurrentFrameGuess
|
||||||
|
//
|
||||||
|
|
||||||
|
if (Assert.ASSERTS_ENABLED) {
|
||||||
|
Assert.that(map != null, "map must be set");
|
||||||
|
}
|
||||||
|
|
||||||
|
// frame owned by optimizing compiler
|
||||||
|
if (Assert.ASSERTS_ENABLED) {
|
||||||
|
Assert.that(cb.getFrameSize() >= 0, "must have non-zero frame size");
|
||||||
|
}
|
||||||
|
Address senderSP = getUnextendedSP().addOffsetTo(cb.getFrameSize());
|
||||||
|
|
||||||
|
// The return_address is always the word on the stack
|
||||||
|
Address senderPC = senderSP.getAddressAt(-1 * VM.getVM().getAddressSize());
|
||||||
|
|
||||||
|
// This is the saved value of FP which may or may not really be an FP.
|
||||||
|
// It is only an FP if the sender is an interpreter frame.
|
||||||
|
Address savedFPAddr = senderSP.addOffsetTo(- SENDER_SP_OFFSET * VM.getVM().getAddressSize());
|
||||||
|
|
||||||
|
if (map.getUpdateMap()) {
|
||||||
|
// Tell GC to use argument oopmaps for some runtime stubs that need it.
|
||||||
|
// For C1, the runtime stub might not have oop maps, so set this flag
|
||||||
|
// outside of update_register_map.
|
||||||
|
map.setIncludeArgumentOops(cb.callerMustGCArguments());
|
||||||
|
|
||||||
|
if (cb.getOopMaps() != null) {
|
||||||
|
ImmutableOopMapSet.updateRegisterMap(this, cb, map, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Since the prolog does the save and restore of FP there is no oopmap
|
||||||
|
// for it so we must fill in its location as if there was an oopmap entry
|
||||||
|
// since if our caller was compiled code there could be live jvm state in it.
|
||||||
|
updateMapWithSavedLink(map, savedFPAddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new AARCH64Frame(senderSP, savedFPAddr.getAddressAt(0), senderPC);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean hasSenderPD() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long frameSize() {
|
||||||
|
return (getSenderSP().minus(getSP()) / VM.getVM().getAddressSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Address getLink() {
|
||||||
|
try {
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.println("Reading link at " + addressOfStackSlot(LINK_OFFSET)
|
||||||
|
+ " = " + addressOfStackSlot(LINK_OFFSET).getAddressAt(0));
|
||||||
|
}
|
||||||
|
return addressOfStackSlot(LINK_OFFSET).getAddressAt(0);
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (DEBUG)
|
||||||
|
System.out.println("Returning null");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: not implementable yet
|
||||||
|
//inline void frame::set_link(intptr_t* addr) { *(intptr_t **)addr_at(link_offset) = addr; }
|
||||||
|
|
||||||
|
public Address getUnextendedSP() { return raw_unextendedSP; }
|
||||||
|
|
||||||
|
// Return address:
|
||||||
|
public Address getSenderPCAddr() { return addressOfStackSlot(RETURN_ADDR_OFFSET); }
|
||||||
|
public Address getSenderPC() { return getSenderPCAddr().getAddressAt(0); }
|
||||||
|
|
||||||
|
// return address of param, zero origin index.
|
||||||
|
public Address getNativeParamAddr(int idx) {
|
||||||
|
return addressOfStackSlot(NATIVE_FRAME_INITIAL_PARAM_OFFSET + idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Address getSenderSP() { return addressOfStackSlot(SENDER_SP_OFFSET); }
|
||||||
|
|
||||||
|
public Address addressOfInterpreterFrameLocals() {
|
||||||
|
return addressOfStackSlot(INTERPRETER_FRAME_LOCALS_OFFSET);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Address addressOfInterpreterFrameBCX() {
|
||||||
|
return addressOfStackSlot(INTERPRETER_FRAME_BCX_OFFSET);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getInterpreterFrameBCI() {
|
||||||
|
// FIXME: this is not atomic with respect to GC and is unsuitable
|
||||||
|
// for use in a non-debugging, or reflective, system. Need to
|
||||||
|
// figure out how to express this.
|
||||||
|
Address bcp = addressOfInterpreterFrameBCX().getAddressAt(0);
|
||||||
|
Address methodHandle = addressOfInterpreterFrameMethod().getAddressAt(0);
|
||||||
|
Method method = (Method)Metadata.instantiateWrapperFor(methodHandle);
|
||||||
|
return bcpToBci(bcp, method);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Address addressOfInterpreterFrameMDX() {
|
||||||
|
return addressOfStackSlot(INTERPRETER_FRAME_MDX_OFFSET);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME
|
||||||
|
//inline int frame::interpreter_frame_monitor_size() {
|
||||||
|
// return BasicObjectLock::size();
|
||||||
|
//}
|
||||||
|
|
||||||
|
// expression stack
|
||||||
|
// (the max_stack arguments are used by the GC; see class FrameClosure)
|
||||||
|
|
||||||
|
public Address addressOfInterpreterFrameExpressionStack() {
|
||||||
|
Address monitorEnd = interpreterFrameMonitorEnd().address();
|
||||||
|
return monitorEnd.addOffsetTo(-1 * VM.getVM().getAddressSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getInterpreterFrameExpressionStackDirection() { return -1; }
|
||||||
|
|
||||||
|
// top of expression stack
|
||||||
|
public Address addressOfInterpreterFrameTOS() {
|
||||||
|
return getSP();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Expression stack from top down */
|
||||||
|
public Address addressOfInterpreterFrameTOSAt(int slot) {
|
||||||
|
return addressOfInterpreterFrameTOS().addOffsetTo(slot * VM.getVM().getAddressSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Address getInterpreterFrameSenderSP() {
|
||||||
|
if (Assert.ASSERTS_ENABLED) {
|
||||||
|
Assert.that(isInterpretedFrame(), "interpreted frame expected");
|
||||||
|
}
|
||||||
|
return addressOfStackSlot(INTERPRETER_FRAME_SENDER_SP_OFFSET).getAddressAt(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Monitors
|
||||||
|
public BasicObjectLock interpreterFrameMonitorBegin() {
|
||||||
|
return new BasicObjectLock(addressOfStackSlot(INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET));
|
||||||
|
}
|
||||||
|
|
||||||
|
public BasicObjectLock interpreterFrameMonitorEnd() {
|
||||||
|
Address result = addressOfStackSlot(INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET).getAddressAt(0);
|
||||||
|
if (Assert.ASSERTS_ENABLED) {
|
||||||
|
// make sure the pointer points inside the frame
|
||||||
|
Assert.that(AddressOps.gt(getFP(), result), "result must < than frame pointer");
|
||||||
|
Assert.that(AddressOps.lte(getSP(), result), "result must >= than stack pointer");
|
||||||
|
}
|
||||||
|
return new BasicObjectLock(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int interpreterFrameMonitorSize() {
|
||||||
|
return BasicObjectLock.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method
|
||||||
|
public Address addressOfInterpreterFrameMethod() {
|
||||||
|
return addressOfStackSlot(INTERPRETER_FRAME_METHOD_OFFSET);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constant pool cache
|
||||||
|
public Address addressOfInterpreterFrameCPCache() {
|
||||||
|
return addressOfStackSlot(INTERPRETER_FRAME_CACHE_OFFSET);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Entry frames
|
||||||
|
public JavaCallWrapper getEntryFrameCallWrapper() {
|
||||||
|
return new AARCH64JavaCallWrapper(addressOfStackSlot(ENTRY_FRAME_CALL_WRAPPER_OFFSET).getAddressAt(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Address addressOfSavedOopResult() {
|
||||||
|
// offset is 2 for compiler2 and 3 for compiler1
|
||||||
|
return getSP().addOffsetTo((VM.getVM().isClientCompiler() ? 2 : 3) *
|
||||||
|
VM.getVM().getAddressSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Address addressOfSavedReceiver() {
|
||||||
|
return getSP().addOffsetTo(-4 * VM.getVM().getAddressSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dumpStack() {
|
||||||
|
for (Address addr = getSP().addOffsetTo(-4 * VM.getVM().getAddressSize());
|
||||||
|
AddressOps.lt(addr, getSP());
|
||||||
|
addr = addr.addOffsetTo(VM.getVM().getAddressSize())) {
|
||||||
|
System.out.println(addr + ": " + addr.getAddressAt(0));
|
||||||
|
}
|
||||||
|
System.out.println("-----------------------");
|
||||||
|
for (Address addr = getSP();
|
||||||
|
AddressOps.lte(addr, getSP().addOffsetTo(20 * VM.getVM().getAddressSize()));
|
||||||
|
addr = addr.addOffsetTo(VM.getVM().getAddressSize())) {
|
||||||
|
System.out.println(addr + ": " + addr.getAddressAt(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright (c) 2015, Red Hat Inc.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sun.jvm.hotspot.runtime.aarch64;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import sun.jvm.hotspot.debugger.*;
|
||||||
|
import sun.jvm.hotspot.types.*;
|
||||||
|
import sun.jvm.hotspot.runtime.*;
|
||||||
|
|
||||||
|
public class AARCH64JavaCallWrapper extends JavaCallWrapper {
|
||||||
|
private static AddressField lastJavaFPField;
|
||||||
|
|
||||||
|
static {
|
||||||
|
VM.registerVMInitializedObserver(new Observer() {
|
||||||
|
public void update(Observable o, Object data) {
|
||||||
|
initialize(VM.getVM().getTypeDataBase());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static synchronized void initialize(TypeDataBase db) {
|
||||||
|
Type type = db.lookupType("JavaFrameAnchor");
|
||||||
|
|
||||||
|
lastJavaFPField = type.getAddressField("_last_Java_fp");
|
||||||
|
}
|
||||||
|
|
||||||
|
public AARCH64JavaCallWrapper(Address addr) {
|
||||||
|
super(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Address getLastJavaFP() {
|
||||||
|
return lastJavaFPField.getValue(addr.addOffsetTo(anchorField.getOffset()));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright (c) 2015, Red Hat Inc.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sun.jvm.hotspot.runtime.aarch64;
|
||||||
|
|
||||||
|
import sun.jvm.hotspot.debugger.*;
|
||||||
|
import sun.jvm.hotspot.runtime.*;
|
||||||
|
|
||||||
|
public class AARCH64RegisterMap extends RegisterMap {
|
||||||
|
|
||||||
|
/** This is the only public constructor */
|
||||||
|
public AARCH64RegisterMap(JavaThread thread, boolean updateMap) {
|
||||||
|
super(thread, updateMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected AARCH64RegisterMap(RegisterMap map) {
|
||||||
|
super(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object clone() {
|
||||||
|
AARCH64RegisterMap retval = new AARCH64RegisterMap(this);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
// no PD state to clear or copy:
|
||||||
|
protected void clearPD() {}
|
||||||
|
protected void initializePD() {}
|
||||||
|
protected void initializeFromPD(RegisterMap map) {}
|
||||||
|
protected Address getLocationPD(VMReg reg) { return null; }
|
||||||
|
}
|
@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright (c) 2015, Red Hat Inc.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sun.jvm.hotspot.runtime.linux_aarch64;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
import sun.jvm.hotspot.debugger.*;
|
||||||
|
import sun.jvm.hotspot.debugger.aarch64.*;
|
||||||
|
import sun.jvm.hotspot.runtime.*;
|
||||||
|
import sun.jvm.hotspot.runtime.aarch64.*;
|
||||||
|
import sun.jvm.hotspot.types.*;
|
||||||
|
import sun.jvm.hotspot.utilities.*;
|
||||||
|
|
||||||
|
public class LinuxAARCH64JavaThreadPDAccess implements JavaThreadPDAccess {
|
||||||
|
private static AddressField lastJavaFPField;
|
||||||
|
private static AddressField osThreadField;
|
||||||
|
|
||||||
|
// Field from OSThread
|
||||||
|
private static CIntegerField osThreadThreadIDField;
|
||||||
|
|
||||||
|
// This is currently unneeded but is being kept in case we change
|
||||||
|
// the currentFrameGuess algorithm
|
||||||
|
private static final long GUESS_SCAN_RANGE = 128 * 1024;
|
||||||
|
|
||||||
|
static {
|
||||||
|
VM.registerVMInitializedObserver(new Observer() {
|
||||||
|
public void update(Observable o, Object data) {
|
||||||
|
initialize(VM.getVM().getTypeDataBase());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static synchronized void initialize(TypeDataBase db) {
|
||||||
|
Type type = db.lookupType("JavaThread");
|
||||||
|
osThreadField = type.getAddressField("_osthread");
|
||||||
|
|
||||||
|
Type anchorType = db.lookupType("JavaFrameAnchor");
|
||||||
|
lastJavaFPField = anchorType.getAddressField("_last_Java_fp");
|
||||||
|
|
||||||
|
Type osThreadType = db.lookupType("OSThread");
|
||||||
|
osThreadThreadIDField = osThreadType.getCIntegerField("_thread_id");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Address getLastJavaFP(Address addr) {
|
||||||
|
return lastJavaFPField.getValue(addr.addOffsetTo(sun.jvm.hotspot.runtime.JavaThread.getAnchorField().getOffset()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Address getLastJavaPC(Address addr) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Address getBaseOfStackPointer(Address addr) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Frame getLastFramePD(JavaThread thread, Address addr) {
|
||||||
|
Address fp = thread.getLastJavaFP();
|
||||||
|
if (fp == null) {
|
||||||
|
return null; // no information
|
||||||
|
}
|
||||||
|
return new AARCH64Frame(thread.getLastJavaSP(), fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RegisterMap newRegisterMap(JavaThread thread, boolean updateMap) {
|
||||||
|
return new AARCH64RegisterMap(thread, updateMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Frame getCurrentFrameGuess(JavaThread thread, Address addr) {
|
||||||
|
ThreadProxy t = getThreadProxy(addr);
|
||||||
|
AARCH64ThreadContext context = (AARCH64ThreadContext) t.getContext();
|
||||||
|
AARCH64CurrentFrameGuess guesser = new AARCH64CurrentFrameGuess(context, thread);
|
||||||
|
if (!guesser.run(GUESS_SCAN_RANGE)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (guesser.getPC() == null) {
|
||||||
|
return new AARCH64Frame(guesser.getSP(), guesser.getFP());
|
||||||
|
} else {
|
||||||
|
return new AARCH64Frame(guesser.getSP(), guesser.getFP(), guesser.getPC());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printThreadIDOn(Address addr, PrintStream tty) {
|
||||||
|
tty.print(getThreadProxy(addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printInfoOn(Address threadAddr, PrintStream tty) {
|
||||||
|
tty.print("Thread id: ");
|
||||||
|
printThreadIDOn(threadAddr, tty);
|
||||||
|
// tty.println("\nPostJavaState: " + getPostJavaState(threadAddr));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Address getLastSP(Address addr) {
|
||||||
|
ThreadProxy t = getThreadProxy(addr);
|
||||||
|
AARCH64ThreadContext context = (AARCH64ThreadContext) t.getContext();
|
||||||
|
return context.getRegisterAsAddress(AARCH64ThreadContext.SP);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ThreadProxy getThreadProxy(Address addr) {
|
||||||
|
// Addr is the address of the JavaThread.
|
||||||
|
// Fetch the OSThread (for now and for simplicity, not making a
|
||||||
|
// separate "OSThread" class in this package)
|
||||||
|
Address osThreadAddr = osThreadField.getValue(addr);
|
||||||
|
// Get the address of the _thread_id from the OSThread
|
||||||
|
Address threadIdAddr = osThreadAddr.addOffsetTo(osThreadThreadIDField.getOffset());
|
||||||
|
|
||||||
|
JVMDebugger debugger = VM.getVM().getDebugger();
|
||||||
|
return debugger.getThreadForIdentifierAddress(threadIdAddr);
|
||||||
|
}
|
||||||
|
}
|
@ -44,6 +44,7 @@ $(AGENT_SRC_DIR)/sun/jvm/hotspot/code/*.java \
|
|||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/compiler/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/compiler/*.java \
|
||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/*.java \
|
||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/amd64/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/amd64/*.java \
|
||||||
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/aarch64/*.java \
|
||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/bsd/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/bsd/*.java \
|
||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/bsd/amd64/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/bsd/amd64/*.java \
|
||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/bsd/x86/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/bsd/x86/*.java \
|
||||||
@ -55,6 +56,7 @@ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/*.java \
|
|||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/amd64/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/amd64/*.java \
|
||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/ia64/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/ia64/*.java \
|
||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/ppc64/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/ppc64/*.java \
|
||||||
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/aarch64/*.java \
|
||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/x86/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/x86/*.java \
|
||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/sparc/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/sparc/*.java \
|
||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/posix/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/posix/*.java \
|
||||||
@ -63,6 +65,7 @@ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/ppc64/*.java \
|
|||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/*.java \
|
||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/amd64/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/amd64/*.java \
|
||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/ppc64/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/ppc64/*.java \
|
||||||
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/aarch64/*.java \
|
||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/sparc/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/sparc/*.java \
|
||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/x86/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/x86/*.java \
|
||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/*.java \
|
||||||
@ -70,6 +73,7 @@ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/amd64/*.java \
|
|||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/ppc64/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/ppc64/*.java \
|
||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/sparc/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/sparc/*.java \
|
||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/x86/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/x86/*.java \
|
||||||
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/aarch64/*.java \
|
||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/sparc/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/sparc/*.java \
|
||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/win32/coff/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/win32/coff/*.java \
|
||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/windbg/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/windbg/*.java \
|
||||||
@ -92,11 +96,13 @@ $(AGENT_SRC_DIR)/sun/jvm/hotspot/opto/*.java \
|
|||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/prims/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/prims/*.java \
|
||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/*.java \
|
||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/amd64/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/amd64/*.java \
|
||||||
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/aarch64/*.java \
|
||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/bsd/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/bsd/*.java \
|
||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/bsd_amd64/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/bsd_amd64/*.java \
|
||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/bsd_x86/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/bsd_x86/*.java \
|
||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux/*.java \
|
||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux_amd64/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux_amd64/*.java \
|
||||||
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux_aarch64/*.java \
|
||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux_x86/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux_x86/*.java \
|
||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux_sparc/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux_sparc/*.java \
|
||||||
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux_ppc64/*.java \
|
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux_ppc64/*.java \
|
||||||
|
Loading…
Reference in New Issue
Block a user