VirtualBox

source: vbox/trunk/src/VBox/Debugger/DBGPlugInSolaris.cpp@ 8800

Last change on this file since 8800 was 8800, checked in by vboxsync, 17 years ago

Started digging into the solaris guest kernel. Added DBGFR3MemRead.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 11.3 KB
Line 
1/* $Id: DBGPlugInSolaris.cpp 8800 2008-05-14 03:03:54Z vboxsync $ */
2/** @file
3 * DBGPlugInSolaris - Debugger and Guest OS Digger Plugin For Solaris.
4 */
5
6/*
7 * Copyright (C) 2008 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.215389.xyz. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22
23/*******************************************************************************
24* Header Files *
25*******************************************************************************/
26#include "DBGPlugIns.h"
27#include <VBox/dbgf.h>
28#include <iprt/string.h>
29
30
31/*******************************************************************************
32* Structures and Typedefs *
33*******************************************************************************/
34
35/** @name InternalSolaris structures
36 * @{ */
37
38typedef struct SOL32_modctl
39{
40 uint32_t mod_next; /**< 0 */
41 uint32_t mod_prev; /**< 4 */
42 int32_t mod_id; /**< 8 */
43 uint32_t mod_mp; /**< c Pointer to the kernel runtime loader bits. */
44 uint32_t mod_inprogress_thread; /**< 10 */
45 uint32_t mod_modinfo; /**< 14 */
46 uint32_t mod_linkage; /**< 18 */
47 uint32_t mod_filename; /**< 1c */
48 uint32_t mod_modname; /**< 20 */
49 int8_t mod_busy; /**< 24 */
50 int8_t mod_want; /**< 25 */
51 int8_t mod_prim; /**< 26 this is 1 for 'unix' and a few others. */
52 int8_t mod_unused_padding; /**< 27 */
53 int32_t mod_ref; /**< 28 */
54 int8_t mod_loaded; /**< 2c */
55 int8_t mod_installed; /**< 2d */
56 int8_t mod_loadflags; /**< 2e */
57 int8_t mod_delay_unload; /**< 2f */
58 uint32_t mod_requisites; /**< 30 */
59 uint32_t mod___unused; /**< 34 */
60 int32_t mod_loadcnt; /**< 38 */
61 int32_t mod_nenabled; /**< 3c */
62 uint32_t mod_text; /**< 40 */
63 uint32_t mod_text_size; /**< 44 */
64 int32_t mod_gencount; /**< 48 */
65 uint32_t mod_requisite_loading; /**< 4c */
66} SOL32_modctl_t;
67AssertCompileSize(SOL32_modctl_t, 0x50);
68
69/** @} */
70
71
72/**
73 * Solaris guest OS digger instance data.
74 */
75typedef struct DBGDIGGERSOLARIS
76{
77 /** Whether the information is valid or not.
78 * (For fending off illegal interface method calls.) */
79 bool fValid;
80
81 /** Address of the 'unix' text segment.
82 * This is set during probing. */
83 DBGFADDRESS AddrUnixText;
84 /** Address of the 'unix' text segment.
85 * This is set during probing. */
86 DBGFADDRESS AddrUnixData;
87 /** Address of the 'unix' modctl_t (aka modules). */
88 DBGFADDRESS AddrUnixModCtl;
89
90} DBGDIGGERSOLARIS;
91/** Pointer to the solaris guest OS digger instance data. */
92typedef DBGDIGGERSOLARIS *PDBGDIGGERSOLARIS;
93
94
95/*******************************************************************************
96* Defined Constants And Macros *
97*******************************************************************************/
98/** Validates a 32-bit solaris kernel address */
99#define SOL32_VALID_ADDRESS(Addr) ((Addr) > UINT32_C(0x80000000) && (Addr) < UINT32_C(0xfffff000))
100
101
102
103/*******************************************************************************
104* Internal Functions *
105*******************************************************************************/
106static DECLCALLBACK(int) dbgDiggerSolarisInit(PVM pVM, void *pvData);
107
108
109
110/**
111 * @copydoc DBGFOSREG::pfnQueryInterface
112 */
113static DECLCALLBACK(void *) dbgDiggerSolarisQueryInterface(PVM pVM, void *pvData, DBGFOSINTERFACE enmIf)
114{
115 return NULL;
116}
117
118
119/**
120 * @copydoc DBGFOSREG::pfnQueryVersion
121 */
122static DECLCALLBACK(int) dbgDiggerSolarisQueryVersion(PVM pVM, void *pvData, char *pszVersion, size_t cchVersion)
123{
124 PDBGDIGGERSOLARIS pThis = (PDBGDIGGERSOLARIS)pvData;
125 Assert(pThis->fValid);
126
127 return VERR_NOT_IMPLEMENTED;
128}
129
130
131/**
132 * @copydoc DBGFOSREG::pfnTerm
133 */
134static DECLCALLBACK(void) dbgDiggerSolarisTerm(PVM pVM, void *pvData)
135{
136 PDBGDIGGERSOLARIS pThis = (PDBGDIGGERSOLARIS)pvData;
137 Assert(pThis->fValid);
138
139 pThis->fValid = false;
140}
141
142
143/**
144 * @copydoc DBGFOSREG::pfnRefresh
145 */
146static DECLCALLBACK(int) dbgDiggerSolarisRefresh(PVM pVM, void *pvData)
147{
148 PDBGDIGGERSOLARIS pThis = (PDBGDIGGERSOLARIS)pvData;
149 Assert(pThis->fValid);
150
151 /*
152 * For now we'll flush and reload everything.
153 */
154 dbgDiggerSolarisTerm(pVM, pvData);
155 return dbgDiggerSolarisInit(pVM, pvData);
156}
157
158
159/**
160 * @copydoc DBGFOSREG::pfnInit
161 */
162static DECLCALLBACK(int) dbgDiggerSolarisInit(PVM pVM, void *pvData)
163{
164 PDBGDIGGERSOLARIS pThis = (PDBGDIGGERSOLARIS)pvData;
165 Assert(!pThis->fValid);
166 int rc;
167
168 /*
169 * Find the 'unix' modctl_t structure (aka modules).
170 * We know it resides in the unix data segment.
171 */
172 DBGFR3AddrFromFlat(pVM, &pThis->AddrUnixModCtl, 0);
173
174 DBGFADDRESS CurAddr = pThis->AddrUnixData;
175 DBGFADDRESS MaxAddr;
176 DBGFR3AddrFromFlat(pVM, &MaxAddr, CurAddr.FlatPtr + 0x01000000);
177 const uint8_t *pbExpr = (const uint8_t *)&pThis->AddrUnixText.FlatPtr;
178 const uint32_t cbExpr = sizeof(uint32_t);//pThis->AddrUnixText.FlatPtr < _4G ? sizeof(uint32_t) : sizeof(uint64_t)
179 while ( CurAddr.FlatPtr < MaxAddr.FlatPtr
180 && CurAddr.FlatPtr >= pThis->AddrUnixData.FlatPtr)
181 {
182 DBGFADDRESS HitAddr;
183 rc = DBGFR3MemScan(pVM, &CurAddr, MaxAddr.FlatPtr - CurAddr.FlatPtr, pbExpr, cbExpr, &HitAddr);
184 if (RT_FAILURE(rc))
185 break;
186
187 /*
188 * Read out the modctl_t structure.
189 */
190 DBGFADDRESS ModCtlAddr;
191 DBGFR3AddrFromFlat(pVM, &ModCtlAddr, HitAddr.FlatPtr - RT_OFFSETOF(SOL32_modctl_t, mod_text));
192 SOL32_modctl_t ModCtl;
193 rc = DBGFR3MemRead(pVM, &ModCtlAddr, &ModCtl, sizeof(ModCtl));
194 if (RT_SUCCESS(rc))
195 {
196 if ( SOL32_VALID_ADDRESS(ModCtl.mod_next)
197 && SOL32_VALID_ADDRESS(ModCtl.mod_prev)
198 && ModCtl.mod_id == 0
199 && SOL32_VALID_ADDRESS(ModCtl.mod_mp)
200 && SOL32_VALID_ADDRESS(ModCtl.mod_filename)
201 && SOL32_VALID_ADDRESS(ModCtl.mod_modname)
202 && ModCtl.mod_prim == 1
203 && ModCtl.mod_loaded == 1
204 && ModCtl.mod_installed == 1
205 && ModCtl.mod_requisites == 0
206 && ModCtl.mod_loadcnt == 1
207 /*&& ModCtl.mod_text == pThis->AddrUnixText.FlatPtr*/
208 && ModCtl.mod_text_size < UINT32_C(0xfec00000) - UINT32_C(0xfe800000) )
209 {
210 char szUnix[5];
211 DBGFADDRESS NameAddr;
212 DBGFR3AddrFromFlat(pVM, &NameAddr, ModCtl.mod_modname);
213 rc = DBGFR3MemRead(pVM, &NameAddr, &szUnix, sizeof(szUnix));
214 if (RT_SUCCESS(rc))
215 {
216 if (!strcmp(szUnix, "unix"))
217 {
218 pThis->AddrUnixModCtl = ModCtlAddr;
219 break;
220 }
221 Log(("sol32 mod_name=%.*s\n", sizeof(szUnix), szUnix));
222 }
223 }
224 }
225
226 /* next */
227 DBGFR3AddrFromFlat(pVM, &CurAddr, HitAddr.FlatPtr + cbExpr);
228 }
229
230 /*
231 * Walk the module chain and add the modules and their symbols.
232 */
233 if (pThis->AddrUnixModCtl.FlatPtr)
234 {
235 int iMod = 0;
236 CurAddr = pThis->AddrUnixModCtl;
237 do
238 {
239 /* read it */
240 SOL32_modctl_t ModCtl;
241 rc = DBGFR3MemRead(pVM, &CurAddr, &ModCtl, sizeof(ModCtl));
242 if (RT_FAILURE(rc))
243 {
244 LogRel(("sol32: bad modctl_t chain: %RGv - %Rrc\n", iMod, CurAddr.FlatPtr, rc));
245 break;
246 }
247
248 /* process it. */
249
250
251 /* next */
252 if (!SOL32_VALID_ADDRESS(ModCtl.mod_next))
253 {
254 LogRel(("sol32: bad modctl_t chain at %RGv: %RGv\n", iMod, CurAddr.FlatPtr, (RTGCUINTPTR)ModCtl.mod_next));
255 break;
256 }
257 if (++iMod >= 1024)
258 {
259 LogRel(("sol32: too many modules (%d)\n", iMod));
260 break;
261 }
262 DBGFR3AddrFromFlat(pVM, &CurAddr, ModCtl.mod_next);
263 } while (CurAddr.FlatPtr != pThis->AddrUnixModCtl.FlatPtr);
264 }
265
266 pThis->fValid = true;
267 return VINF_SUCCESS;
268}
269
270
271/**
272 * @copydoc DBGFOSREG::pfnProbe
273 */
274static DECLCALLBACK(bool) dbgDiggerSolarisProbe(PVM pVM, void *pvData)
275{
276 PDBGDIGGERSOLARIS pThis = (PDBGDIGGERSOLARIS)pvData;
277
278 /*
279 * Look for "SunOS Release" in the text segment.
280 */
281 DBGFADDRESS Addr;
282 DBGFR3AddrFromFlat(pVM, &Addr, 0xfe800000);
283 RTGCUINTPTR cbRange = 0xfec00000 - 0xfe800000;
284
285 DBGFADDRESS HitAddr;
286 static const uint8_t s_abSunRelease[] = "SunOS Release ";
287 int rc = DBGFR3MemScan(pVM, &Addr, cbRange, s_abSunRelease, sizeof(s_abSunRelease) - 1, &HitAddr);
288 if (RT_FAILURE(rc))
289 return false;
290
291 /*
292 * Look for the copy right string too, just to be sure.
293 */
294 static const uint8_t s_abSMI[] = "Sun Microsystems, Inc.";
295 rc = DBGFR3MemScan(pVM, &Addr, cbRange, s_abSMI, sizeof(s_abSMI) - 1, &HitAddr);
296 if (RT_FAILURE(rc))
297 return false;
298
299 /*
300 * Remember the unix text and data addresses (32-bit vs 64-bit).
301 */
302 pThis->AddrUnixText = Addr;
303// if (pThis->AddrUnixText.FlatPtr == 0xfe800000)
304 {
305 DBGFR3AddrFromFlat(pVM, &Addr, 0xfec00000);
306 pThis->AddrUnixData = Addr;
307 }
308// else
309// {
310// DBGFR3AddrFromFlat(pVM, &Addr, UINT64_C(0xwhateveritis));
311// pThis->AddrUnixData = Addr;
312// }
313
314 return true;
315}
316
317
318/**
319 * @copydoc DBGFOSREG::pfnDestruct
320 */
321static DECLCALLBACK(void) dbgDiggerSolarisDestruct(PVM pVM, void *pvData)
322{
323
324}
325
326
327/**
328 * @copydoc DBGFOSREG::pfnConstruct
329 */
330static DECLCALLBACK(int) dbgDiggerSolarisConstruct(PVM pVM, void *pvData)
331{
332 return VINF_SUCCESS;
333}
334
335
336const DBGFOSREG g_DBGDiggerSolaris =
337{
338 /* .u32Magic = */ DBGFOSREG_MAGIC,
339 /* .fFlags = */ 0,
340 /* .cbData = */ sizeof(DBGDIGGERSOLARIS),
341 /* .szName = */ "Solaris",
342 /* .pfnConstruct = */ dbgDiggerSolarisConstruct,
343 /* .pfnDestruct = */ dbgDiggerSolarisDestruct,
344 /* .pfnProbe = */ dbgDiggerSolarisProbe,
345 /* .pfnInit = */ dbgDiggerSolarisInit,
346 /* .pfnRefresh = */ dbgDiggerSolarisRefresh,
347 /* .pfnTerm = */ dbgDiggerSolarisTerm,
348 /* .pfnQueryVersion = */ dbgDiggerSolarisQueryVersion,
349 /* .pfnQueryInterface = */ dbgDiggerSolarisQueryInterface,
350 /* .u32EndMagic = */ DBGFOSREG_MAGIC
351};
352
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette