annotate agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/DLL.java @ 2072:d6cd0d55d0b5

6987812: 2/3 SAJDI: "gHotSpotVMTypes was not initialized properly in the remote process" Summary: Change ExportDirectoryTableImpl to return the 'Export RVA' field without modification. Read 'Base Of Data' field in optional header when PE32 format COFF file is read. Refine search for dbgeng.dll and dbghelp.dll. Other cleanups. Reviewed-by: swamyv, poonam
author dcubed
date Thu, 23 Dec 2010 07:58:35 -0800
parents c18cbe5936b8
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
2 * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 package sun.jvm.hotspot.debugger.windbg;
a61af66fc99e Initial load
duke
parents:
diff changeset
26
a61af66fc99e Initial load
duke
parents:
diff changeset
27 import sun.jvm.hotspot.debugger.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
28 import sun.jvm.hotspot.debugger.win32.coff.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
29 import sun.jvm.hotspot.debugger.cdbg.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
30 import sun.jvm.hotspot.utilities.Assert;
a61af66fc99e Initial load
duke
parents:
diff changeset
31 import sun.jvm.hotspot.utilities.memo.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
32
a61af66fc99e Initial load
duke
parents:
diff changeset
33 /** Provides a simple wrapper around the COFF library which handles
a61af66fc99e Initial load
duke
parents:
diff changeset
34 relocation. A DLL can represent either a DLL or an EXE file. */
a61af66fc99e Initial load
duke
parents:
diff changeset
35
a61af66fc99e Initial load
duke
parents:
diff changeset
36 public class DLL implements LoadObject {
a61af66fc99e Initial load
duke
parents:
diff changeset
37
a61af66fc99e Initial load
duke
parents:
diff changeset
38 public DLL(WindbgDebugger dbg, String filename, long size, Address relocation) throws COFFException {
a61af66fc99e Initial load
duke
parents:
diff changeset
39 this.dbg = dbg;
a61af66fc99e Initial load
duke
parents:
diff changeset
40 fullPathName = filename;
a61af66fc99e Initial load
duke
parents:
diff changeset
41 this.size = size;
a61af66fc99e Initial load
duke
parents:
diff changeset
42 file = new MemoizedObject() {
a61af66fc99e Initial load
duke
parents:
diff changeset
43 public Object computeValue() {
a61af66fc99e Initial load
duke
parents:
diff changeset
44 return COFFFileParser.getParser().parse(fullPathName);
a61af66fc99e Initial load
duke
parents:
diff changeset
45 }
a61af66fc99e Initial load
duke
parents:
diff changeset
46 };
a61af66fc99e Initial load
duke
parents:
diff changeset
47 addr = relocation;
a61af66fc99e Initial load
duke
parents:
diff changeset
48 }
a61af66fc99e Initial load
duke
parents:
diff changeset
49
a61af66fc99e Initial load
duke
parents:
diff changeset
50 /** This constructor was originally used to fetch the DLL's name out
a61af66fc99e Initial load
duke
parents:
diff changeset
51 of the target process to match it up with the known DLL names,
a61af66fc99e Initial load
duke
parents:
diff changeset
52 before the fetching of the DLL names and bases was folded into
a61af66fc99e Initial load
duke
parents:
diff changeset
53 one command. It is no longer used. If it is used, getName() will
a61af66fc99e Initial load
duke
parents:
diff changeset
54 return null and getSize() will return 0. */
a61af66fc99e Initial load
duke
parents:
diff changeset
55 public DLL(Address base) throws COFFException {
a61af66fc99e Initial load
duke
parents:
diff changeset
56 this.addr = base;
a61af66fc99e Initial load
duke
parents:
diff changeset
57 file = new MemoizedObject() {
a61af66fc99e Initial load
duke
parents:
diff changeset
58 public Object computeValue() {
a61af66fc99e Initial load
duke
parents:
diff changeset
59 return COFFFileParser.getParser().parse(new AddressDataSource(addr));
a61af66fc99e Initial load
duke
parents:
diff changeset
60 }
a61af66fc99e Initial load
duke
parents:
diff changeset
61 };
a61af66fc99e Initial load
duke
parents:
diff changeset
62 }
a61af66fc99e Initial load
duke
parents:
diff changeset
63
a61af66fc99e Initial load
duke
parents:
diff changeset
64 /** Indicates whether this is really a DLL or actually a .EXE
a61af66fc99e Initial load
duke
parents:
diff changeset
65 file. */
a61af66fc99e Initial load
duke
parents:
diff changeset
66 public boolean isDLL() {
a61af66fc99e Initial load
duke
parents:
diff changeset
67 return getFile().getHeader().hasCharacteristic(Characteristics.IMAGE_FILE_DLL);
a61af66fc99e Initial load
duke
parents:
diff changeset
68 }
a61af66fc99e Initial load
duke
parents:
diff changeset
69
a61af66fc99e Initial load
duke
parents:
diff changeset
70 /** Look up a symbol; returns absolute address or null if symbol was
a61af66fc99e Initial load
duke
parents:
diff changeset
71 not found. */
a61af66fc99e Initial load
duke
parents:
diff changeset
72 public Address lookupSymbol(String symbol) throws COFFException {
a61af66fc99e Initial load
duke
parents:
diff changeset
73 if (!isDLL()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
74 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
75 }
a61af66fc99e Initial load
duke
parents:
diff changeset
76 ExportDirectoryTable exports = getExportDirectoryTable();
a61af66fc99e Initial load
duke
parents:
diff changeset
77 return lookupSymbol(symbol, exports,
a61af66fc99e Initial load
duke
parents:
diff changeset
78 0, exports.getNumberOfNamePointers() - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
79 }
a61af66fc99e Initial load
duke
parents:
diff changeset
80
a61af66fc99e Initial load
duke
parents:
diff changeset
81 public Address getBase() {
a61af66fc99e Initial load
duke
parents:
diff changeset
82 return addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
83 }
a61af66fc99e Initial load
duke
parents:
diff changeset
84
a61af66fc99e Initial load
duke
parents:
diff changeset
85 /** Returns the full path name of this DLL/EXE, or null if this DLL
a61af66fc99e Initial load
duke
parents:
diff changeset
86 object was created by parsing the target process's address
a61af66fc99e Initial load
duke
parents:
diff changeset
87 space. */
a61af66fc99e Initial load
duke
parents:
diff changeset
88 public String getName() {
a61af66fc99e Initial load
duke
parents:
diff changeset
89 return fullPathName;
a61af66fc99e Initial load
duke
parents:
diff changeset
90 }
a61af66fc99e Initial load
duke
parents:
diff changeset
91
a61af66fc99e Initial load
duke
parents:
diff changeset
92 public long getSize() {
a61af66fc99e Initial load
duke
parents:
diff changeset
93 return size;
a61af66fc99e Initial load
duke
parents:
diff changeset
94 }
a61af66fc99e Initial load
duke
parents:
diff changeset
95
a61af66fc99e Initial load
duke
parents:
diff changeset
96 public CDebugInfoDataBase getDebugInfoDataBase() throws DebuggerException {
a61af66fc99e Initial load
duke
parents:
diff changeset
97 if (db != null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
98 return db;
a61af66fc99e Initial load
duke
parents:
diff changeset
99 }
a61af66fc99e Initial load
duke
parents:
diff changeset
100
a61af66fc99e Initial load
duke
parents:
diff changeset
101 // Try to parse
a61af66fc99e Initial load
duke
parents:
diff changeset
102 if (dbg == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
103 return null; // Need WindbgDebugger
a61af66fc99e Initial load
duke
parents:
diff changeset
104 }
a61af66fc99e Initial load
duke
parents:
diff changeset
105
a61af66fc99e Initial load
duke
parents:
diff changeset
106 if (Assert.ASSERTS_ENABLED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
107 Assert.that(fullPathName != null, "Need full path name to build debug info database");
a61af66fc99e Initial load
duke
parents:
diff changeset
108 }
a61af66fc99e Initial load
duke
parents:
diff changeset
109
a61af66fc99e Initial load
duke
parents:
diff changeset
110 db = new WindbgCDebugInfoBuilder(dbg).buildDataBase(fullPathName, addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
111 return db;
a61af66fc99e Initial load
duke
parents:
diff changeset
112 }
a61af66fc99e Initial load
duke
parents:
diff changeset
113
a61af66fc99e Initial load
duke
parents:
diff changeset
114 public BlockSym debugInfoForPC(Address pc) throws DebuggerException {
a61af66fc99e Initial load
duke
parents:
diff changeset
115 CDebugInfoDataBase db = getDebugInfoDataBase();
a61af66fc99e Initial load
duke
parents:
diff changeset
116 if (db == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
117 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
118 }
a61af66fc99e Initial load
duke
parents:
diff changeset
119 return db.debugInfoForPC(pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
120 }
a61af66fc99e Initial load
duke
parents:
diff changeset
121
a61af66fc99e Initial load
duke
parents:
diff changeset
122 public ClosestSymbol closestSymbolToPC(Address pcAsAddr) throws DebuggerException {
a61af66fc99e Initial load
duke
parents:
diff changeset
123 ExportDirectoryTable exports = getExportDirectoryTable();
a61af66fc99e Initial load
duke
parents:
diff changeset
124 if (exports == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
125 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
126 }
a61af66fc99e Initial load
duke
parents:
diff changeset
127 String name = null;
a61af66fc99e Initial load
duke
parents:
diff changeset
128 long pc = dbg.getAddressValue(pcAsAddr);
a61af66fc99e Initial load
duke
parents:
diff changeset
129 long diff = Long.MAX_VALUE;
a61af66fc99e Initial load
duke
parents:
diff changeset
130 long base = dbg.getAddressValue(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
131 for (int i = 0; i < exports.getNumberOfNamePointers(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
132 if (!exports.isExportAddressForwarder(exports.getExportOrdinal(i))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
133 long tmp = base + (exports.getExportAddress(exports.getExportOrdinal(i)) & 0xFFFFFFFF);
a61af66fc99e Initial load
duke
parents:
diff changeset
134 if ((tmp <= pc) && ((pc - tmp) < diff)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
135 diff = pc - tmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
136 name = exports.getExportName(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
137 }
a61af66fc99e Initial load
duke
parents:
diff changeset
138 }
a61af66fc99e Initial load
duke
parents:
diff changeset
139 }
a61af66fc99e Initial load
duke
parents:
diff changeset
140 if (name == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
141 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
142 }
a61af66fc99e Initial load
duke
parents:
diff changeset
143 return new ClosestSymbol(name, diff);
a61af66fc99e Initial load
duke
parents:
diff changeset
144 }
a61af66fc99e Initial load
duke
parents:
diff changeset
145
a61af66fc99e Initial load
duke
parents:
diff changeset
146 public LineNumberInfo lineNumberForPC(Address pc) throws DebuggerException {
a61af66fc99e Initial load
duke
parents:
diff changeset
147 CDebugInfoDataBase db = getDebugInfoDataBase();
a61af66fc99e Initial load
duke
parents:
diff changeset
148 if (db == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
149 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
150 }
a61af66fc99e Initial load
duke
parents:
diff changeset
151 return db.lineNumberForPC(pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
152 }
a61af66fc99e Initial load
duke
parents:
diff changeset
153
a61af66fc99e Initial load
duke
parents:
diff changeset
154 public void close() {
a61af66fc99e Initial load
duke
parents:
diff changeset
155 getFile().close();
a61af66fc99e Initial load
duke
parents:
diff changeset
156 file = null;
a61af66fc99e Initial load
duke
parents:
diff changeset
157 }
a61af66fc99e Initial load
duke
parents:
diff changeset
158
a61af66fc99e Initial load
duke
parents:
diff changeset
159 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
160 // Internals only below this point
a61af66fc99e Initial load
duke
parents:
diff changeset
161 //
a61af66fc99e Initial load
duke
parents:
diff changeset
162
a61af66fc99e Initial load
duke
parents:
diff changeset
163 private COFFFile getFile() {
a61af66fc99e Initial load
duke
parents:
diff changeset
164 return (COFFFile) file.getValue();
a61af66fc99e Initial load
duke
parents:
diff changeset
165 }
a61af66fc99e Initial load
duke
parents:
diff changeset
166
a61af66fc99e Initial load
duke
parents:
diff changeset
167 private Address lookupSymbol(String symbol, ExportDirectoryTable exports,
a61af66fc99e Initial load
duke
parents:
diff changeset
168 int loIdx, int hiIdx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
169 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
170 int curIdx = ((loIdx + hiIdx) >> 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
171 String cur = exports.getExportName(curIdx);
a61af66fc99e Initial load
duke
parents:
diff changeset
172 if (symbol.equals(cur)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
173 return addr.addOffsetTo(
a61af66fc99e Initial load
duke
parents:
diff changeset
174 ((long) exports.getExportAddress(exports.getExportOrdinal(curIdx))) & 0xFFFFFFFFL
a61af66fc99e Initial load
duke
parents:
diff changeset
175 );
a61af66fc99e Initial load
duke
parents:
diff changeset
176 }
a61af66fc99e Initial load
duke
parents:
diff changeset
177 if (symbol.compareTo(cur) < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
178 if (hiIdx == curIdx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
179 hiIdx = curIdx - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
180 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
181 hiIdx = curIdx;
a61af66fc99e Initial load
duke
parents:
diff changeset
182 }
a61af66fc99e Initial load
duke
parents:
diff changeset
183 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
184 if (loIdx == curIdx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
185 loIdx = curIdx + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
186 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
187 loIdx = curIdx;
a61af66fc99e Initial load
duke
parents:
diff changeset
188 }
a61af66fc99e Initial load
duke
parents:
diff changeset
189 }
a61af66fc99e Initial load
duke
parents:
diff changeset
190 } while (loIdx <= hiIdx);
a61af66fc99e Initial load
duke
parents:
diff changeset
191
a61af66fc99e Initial load
duke
parents:
diff changeset
192 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
193 }
a61af66fc99e Initial load
duke
parents:
diff changeset
194
a61af66fc99e Initial load
duke
parents:
diff changeset
195 private ExportDirectoryTable getExportDirectoryTable() {
a61af66fc99e Initial load
duke
parents:
diff changeset
196 return
a61af66fc99e Initial load
duke
parents:
diff changeset
197 getFile().getHeader().getOptionalHeader().getDataDirectories().getExportDirectoryTable();
a61af66fc99e Initial load
duke
parents:
diff changeset
198 }
a61af66fc99e Initial load
duke
parents:
diff changeset
199
a61af66fc99e Initial load
duke
parents:
diff changeset
200 private WindbgDebugger dbg;
a61af66fc99e Initial load
duke
parents:
diff changeset
201 private String fullPathName;
a61af66fc99e Initial load
duke
parents:
diff changeset
202 private long size;
a61af66fc99e Initial load
duke
parents:
diff changeset
203 // MemoizedObject contains a COFFFile
a61af66fc99e Initial load
duke
parents:
diff changeset
204 private MemoizedObject file;
a61af66fc99e Initial load
duke
parents:
diff changeset
205 // Base address of module in target process
a61af66fc99e Initial load
duke
parents:
diff changeset
206 private Address addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
207 // Debug info database for this DLL
a61af66fc99e Initial load
duke
parents:
diff changeset
208 private CDebugInfoDataBase db;
a61af66fc99e Initial load
duke
parents:
diff changeset
209 }