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.bsd.x86;
26 
27 import sun.jvm.hotspot.debugger.*;
28 import sun.jvm.hotspot.debugger.bsd.*;
29 import sun.jvm.hotspot.debugger.cdbg.*;
30 import sun.jvm.hotspot.debugger.cdbg.basic.*;
31 import sun.jvm.hotspot.debugger.x86.*;
32 
33 final public class BsdX86CFrame extends BasicCFrame {
34    // package/class internals only
BsdX86CFrame(BsdDebugger dbg, Address ebp, Address pc)35    public BsdX86CFrame(BsdDebugger dbg, Address ebp, Address pc) {
36       super(dbg.getCDebugger());
37       this.ebp = ebp;
38       this.pc = pc;
39       this.dbg = dbg;
40    }
41 
42    // override base class impl to avoid ELF parsing
closestSymbolToPC()43    public ClosestSymbol closestSymbolToPC() {
44       // try native lookup in debugger.
45       return dbg.lookup(dbg.getAddressValue(pc()));
46    }
47 
pc()48    public Address pc() {
49       return pc;
50    }
51 
localVariableBase()52    public Address localVariableBase() {
53       return ebp;
54    }
55 
sender(ThreadProxy thread)56    public CFrame sender(ThreadProxy thread) {
57       X86ThreadContext context = (X86ThreadContext) thread.getContext();
58       /*
59        * Native code fills in the stack pointer register value using index
60        * X86ThreadContext.SP.
61        * See file BsdDebuggerLocal.c macro REG_INDEX(reg).
62        *
63        * Be sure to use SP, or UESP which is aliased to SP in Java code,
64        * for the frame pointer validity check.
65        */
66       Address esp = context.getRegisterAsAddress(X86ThreadContext.SP);
67 
68       if ( (ebp == null) || ebp.lessThan(esp) ) {
69         return null;
70       }
71 
72       // Check alignment of ebp
73       if ( dbg.getAddressValue(ebp) % ADDRESS_SIZE != 0) {
74         return null;
75       }
76 
77       Address nextEBP = ebp.getAddressAt( 0 * ADDRESS_SIZE);
78       if (nextEBP == null || nextEBP.lessThanOrEqual(ebp)) {
79         return null;
80       }
81       Address nextPC  = ebp.getAddressAt( 1 * ADDRESS_SIZE);
82       if (nextPC == null) {
83         return null;
84       }
85       return new BsdX86CFrame(dbg, nextEBP, nextPC);
86    }
87 
88    private static final int ADDRESS_SIZE = 4;
89    private Address pc;
90    private Address ebp;
91    private BsdDebugger dbg;
92 }
93