< prev index next >

src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/amd64/LinuxAMD64CFrame.java

Print this page


   1 /*
   2  * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 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    public LinuxAMD64CFrame(LinuxDebugger dbg, Address rbp, Address rip) {
  35       super(dbg.getCDebugger());
  36       this.rbp = rbp;
  37       this.rip = rip;
  38       this.dbg = dbg;

  39    }
  40 
  41    // override base class impl to avoid ELF parsing
  42    public ClosestSymbol closestSymbolToPC() {
  43       // try native lookup in debugger.
  44       return dbg.lookup(dbg.getAddressValue(pc()));
  45    }
  46 
  47    public Address pc() {
  48       return rip;
  49    }
  50 
  51    public Address localVariableBase() {
  52       return rbp;
  53    }
  54 
  55    public CFrame sender(ThreadProxy thread) {
  56       AMD64ThreadContext context = (AMD64ThreadContext) thread.getContext();
  57       Address rsp = context.getRegisterAsAddress(AMD64ThreadContext.RSP);






















  58 
  59       if ( (rbp == null) || rbp.lessThan(rsp) ) {

  60         return null;
  61       }
  62 
  63       // Check alignment of rbp
  64       if ( dbg.getAddressValue(rbp) % ADDRESS_SIZE != 0) {











  65         return null;
  66       }






  67 
  68       Address nextRBP = rbp.getAddressAt( 0 * ADDRESS_SIZE);
  69       if (nextRBP == null || nextRBP.lessThanOrEqual(rbp)) {




  70         return null;
  71       }
  72       Address nextPC  = rbp.getAddressAt( 1 * ADDRESS_SIZE);

























  73       if (nextPC == null) {
  74         return null;
  75       }
  76       return new LinuxAMD64CFrame(dbg, nextRBP, nextPC);




















  77    }
  78 
  79    // package/class internals only
  80    private static final int ADDRESS_SIZE = 8;
  81    private Address rip;
  82    private Address rbp;
  83    private LinuxDebugger dbg;

  84 }
   1 /*
   2  * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 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    public LinuxAMD64CFrame(LinuxDebugger dbg, Address cfa, Address rip, DwarfParser dwarf) {
  35       super(dbg.getCDebugger());
  36       this.cfa = cfa;
  37       this.rip = rip;
  38       this.dbg = dbg;
  39       this.dwarf = dwarf;
  40    }
  41 
  42    // override base class impl to avoid ELF parsing
  43    public ClosestSymbol closestSymbolToPC() {
  44       // try native lookup in debugger.
  45       return dbg.lookup(dbg.getAddressValue(pc()));
  46    }
  47 
  48    public Address pc() {
  49       return rip;
  50    }
  51 
  52    public Address localVariableBase() {
  53       return cfa;
  54    }
  55 
  56    private Address getNextPC(boolean useDwarf) {
  57      try {
  58        long ofs = useDwarf ? dwarf.getReturnAddressOffsetFromCFA()
  59                            : ADDRESS_SIZE;
  60        return cfa.getAddressAt(ofs);
  61      } catch (UnmappedAddressException | UnalignedAddressException e) {
  62        return null;
  63      }
  64    }
  65 
  66    private boolean isValidFrame(Address nextCFA, ThreadContext context) {
  67      return (nextCFA != null) &&
  68              !nextCFA.lessThan(context.getRegisterAsAddress(AMD64ThreadContext.RSP));
  69    }
  70 
  71    private Address getNextCFA(DwarfParser nextDwarf, ThreadContext context) {
  72      Address nextCFA;
  73 
  74      if (dwarf == null) {
  75        nextCFA = cfa.getAddressAt(0);
  76        if (nextDwarf != null) {
  77          nextCFA = nextCFA.addOffsetTo(- nextDwarf.getBasePointerOffsetFromCFA());
  78        }
  79        return isValidFrame(nextCFA, context) ? nextCFA : null;
  80      }
  81 
  82      nextCFA = cfa.getAddressAt(dwarf.getBasePointerOffsetFromCFA());
  83      if (nextCFA == null) {
  84        return null;
  85      }
  86 
  87      if (nextDwarf == null) {
  88        return isValidFrame(nextCFA, context) ? nextCFA : null;
  89      } else {
  90        int nextCFAReg = nextDwarf.getCFARegister();
  91        if (!dwarf.isBPOffsetAvailable() &&
  92            (nextCFAReg == AMD64ThreadContext.RBP) &&
  93            (nextCFAReg != dwarf.getCFARegister())) {
  94          nextCFA = context.getRegisterAsAddress(AMD64ThreadContext.RBP);
  95          if (nextCFA == null) {
  96            return null;
  97          }
  98          nextCFA = nextCFA.getAddressAt(0);
  99          if (nextCFA == null) {
 100            return null;
 101          }
 102        }
 103      }
 104 
 105      nextCFA = nextCFA.addOffsetTo(- nextDwarf.getBasePointerOffsetFromCFA());
 106      return isValidFrame(nextCFA, context) ? nextCFA : null;
 107    }
 108 
 109    private CFrame javaSender(ThreadContext context) {
 110      Address nextCFA;
 111      Address nextPC;
 112 
 113      nextPC = getNextPC(false);
 114      if (nextPC == null) {
 115        return null;
 116      }
 117 
 118      DwarfParser nextDwarf = null;
 119      long libptr = dbg.findLibPtrByAddress(nextPC);
 120      if (libptr != 0L) { // Native frame
 121        try {
 122          nextDwarf = new DwarfParser(libptr);
 123        } catch (DebuggerException e) {
 124          nextCFA = getNextCFA(null, context);
 125          return (nextCFA == null) ? null : new LinuxAMD64CFrame(dbg, nextCFA, nextPC, null);
 126        }
 127        nextDwarf.processDwarf(nextPC);
 128      }
 129 
 130      nextCFA = getNextCFA(nextDwarf, context);
 131      return (nextCFA == null) ? null
 132                               : new LinuxAMD64CFrame(dbg, nextCFA, nextPC, nextDwarf);
 133    }
 134 
 135    public CFrame sender(ThreadProxy thread) {
 136      ThreadContext context = thread.getContext();
 137 
 138      if (dwarf == null) { // Java frame
 139        return javaSender(context);
 140      }
 141 
 142      Address nextPC = getNextPC(true);
 143      if (nextPC == null) {
 144        return null;
 145      }
 146 
 147      Address nextCFA;
 148      DwarfParser nextDwarf = dwarf;
 149      if (!dwarf.isIn(nextPC)) {
 150        long libptr = dbg.findLibPtrByAddress(nextPC);
 151        if (libptr == 0L) {
 152          // Next frame might be Java frame
 153          nextCFA = getNextCFA(null, context);
 154          return (nextCFA == null) ? null : new LinuxAMD64CFrame(dbg, nextCFA, nextPC, null);
 155        }
 156        try {
 157          nextDwarf = new DwarfParser(libptr);
 158        } catch (DebuggerException e) {
 159          nextCFA = getNextCFA(null, context);
 160          return (nextCFA == null) ? null : new LinuxAMD64CFrame(dbg, nextCFA, nextPC, null);
 161        }
 162      }
 163 
 164      nextDwarf.processDwarf(nextPC);
 165      nextCFA = getNextCFA(nextDwarf, context);
 166      return (nextCFA == null) ? null : new LinuxAMD64CFrame(dbg, nextCFA, nextPC, nextDwarf);
 167    }
 168 
 169    // package/class internals only
 170    private static final int ADDRESS_SIZE = 8;
 171    private Address rip;
 172    private Address cfa;
 173    private LinuxDebugger dbg;
 174    private DwarfParser dwarf;
 175 }
< prev index next >