1 /* 2 * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. 3 * Copyright (c) 2015, Red Hat Inc. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 * 24 */ 25 26 package sun.jvm.hotspot.debugger.linux; 27 28 import java.io.*; 29 import java.util.*; 30 31 import sun.jvm.hotspot.debugger.*; 32 import sun.jvm.hotspot.debugger.cdbg.*; 33 import sun.jvm.hotspot.debugger.x86.*; 34 import sun.jvm.hotspot.debugger.amd64.*; 35 import sun.jvm.hotspot.debugger.aarch64.*; 36 import sun.jvm.hotspot.debugger.riscv64.*; 37 import sun.jvm.hotspot.debugger.ppc64.*; 38 import sun.jvm.hotspot.debugger.linux.x86.*; 39 import sun.jvm.hotspot.debugger.linux.amd64.*; 40 import sun.jvm.hotspot.debugger.linux.ppc64.*; 41 import sun.jvm.hotspot.debugger.linux.aarch64.*; 42 import sun.jvm.hotspot.debugger.linux.riscv64.*; 43 import sun.jvm.hotspot.utilities.*; 44 45 class LinuxCDebugger implements CDebugger { 46 private LinuxDebugger dbg; 47 48 LinuxCDebugger(LinuxDebugger dbg) { 49 this.dbg = dbg; 50 } 51 52 public List<ThreadProxy> getThreadList() throws DebuggerException { 53 return dbg.getThreadList(); 54 } 55 56 public List<LoadObject> getLoadObjectList() throws DebuggerException { 57 return dbg.getLoadObjectList(); 58 } 59 60 public LoadObject loadObjectContainingPC(Address pc) throws DebuggerException { 61 if (pc == null) { 62 return null; 63 } 64 65 /* Typically we have about ten loaded objects here. So no reason to do 66 sort/binary search here. Linear search gives us acceptable performance.*/ 67 68 List<LoadObject> objs = getLoadObjectList(); 69 70 for (int i = 0; i < objs.size(); i++) { 71 LoadObject ob = (LoadObject) objs.get(i); 72 Address base = ob.getBase(); 73 long size = ob.getSize(); 74 if (pc.greaterThanOrEqual(base) && pc.lessThan(base.addOffsetTo(size))) { 75 return ob; 76 } 77 } 78 79 return null; 80 } 81 82 public CFrame topFrameForThread(ThreadProxy thread) throws DebuggerException { 83 String cpu = dbg.getCPU(); 84 if (cpu.equals("x86")) { 85 X86ThreadContext context = (X86ThreadContext) thread.getContext(); 86 Address ebp = context.getRegisterAsAddress(X86ThreadContext.EBP); 87 if (ebp == null) return null; 88 Address pc = context.getRegisterAsAddress(X86ThreadContext.EIP); 89 if (pc == null) return null; 90 return new LinuxX86CFrame(dbg, ebp, pc); 91 } else if (cpu.equals("amd64")) { 92 AMD64ThreadContext context = (AMD64ThreadContext) thread.getContext(); 93 Address pc = context.getRegisterAsAddress(AMD64ThreadContext.RIP); 94 if (pc == null) return null; 95 return LinuxAMD64CFrame.getTopFrame(dbg, pc, context); 96 } else if (cpu.equals("ppc64")) { 97 PPC64ThreadContext context = (PPC64ThreadContext) thread.getContext(); 98 Address sp = context.getRegisterAsAddress(PPC64ThreadContext.SP); 99 if (sp == null) return null; 100 Address pc = context.getRegisterAsAddress(PPC64ThreadContext.PC); 101 if (pc == null) return null; 102 return new LinuxPPC64CFrame(dbg, sp, pc, LinuxDebuggerLocal.getAddressSize()); 103 } else if (cpu.equals("aarch64")) { 104 AARCH64ThreadContext context = (AARCH64ThreadContext) thread.getContext(); 105 Address fp = context.getRegisterAsAddress(AARCH64ThreadContext.FP); 106 if (fp == null) return null; 107 Address pc = context.getRegisterAsAddress(AARCH64ThreadContext.PC); 108 if (pc == null) return null; 109 return new LinuxAARCH64CFrame(dbg, fp, pc); 110 } else if (cpu.equals("riscv64")) { 111 RISCV64ThreadContext context = (RISCV64ThreadContext) thread.getContext(); 112 Address fp = context.getRegisterAsAddress(RISCV64ThreadContext.FP); 113 if (fp == null) return null; 114 Address pc = context.getRegisterAsAddress(RISCV64ThreadContext.PC); 115 if (pc == null) return null; 116 return new LinuxRISCV64CFrame(dbg, fp, pc); 117 } else { 118 // Runtime exception thrown by LinuxThreadContextFactory if unknown cpu 119 ThreadContext context = (ThreadContext) thread.getContext(); 120 return context.getTopFrame(dbg); 121 } 122 } 123 124 public String getNameOfFile(String fileName) { 125 return new File(fileName).getName(); 126 } 127 128 public ProcessControl getProcessControl() throws DebuggerException { 129 // FIXME: after stabs parser 130 return null; 131 } 132 133 public boolean canDemangle() { 134 return true; 135 } 136 137 public String demangle(String sym) { 138 return dbg.demangle(sym); 139 } 140 }