21 * questions. 22 * 23 */ 24 25 package sun.jvm.hotspot.debugger.linux.amd64; 26 27 import sun.jvm.hotspot.debugger.*; 28 import sun.jvm.hotspot.debugger.amd64.*; 29 import sun.jvm.hotspot.debugger.linux.*; 30 import sun.jvm.hotspot.debugger.cdbg.*; 31 import sun.jvm.hotspot.debugger.cdbg.basic.*; 32 33 final public class LinuxAMD64CFrame extends BasicCFrame { 34 35 public static LinuxAMD64CFrame getTopFrame(LinuxDebugger dbg, Address rip, ThreadContext context) { 36 Address libptr = dbg.findLibPtrByAddress(rip); 37 Address cfa = context.getRegisterAsAddress(AMD64ThreadContext.RBP); 38 DwarfParser dwarf = null; 39 40 if (libptr != null) { // Native frame 41 try { 42 dwarf = new DwarfParser(libptr); 43 dwarf.processDwarf(rip); 44 cfa = ((dwarf.getCFARegister() == AMD64ThreadContext.RBP) && 45 !dwarf.isBPOffsetAvailable()) 46 ? context.getRegisterAsAddress(AMD64ThreadContext.RBP) 47 : context.getRegisterAsAddress(dwarf.getCFARegister()) 48 .addOffsetTo(dwarf.getCFAOffset()); 49 } catch (DebuggerException e) { 50 // Bail out to Java frame case 51 } 52 } 53 54 return (cfa == null) ? null 55 : new LinuxAMD64CFrame(dbg, cfa, rip, dwarf); 56 } 57 58 private LinuxAMD64CFrame(LinuxDebugger dbg, Address cfa, Address rip, DwarfParser dwarf) { 59 super(dbg.getCDebugger()); 60 this.cfa = cfa; 61 this.rip = rip; 62 this.dbg = dbg; 63 this.dwarf = dwarf; 64 } 65 66 // override base class impl to avoid ELF parsing 67 public ClosestSymbol closestSymbolToPC() { 68 // try native lookup in debugger. 69 return dbg.lookup(dbg.getAddressValue(pc())); 70 } 71 72 public Address pc() { 73 return rip; 74 } 75 76 public Address localVariableBase() { 77 return cfa; 78 } 79 80 private Address getNextPC(boolean useDwarf) { 81 try { 82 long offs = useDwarf ? dwarf.getReturnAddressOffsetFromCFA() 83 : ADDRESS_SIZE; 106 if (!dwarf.isBPOffsetAvailable() && // Use RBP as CFA 107 (nextCFAReg == AMD64ThreadContext.RBP) && 108 (nextCFAReg != dwarf.getCFARegister())) { 109 nextCFA = context.getRegisterAsAddress(AMD64ThreadContext.RBP); 110 if (nextCFA == null) { 111 return null; 112 } 113 nextCFA = nextCFA.getAddressAt(0); 114 } else { 115 nextCFA = cfa.getAddressAt(dwarf.getBasePointerOffsetFromCFA()); 116 } 117 } 118 if (nextCFA != null) { 119 nextCFA = nextCFA.addOffsetTo(-nextDwarf.getBasePointerOffsetFromCFA()); 120 } 121 } 122 123 return isValidFrame(nextCFA, context) ? nextCFA : null; 124 } 125 126 private DwarfParser getNextDwarf(Address nextPC) { 127 DwarfParser nextDwarf = null; 128 129 if ((dwarf != null) && dwarf.isIn(nextPC)) { 130 nextDwarf = dwarf; 131 } else { 132 Address libptr = dbg.findLibPtrByAddress(nextPC); 133 if (libptr != null) { 134 try { 135 nextDwarf = new DwarfParser(libptr); 136 } catch (DebuggerException e) { 137 // Bail out to Java frame 138 } 139 } 140 } 141 142 if (nextDwarf != null) { 143 nextDwarf.processDwarf(nextPC); 144 } 145 146 return nextDwarf; 147 } 148 149 @Override 150 public CFrame sender(ThreadProxy thread) { 151 ThreadContext context = thread.getContext(); 152 153 Address nextPC = getNextPC(dwarf != null); 154 if (nextPC == null) { 155 return null; 156 } 157 158 DwarfParser nextDwarf = getNextDwarf(nextPC); 159 Address nextCFA = getNextCFA(nextDwarf, context); 160 return isValidFrame(nextCFA, context) ? new LinuxAMD64CFrame(dbg, nextCFA, nextPC, nextDwarf) 161 : null; 162 } 163 164 // package/class internals only 165 private static final int ADDRESS_SIZE = 8; 166 private Address rip; 167 private Address cfa; 168 private LinuxDebugger dbg; 169 private DwarfParser dwarf; 170 } | 21 * questions. 22 * 23 */ 24 25 package sun.jvm.hotspot.debugger.linux.amd64; 26 27 import sun.jvm.hotspot.debugger.*; 28 import sun.jvm.hotspot.debugger.amd64.*; 29 import sun.jvm.hotspot.debugger.linux.*; 30 import sun.jvm.hotspot.debugger.cdbg.*; 31 import sun.jvm.hotspot.debugger.cdbg.basic.*; 32 33 final public class LinuxAMD64CFrame extends BasicCFrame { 34 35 public static LinuxAMD64CFrame getTopFrame(LinuxDebugger dbg, Address rip, ThreadContext context) { 36 Address libptr = dbg.findLibPtrByAddress(rip); 37 Address cfa = context.getRegisterAsAddress(AMD64ThreadContext.RBP); 38 DwarfParser dwarf = null; 39 40 if (libptr != null) { // Native frame 41 dwarf = new DwarfParser(libptr); 42 try { 43 dwarf.processDwarf(rip); 44 } catch (DebuggerException e) { 45 // DWARF processing should succeed when the frame is native 46 // but it might fail if Common Information Entry (CIE) has language 47 // personality routine and/or Language Specific Data Area (LSDA). 48 return new LinuxAMD64CFrame(dbg, cfa, rip, dwarf, true); 49 } 50 cfa = ((dwarf.getCFARegister() == AMD64ThreadContext.RBP) && 51 !dwarf.isBPOffsetAvailable()) 52 ? context.getRegisterAsAddress(AMD64ThreadContext.RBP) 53 : context.getRegisterAsAddress(dwarf.getCFARegister()) 54 .addOffsetTo(dwarf.getCFAOffset()); 55 } 56 57 return (cfa == null) ? null 58 : new LinuxAMD64CFrame(dbg, cfa, rip, dwarf); 59 } 60 61 private LinuxAMD64CFrame(LinuxDebugger dbg, Address cfa, Address rip, DwarfParser dwarf) { 62 this(dbg, cfa, rip, dwarf, false); 63 } 64 65 private LinuxAMD64CFrame(LinuxDebugger dbg, Address cfa, Address rip, DwarfParser dwarf, boolean lastFrame) { 66 super(dbg.getCDebugger()); 67 this.cfa = cfa; 68 this.rip = rip; 69 this.dbg = dbg; 70 this.dwarf = dwarf; 71 this.lastFrame = lastFrame; 72 } 73 74 // override base class impl to avoid ELF parsing 75 public ClosestSymbol closestSymbolToPC() { 76 // try native lookup in debugger. 77 return dbg.lookup(dbg.getAddressValue(pc())); 78 } 79 80 public Address pc() { 81 return rip; 82 } 83 84 public Address localVariableBase() { 85 return cfa; 86 } 87 88 private Address getNextPC(boolean useDwarf) { 89 try { 90 long offs = useDwarf ? dwarf.getReturnAddressOffsetFromCFA() 91 : ADDRESS_SIZE; 114 if (!dwarf.isBPOffsetAvailable() && // Use RBP as CFA 115 (nextCFAReg == AMD64ThreadContext.RBP) && 116 (nextCFAReg != dwarf.getCFARegister())) { 117 nextCFA = context.getRegisterAsAddress(AMD64ThreadContext.RBP); 118 if (nextCFA == null) { 119 return null; 120 } 121 nextCFA = nextCFA.getAddressAt(0); 122 } else { 123 nextCFA = cfa.getAddressAt(dwarf.getBasePointerOffsetFromCFA()); 124 } 125 } 126 if (nextCFA != null) { 127 nextCFA = nextCFA.addOffsetTo(-nextDwarf.getBasePointerOffsetFromCFA()); 128 } 129 } 130 131 return isValidFrame(nextCFA, context) ? nextCFA : null; 132 } 133 134 @Override 135 public CFrame sender(ThreadProxy thread) { 136 if (lastFrame) { 137 return null; 138 } 139 140 ThreadContext context = thread.getContext(); 141 142 Address nextPC = getNextPC(dwarf != null); 143 if (nextPC == null) { 144 return null; 145 } 146 147 DwarfParser nextDwarf = null; 148 149 if ((dwarf != null) && dwarf.isIn(nextPC)) { 150 nextDwarf = dwarf; 151 } else { 152 Address libptr = dbg.findLibPtrByAddress(nextPC); 153 if (libptr != null) { 154 try { 155 nextDwarf = new DwarfParser(libptr); 156 } catch (DebuggerException e) { 157 // Bail out to Java frame 158 } 159 } 160 } 161 162 if (nextDwarf != null) { 163 try { 164 nextDwarf.processDwarf(nextPC); 165 } catch (DebuggerException e) { 166 // DWARF processing should succeed when the frame is native 167 // but it might fail if Common Information Entry (CIE) has language 168 // personality routine and/or Language Specific Data Area (LSDA). 169 return new LinuxAMD64CFrame(dbg, null, nextPC, nextDwarf, true); 170 } 171 } 172 173 Address nextCFA = getNextCFA(nextDwarf, context); 174 return isValidFrame(nextCFA, context) ? new LinuxAMD64CFrame(dbg, nextCFA, nextPC, nextDwarf) 175 : null; 176 } 177 178 // package/class internals only 179 private static final int ADDRESS_SIZE = 8; 180 private Address rip; 181 private Address cfa; 182 private LinuxDebugger dbg; 183 private DwarfParser dwarf; 184 private boolean lastFrame; 185 } |