VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/dbg/dbgmoddeferred.cpp@ 51701

Last change on this file since 51701 was 49044, checked in by vboxsync, 11 years ago

Darwin guest OS digger hacking in progress. Adding symbol cache util to iprt and started on the Mach-O code that'll make use of it (RTDbgModCreateFromMachOImage++). Updates kStuff from 53 to 55 for UUID query and 64-bit kext loading.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.5 KB
Line 
1/* $Id: dbgmoddeferred.cpp 49044 2013-10-11 01:06:28Z vboxsync $ */
2/** @file
3 * IPRT - Debug Module Deferred Loading Stub.
4 */
5
6/*
7 * Copyright (C) 2013 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. 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 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*******************************************************************************
29* Header Files *
30*******************************************************************************/
31#include <iprt/dbg.h>
32#include "internal/iprt.h"
33
34#include <iprt/asm.h>
35#include <iprt/assert.h>
36#include <iprt/err.h>
37#include <iprt/mem.h>
38#include <iprt/param.h>
39#include <iprt/path.h>
40#include <iprt/string.h>
41#include "internal/dbgmod.h"
42#include "internal/magics.h"
43
44
45
46/**
47 * Releases the instance data.
48 *
49 * @param pThis The instance data.
50 */
51static void rtDbgModDeferredReleaseInstanceData(PRTDBGMODDEFERRED pThis)
52{
53 AssertPtr(pThis);
54 uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs); Assert(cRefs < 8);
55 if (!cRefs)
56 {
57 RTDbgCfgRelease(pThis->hDbgCfg);
58 pThis->hDbgCfg = NIL_RTDBGCFG;
59 RTMemFree(pThis);
60 }
61}
62
63
64/**
65 * Does the deferred loading of the real data (image and/or debug info).
66 *
67 * @returns VINF_SUCCESS or VERR_DBG_DEFERRED_LOAD_FAILED.
68 * @param pMod The generic module instance data.
69 * @param fForcedRetry Whether it's a forced retry by one of the
70 * pfnTryOpen methods.
71 */
72static int rtDbgModDeferredDoIt(PRTDBGMODINT pMod, bool fForcedRetry)
73{
74 RTCritSectEnter(&pMod->CritSect);
75
76 int rc;
77 if (!pMod->fDeferredFailed || fForcedRetry)
78 {
79 bool const fDbgVt = pMod->pDbgVt == &g_rtDbgModVtDbgDeferred;
80 bool const fImgVt = pMod->pImgVt == &g_rtDbgModVtImgDeferred;
81 AssertReturnStmt(fDbgVt || fImgVt, RTCritSectLeave(&pMod->CritSect), VERR_INTERNAL_ERROR_5);
82
83 PRTDBGMODDEFERRED pThis = (PRTDBGMODDEFERRED)(fDbgVt ? pMod->pvDbgPriv : pMod->pvImgPriv);
84
85 /* Reset the method tables and private data pointes so the deferred loading
86 procedure can figure out what to do and won't get confused. */
87 if (fDbgVt)
88 {
89 pMod->pvDbgPriv = NULL;
90 pMod->pDbgVt = NULL;
91 }
92
93 if (fImgVt)
94 {
95 pMod->pvImgPriv = NULL;
96 pMod->pImgVt = NULL;
97 }
98
99 /* Do the deferred loading. */
100 rc = pThis->pfnDeferred(pMod, pThis);
101 if (RT_SUCCESS(rc))
102 {
103 Assert(!fDbgVt || pMod->pDbgVt != NULL);
104 Assert(!fImgVt || pMod->pImgVt != NULL);
105
106 pMod->fDeferred = false;
107 pMod->fDeferredFailed = false;
108
109 rtDbgModDeferredReleaseInstanceData(pThis);
110 if (fImgVt && fDbgVt)
111 rtDbgModDeferredReleaseInstanceData(pThis);
112 }
113 else
114 {
115 /* Failed, bail out and restore the deferred setup. */
116 pMod->fDeferredFailed = true;
117
118 if (fDbgVt)
119 {
120 Assert(!pMod->pDbgVt);
121 pMod->pDbgVt = &g_rtDbgModVtDbgDeferred;
122 pMod->pvDbgPriv = pThis;
123 }
124
125 if (fImgVt)
126 {
127 Assert(!pMod->pImgVt);
128 pMod->pImgVt = &g_rtDbgModVtImgDeferred;
129 pMod->pvImgPriv = pThis;
130 }
131 }
132 }
133 else
134 rc = VERR_DBG_DEFERRED_LOAD_FAILED;
135
136 RTCritSectLeave(&pMod->CritSect);
137 return rc;
138}
139
140
141
142
143/*
144 *
145 * D e b u g I n f o M e t h o d s
146 * D e b u g I n f o M e t h o d s
147 * D e b u g I n f o M e t h o d s
148 *
149 */
150
151
152/** @interface_method_impl{RTDBGMODVTDBG,pfnLineByAddr} */
153static DECLCALLBACK(int) rtDbgModDeferredDbg_LineByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off,
154 PRTINTPTR poffDisp, PRTDBGLINE pLineInfo)
155{
156 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
157 if (RT_SUCCESS(rc))
158 rc = pMod->pDbgVt->pfnLineByAddr(pMod, iSeg, off, poffDisp, pLineInfo);
159 return rc;
160}
161
162
163/** @interface_method_impl{RTDBGMODVTDBG,pfnLineByOrdinal} */
164static DECLCALLBACK(int) rtDbgModDeferredDbg_LineByOrdinal(PRTDBGMODINT pMod, uint32_t iOrdinal, PRTDBGLINE pLineInfo)
165{
166 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
167 if (RT_SUCCESS(rc))
168 rc = pMod->pDbgVt->pfnLineByOrdinal(pMod, iOrdinal, pLineInfo);
169 return rc;
170}
171
172
173/** @interface_method_impl{RTDBGMODVTDBG,pfnLineCount} */
174static DECLCALLBACK(uint32_t) rtDbgModDeferredDbg_LineCount(PRTDBGMODINT pMod)
175{
176 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
177 if (RT_SUCCESS(rc))
178 return pMod->pDbgVt->pfnLineCount(pMod);
179 return 0;
180}
181
182
183/** @interface_method_impl{RTDBGMODVTDBG,pfnLineAdd} */
184static DECLCALLBACK(int) rtDbgModDeferredDbg_LineAdd(PRTDBGMODINT pMod, const char *pszFile, size_t cchFile, uint32_t uLineNo,
185 uint32_t iSeg, RTUINTPTR off, uint32_t *piOrdinal)
186{
187 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
188 if (RT_SUCCESS(rc))
189 rc = pMod->pDbgVt->pfnLineAdd(pMod, pszFile, cchFile, uLineNo, iSeg, off, piOrdinal);
190 return rc;
191}
192
193
194/**
195 * Fill in symbol info for the fake start symbol.
196 *
197 * @returns VINF_SUCCESS
198 * @param pThis The deferred load data.
199 * @param pSymInfo The output structure.
200 */
201static int rtDbgModDeferredDbgSymInfo_Start(PRTDBGMODDEFERRED pThis, PRTDBGSYMBOL pSymInfo)
202{
203 pSymInfo->Value = 0;
204 pSymInfo->cb = pThis->cbImage;
205 pSymInfo->offSeg = 0;
206 pSymInfo->iSeg = 0;
207 pSymInfo->fFlags = 0;
208 pSymInfo->iOrdinal = 0;
209 strcpy(pSymInfo->szName, "DeferredStart");
210 return VINF_SUCCESS;
211}
212
213
214/**
215 * Fill in symbol info for the fake last symbol.
216 *
217 * @returns VINF_SUCCESS
218 * @param pThis The deferred load data.
219 * @param pSymInfo The output structure.
220 */
221static int rtDbgModDeferredDbgSymInfo_Last(PRTDBGMODDEFERRED pThis, PRTDBGSYMBOL pSymInfo)
222{
223 pSymInfo->Value = pThis->cbImage - 1;
224 pSymInfo->cb = 0;
225 pSymInfo->offSeg = pThis->cbImage - 1;
226 pSymInfo->iSeg = 0;
227 pSymInfo->fFlags = 0;
228 pSymInfo->iOrdinal = 1;
229 strcpy(pSymInfo->szName, "DeferredLast");
230 return VINF_SUCCESS;
231}
232
233
234/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByAddr} */
235static DECLCALLBACK(int) rtDbgModDeferredDbg_SymbolByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off, uint32_t fFlags,
236 PRTINTPTR poffDisp, PRTDBGSYMBOL pSymInfo)
237{
238 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
239 if (RT_SUCCESS(rc))
240 rc = pMod->pDbgVt->pfnSymbolByAddr(pMod, iSeg, off, fFlags, poffDisp, pSymInfo);
241 else
242 {
243 PRTDBGMODDEFERRED pThis = (PRTDBGMODDEFERRED)pMod->pvDbgPriv;
244 if (off == 0)
245 rc = rtDbgModDeferredDbgSymInfo_Start(pThis, pSymInfo);
246 else if (off >= pThis->cbImage - 1 || (fFlags & RTDBGSYMADDR_FLAGS_GREATER_OR_EQUAL))
247 rc = rtDbgModDeferredDbgSymInfo_Last(pThis, pSymInfo);
248 else
249 rc = rtDbgModDeferredDbgSymInfo_Start(pThis, pSymInfo);
250 if (poffDisp)
251 *poffDisp = off - pSymInfo->offSeg;
252 }
253 return rc;
254}
255
256
257/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByName} */
258static DECLCALLBACK(int) rtDbgModDeferredDbg_SymbolByName(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol,
259 PRTDBGSYMBOL pSymInfo)
260{
261 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
262 if (RT_SUCCESS(rc))
263 rc = pMod->pDbgVt->pfnSymbolByName(pMod, pszSymbol, cchSymbol, pSymInfo);
264 else
265 {
266 PRTDBGMODDEFERRED pThis = (PRTDBGMODDEFERRED)pMod->pvDbgPriv;
267 if ( cchSymbol == sizeof("DeferredStart") - 1
268 && !memcmp(pszSymbol, RT_STR_TUPLE("DeferredStart")))
269 rc = rtDbgModDeferredDbgSymInfo_Start(pThis, pSymInfo);
270 else if ( cchSymbol == sizeof("DeferredLast") - 1
271 && !memcmp(pszSymbol, RT_STR_TUPLE("DeferredLast")))
272 rc = rtDbgModDeferredDbgSymInfo_Last(pThis, pSymInfo);
273 else
274 rc = VERR_SYMBOL_NOT_FOUND;
275 }
276 return rc;
277}
278
279
280/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByOrdinal} */
281static DECLCALLBACK(int) rtDbgModDeferredDbg_SymbolByOrdinal(PRTDBGMODINT pMod, uint32_t iOrdinal, PRTDBGSYMBOL pSymInfo)
282{
283 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
284 if (RT_SUCCESS(rc))
285 rc = pMod->pDbgVt->pfnSymbolByOrdinal(pMod, iOrdinal, pSymInfo);
286 else
287 {
288 PRTDBGMODDEFERRED pThis = (PRTDBGMODDEFERRED)pMod->pvDbgPriv;
289 if (iOrdinal == 0)
290 rc = rtDbgModDeferredDbgSymInfo_Start(pThis, pSymInfo);
291 else if (iOrdinal == 1)
292 rc = rtDbgModDeferredDbgSymInfo_Last(pThis, pSymInfo);
293 else
294 rc = VERR_SYMBOL_NOT_FOUND;
295 }
296 return rc;
297}
298
299
300/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolCount} */
301static DECLCALLBACK(uint32_t) rtDbgModDeferredDbg_SymbolCount(PRTDBGMODINT pMod)
302{
303 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
304 if (RT_SUCCESS(rc))
305 return pMod->pDbgVt->pfnSymbolCount(pMod);
306 return 2;
307}
308
309
310/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolAdd} */
311static DECLCALLBACK(int) rtDbgModDeferredDbg_SymbolAdd(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol,
312 RTDBGSEGIDX iSeg, RTUINTPTR off, RTUINTPTR cb, uint32_t fFlags,
313 uint32_t *piOrdinal)
314{
315 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
316 if (RT_SUCCESS(rc))
317 rc = pMod->pDbgVt->pfnSymbolAdd(pMod, pszSymbol, cchSymbol, iSeg, off, cb, fFlags, piOrdinal);
318 return rc;
319}
320
321
322/** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentByIndex} */
323static DECLCALLBACK(int) rtDbgModDeferredDbg_SegmentByIndex(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, PRTDBGSEGMENT pSegInfo)
324{
325 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
326 if (RT_SUCCESS(rc))
327 rc = pMod->pDbgVt->pfnSegmentByIndex(pMod, iSeg, pSegInfo);
328 else if (iSeg == 0)
329 {
330 PRTDBGMODDEFERRED pThis = (PRTDBGMODDEFERRED)pMod->pvDbgPriv;
331 pSegInfo->Address = 0;
332 pSegInfo->uRva = 0;
333 pSegInfo->cb = pThis->cbImage;
334 pSegInfo->fFlags = 0;
335 pSegInfo->iSeg = 0;
336 memcpy(pSegInfo->szName, RT_STR_TUPLE("LATER"));
337 rc = VINF_SUCCESS;
338 }
339 else
340 rc = VERR_DBG_INVALID_SEGMENT_INDEX;
341 return rc;
342}
343
344
345/** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentCount} */
346static DECLCALLBACK(RTDBGSEGIDX) rtDbgModDeferredDbg_SegmentCount(PRTDBGMODINT pMod)
347{
348 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
349 if (RT_SUCCESS(rc))
350 return pMod->pDbgVt->pfnSegmentCount(pMod);
351 return 1;
352}
353
354
355/** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentAdd} */
356static DECLCALLBACK(int) rtDbgModDeferredDbg_SegmentAdd(PRTDBGMODINT pMod, RTUINTPTR uRva, RTUINTPTR cb, const char *pszName,
357 size_t cchName, uint32_t fFlags, PRTDBGSEGIDX piSeg)
358{
359 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
360 if (RT_SUCCESS(rc))
361 rc = pMod->pDbgVt->pfnSegmentAdd(pMod, uRva, cb, pszName, cchName, fFlags, piSeg);
362 return rc;
363}
364
365
366/** @interface_method_impl{RTDBGMODVTDBG,pfnImageSize} */
367static DECLCALLBACK(RTUINTPTR) rtDbgModDeferredDbg_ImageSize(PRTDBGMODINT pMod)
368{
369 PRTDBGMODDEFERRED pThis = (PRTDBGMODDEFERRED)pMod->pvDbgPriv;
370 return pThis->cbImage;
371}
372
373
374/** @interface_method_impl{RTDBGMODVTDBG,pfnRvaToSegOff} */
375static DECLCALLBACK(RTDBGSEGIDX) rtDbgModDeferredDbg_RvaToSegOff(PRTDBGMODINT pMod, RTUINTPTR uRva, PRTUINTPTR poffSeg)
376{
377 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
378 if (RT_SUCCESS(rc))
379 return pMod->pDbgVt->pfnRvaToSegOff(pMod, uRva, poffSeg);
380 return 0;
381}
382
383
384/** @interface_method_impl{RTDBGMODVTDBG,pfnClose} */
385static DECLCALLBACK(int) rtDbgModDeferredDbg_Close(PRTDBGMODINT pMod)
386{
387 rtDbgModDeferredReleaseInstanceData((PRTDBGMODDEFERRED)pMod->pvImgPriv);
388 return VINF_SUCCESS;
389}
390
391
392/** @interface_method_impl{RTDBGMODVTDBG,pfnTryOpen} */
393static DECLCALLBACK(int) rtDbgModDeferredDbg_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch)
394{
395 NOREF(enmArch);
396 return rtDbgModDeferredDoIt(pMod, true /*fForceRetry*/);
397}
398
399
400
401/** Virtual function table for the deferred debug info reader. */
402DECL_HIDDEN_CONST(RTDBGMODVTDBG) const g_rtDbgModVtDbgDeferred =
403{
404 /*.u32Magic = */ RTDBGMODVTDBG_MAGIC,
405 /*.fSupports = */ RT_DBGTYPE_MAP,
406 /*.pszName = */ "deferred",
407 /*.pfnTryOpen = */ rtDbgModDeferredDbg_TryOpen,
408 /*.pfnClose = */ rtDbgModDeferredDbg_Close,
409
410 /*.pfnRvaToSegOff = */ rtDbgModDeferredDbg_RvaToSegOff,
411 /*.pfnImageSize = */ rtDbgModDeferredDbg_ImageSize,
412
413 /*.pfnSegmentAdd = */ rtDbgModDeferredDbg_SegmentAdd,
414 /*.pfnSegmentCount = */ rtDbgModDeferredDbg_SegmentCount,
415 /*.pfnSegmentByIndex = */ rtDbgModDeferredDbg_SegmentByIndex,
416
417 /*.pfnSymbolAdd = */ rtDbgModDeferredDbg_SymbolAdd,
418 /*.pfnSymbolCount = */ rtDbgModDeferredDbg_SymbolCount,
419 /*.pfnSymbolByOrdinal = */ rtDbgModDeferredDbg_SymbolByOrdinal,
420 /*.pfnSymbolByName = */ rtDbgModDeferredDbg_SymbolByName,
421 /*.pfnSymbolByAddr = */ rtDbgModDeferredDbg_SymbolByAddr,
422
423 /*.pfnLineAdd = */ rtDbgModDeferredDbg_LineAdd,
424 /*.pfnLineCount = */ rtDbgModDeferredDbg_LineCount,
425 /*.pfnLineByOrdinal = */ rtDbgModDeferredDbg_LineByOrdinal,
426 /*.pfnLineByAddr = */ rtDbgModDeferredDbg_LineByAddr,
427
428 /*.u32EndMagic = */ RTDBGMODVTDBG_MAGIC
429};
430
431
432
433
434/*
435 *
436 * I m a g e M e t h o d s
437 * I m a g e M e t h o d s
438 * I m a g e M e t h o d s
439 *
440 */
441
442/** @interface_method_impl{RTDBGMODVTIMG,pfnQueryProp} */
443static DECLCALLBACK(int ) rtDbgModDeferredImg_QueryProp(PRTDBGMODINT pMod, RTLDRPROP enmProp, void *pvBuf, size_t cbBuf)
444{
445 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
446 if (RT_SUCCESS(rc))
447 rc = pMod->pImgVt->pfnQueryProp(pMod, enmProp, pvBuf, cbBuf);
448 return rc;
449}
450
451
452/** @interface_method_impl{RTDBGMODVTIMG,pfnGetArch} */
453static DECLCALLBACK(RTLDRARCH) rtDbgModDeferredImg_GetArch(PRTDBGMODINT pMod)
454{
455 RTLDRARCH enmArch;
456 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
457 if (RT_SUCCESS(rc))
458 enmArch = pMod->pImgVt->pfnGetArch(pMod);
459 else
460 enmArch = RTLDRARCH_WHATEVER;
461 return enmArch;
462}
463
464
465/** @interface_method_impl{RTDBGMODVTIMG,pfnGetFormat} */
466static DECLCALLBACK(RTLDRFMT) rtDbgModDeferredImg_GetFormat(PRTDBGMODINT pMod)
467{
468 RTLDRFMT enmFmt;
469 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
470 if (RT_SUCCESS(rc))
471 enmFmt = pMod->pImgVt->pfnGetFormat(pMod);
472 else
473 enmFmt = RTLDRFMT_INVALID;
474 return enmFmt;
475}
476
477
478/** @interface_method_impl{RTDBGMODVTIMG,pfnReadAt} */
479static DECLCALLBACK(int) rtDbgModDeferredImg_ReadAt(PRTDBGMODINT pMod, uint32_t iDbgInfoHint, RTFOFF off, void *pvBuf, size_t cb)
480{
481 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
482 if (RT_SUCCESS(rc))
483 rc = pMod->pImgVt->pfnReadAt(pMod, iDbgInfoHint, off, pvBuf, cb);
484 return rc;
485}
486
487
488/** @interface_method_impl{RTDBGMODVTIMG,pfnUnmapPart} */
489static DECLCALLBACK(int) rtDbgModDeferredImg_UnmapPart(PRTDBGMODINT pMod, size_t cb, void const **ppvMap)
490{
491 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
492 if (RT_SUCCESS(rc))
493 rc = pMod->pImgVt->pfnUnmapPart(pMod, cb, ppvMap);
494 return rc;
495}
496
497
498/** @interface_method_impl{RTDBGMODVTIMG,pfnMapPart} */
499static DECLCALLBACK(int) rtDbgModDeferredImg_MapPart(PRTDBGMODINT pMod, uint32_t iDbgInfo, RTFOFF off, size_t cb, void const **ppvMap)
500{
501 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
502 if (RT_SUCCESS(rc))
503 rc = pMod->pImgVt->pfnMapPart(pMod, iDbgInfo, off, cb, ppvMap);
504 return rc;
505}
506
507
508/** @interface_method_impl{RTDBGMODVTIMG,pfnImageSize} */
509static DECLCALLBACK(RTUINTPTR) rtDbgModDeferredImg_ImageSize(PRTDBGMODINT pMod)
510{
511 PRTDBGMODDEFERRED pThis = (PRTDBGMODDEFERRED)pMod->pvImgPriv;
512 return pThis->cbImage;
513}
514
515
516/** @interface_method_impl{RTDBGMODVTIMG,pfnRvaToSegOffset} */
517static DECLCALLBACK(int) rtDbgModDeferredImg_RvaToSegOffset(PRTDBGMODINT pMod, RTLDRADDR uRva,
518 PRTDBGSEGIDX piSeg, PRTLDRADDR poffSeg)
519{
520 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
521 if (RT_SUCCESS(rc))
522 rc = pMod->pImgVt->pfnRvaToSegOffset(pMod, uRva, piSeg, poffSeg);
523 return rc;
524}
525
526
527/** @interface_method_impl{RTDBGMODVTIMG,pfnLinkAddressToSegOffset} */
528static DECLCALLBACK(int) rtDbgModDeferredImg_LinkAddressToSegOffset(PRTDBGMODINT pMod, RTLDRADDR LinkAddress,
529 PRTDBGSEGIDX piSeg, PRTLDRADDR poffSeg)
530{
531 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
532 if (RT_SUCCESS(rc))
533 rc = pMod->pImgVt->pfnLinkAddressToSegOffset(pMod, LinkAddress, piSeg, poffSeg);
534 return rc;
535}
536
537
538/** @interface_method_impl{RTDBGMODVTIMG,pfnEnumSymbols} */
539static DECLCALLBACK(int) rtDbgModDeferredImg_EnumSymbols(PRTDBGMODINT pMod, uint32_t fFlags, RTLDRADDR BaseAddress,
540 PFNRTLDRENUMSYMS pfnCallback, void *pvUser)
541{
542 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
543 if (RT_SUCCESS(rc))
544 rc = pMod->pImgVt->pfnEnumSymbols(pMod, fFlags, BaseAddress, pfnCallback, pvUser);
545 return rc;
546}
547
548
549/** @interface_method_impl{RTDBGMODVTIMG,pfnEnumSegments} */
550static DECLCALLBACK(int) rtDbgModDeferredImg_EnumSegments(PRTDBGMODINT pMod, PFNRTLDRENUMSEGS pfnCallback, void *pvUser)
551{
552 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
553 if (RT_SUCCESS(rc))
554 rc = pMod->pImgVt->pfnEnumSegments(pMod, pfnCallback, pvUser);
555 return rc;
556}
557
558
559/** @interface_method_impl{RTDBGMODVTIMG,pfnEnumDbgInfo} */
560static DECLCALLBACK(int) rtDbgModDeferredImg_EnumDbgInfo(PRTDBGMODINT pMod, PFNRTLDRENUMDBG pfnCallback, void *pvUser)
561{
562 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
563 if (RT_SUCCESS(rc))
564 rc = pMod->pImgVt->pfnEnumDbgInfo(pMod, pfnCallback, pvUser);
565 return rc;
566}
567
568
569/** @interface_method_impl{RTDBGMODVTIMG,pfnClose} */
570static DECLCALLBACK(int) rtDbgModDeferredImg_Close(PRTDBGMODINT pMod)
571{
572 rtDbgModDeferredReleaseInstanceData((PRTDBGMODDEFERRED)pMod->pvImgPriv);
573 return VINF_SUCCESS;
574}
575
576
577/** @interface_method_impl{RTDBGMODVTIMG,pfnTryOpen} */
578static DECLCALLBACK(int) rtDbgModDeferredImg_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch)
579{
580 NOREF(enmArch);
581 return rtDbgModDeferredDoIt(pMod, true /*fForceRetry*/);
582}
583
584
585/** Virtual function table for the RTLdr based image reader. */
586DECL_HIDDEN_CONST(RTDBGMODVTIMG) const g_rtDbgModVtImgDeferred =
587{
588 /*.u32Magic = */ RTDBGMODVTIMG_MAGIC,
589 /*.fReserved = */ 0,
590 /*.pszName = */ "deferred",
591 /*.pfnTryOpen = */ rtDbgModDeferredImg_TryOpen,
592 /*.pfnClose = */ rtDbgModDeferredImg_Close,
593 /*.pfnEnumDbgInfo = */ rtDbgModDeferredImg_EnumDbgInfo,
594 /*.pfnEnumSegments = */ rtDbgModDeferredImg_EnumSegments,
595 /*.pfnEnumSymbols = */ rtDbgModDeferredImg_EnumSymbols,
596 /*.pfnGetLoadedSize = */ rtDbgModDeferredImg_ImageSize,
597 /*.pfnLinkAddressToSegOffset = */ rtDbgModDeferredImg_LinkAddressToSegOffset,
598 /*.pfnRvaToSegOffset = */ rtDbgModDeferredImg_RvaToSegOffset,
599 /*.pfnMapPart = */ rtDbgModDeferredImg_MapPart,
600 /*.pfnUnmapPart = */ rtDbgModDeferredImg_UnmapPart,
601 /*.pfnReadAt = */ rtDbgModDeferredImg_ReadAt,
602 /*.pfnGetFormat = */ rtDbgModDeferredImg_GetFormat,
603 /*.pfnGetArch = */ rtDbgModDeferredImg_GetArch,
604 /*.pfnQueryProp = */ rtDbgModDeferredImg_QueryProp,
605
606 /*.u32EndMagic = */ RTDBGMODVTIMG_MAGIC
607};
608
609
610/**
611 * Creates a deferred loading stub for both image and debug info.
612 *
613 * @returns IPRT status code.
614 * @param pDbgMod The debug module.
615 * @param pfnDeferred The callback that will try load the image and
616 * debug info.
617 * @param cbImage The size of the image.
618 * @param hDbgCfg The debug config handle. Can be NIL. A
619 * reference will be retained.
620 * @param cbDeferred The size of the deferred instance data, 0 if the
621 * default structure is good enough.
622 * @param ppDeferred Where to return the instance data. Can be NULL.
623 */
624DECLHIDDEN(int) rtDbgModDeferredCreate(PRTDBGMODINT pDbgMod, PFNRTDBGMODDEFERRED pfnDeferred, RTUINTPTR cbImage,
625 RTDBGCFG hDbgCfg, size_t cbDeferred, PRTDBGMODDEFERRED *ppDeferred)
626{
627 AssertReturn(!pDbgMod->pDbgVt, VERR_DBG_MOD_IPE);
628
629 if (cbDeferred < sizeof(RTDBGMODDEFERRED))
630 cbDeferred = sizeof(RTDBGMODDEFERRED);
631 PRTDBGMODDEFERRED pDeferred = (PRTDBGMODDEFERRED)RTMemAllocZ(cbDeferred);
632 if (!pDeferred)
633 return VERR_NO_MEMORY;
634
635 pDeferred->cbImage = cbImage;
636 pDeferred->cRefs = 1 + (pDbgMod->pImgVt == NULL);
637 if (hDbgCfg != NIL_RTDBGCFG)
638 RTDbgCfgRetain(hDbgCfg);
639 pDeferred->hDbgCfg = hDbgCfg;
640 pDeferred->pfnDeferred = pfnDeferred;
641
642 pDbgMod->pDbgVt = &g_rtDbgModVtDbgDeferred;
643 pDbgMod->pvDbgPriv = pDeferred;
644 if (!pDbgMod->pImgVt)
645 {
646 pDbgMod->pImgVt = &g_rtDbgModVtImgDeferred;
647 pDbgMod->pvImgPriv = pDeferred;
648 }
649 pDbgMod->fDeferred = true;
650 pDbgMod->fDeferredFailed = false;
651
652 if (ppDeferred)
653 *ppDeferred = pDeferred;
654 return VINF_SUCCESS;
655}
656
Note: See TracBrowser for help on using the repository browser.

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