VirtualBox

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

Last change on this file since 46109 was 46109, checked in by vboxsync, 12 years ago

Made deferred loading work.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 19.5 KB
Line 
1/* $Id: dbgmoddeferred.cpp 46109 2013-05-15 19:54:06Z 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 memcpy(pSymInfo->szName, RT_STR_TUPLE("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 memcpy(pSymInfo->szName, RT_STR_TUPLE("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 }
338 else
339 rc = VERR_DBG_INVALID_SEGMENT_INDEX;
340 return rc;
341}
342
343
344/** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentCount} */
345static DECLCALLBACK(RTDBGSEGIDX) rtDbgModDeferredDbg_SegmentCount(PRTDBGMODINT pMod)
346{
347 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
348 if (RT_SUCCESS(rc))
349 return pMod->pDbgVt->pfnSegmentCount(pMod);
350 return 1;
351}
352
353
354/** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentAdd} */
355static DECLCALLBACK(int) rtDbgModDeferredDbg_SegmentAdd(PRTDBGMODINT pMod, RTUINTPTR uRva, RTUINTPTR cb, const char *pszName,
356 size_t cchName, uint32_t fFlags, PRTDBGSEGIDX piSeg)
357{
358 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
359 if (RT_SUCCESS(rc))
360 rc = pMod->pDbgVt->pfnSegmentAdd(pMod, uRva, cb, pszName, cchName, fFlags, piSeg);
361 return rc;
362}
363
364
365/** @interface_method_impl{RTDBGMODVTDBG,pfnImageSize} */
366static DECLCALLBACK(RTUINTPTR) rtDbgModDeferredDbg_ImageSize(PRTDBGMODINT pMod)
367{
368 PRTDBGMODDEFERRED pThis = (PRTDBGMODDEFERRED)pMod->pvDbgPriv;
369 return pThis->cbImage;
370}
371
372
373/** @interface_method_impl{RTDBGMODVTDBG,pfnRvaToSegOff} */
374static DECLCALLBACK(RTDBGSEGIDX) rtDbgModDeferredDbg_RvaToSegOff(PRTDBGMODINT pMod, RTUINTPTR uRva, PRTUINTPTR poffSeg)
375{
376 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
377 if (RT_SUCCESS(rc))
378 return pMod->pDbgVt->pfnRvaToSegOff(pMod, uRva, poffSeg);
379 return 0;
380}
381
382
383/** @interface_method_impl{RTDBGMODVTDBG,pfnClose} */
384static DECLCALLBACK(int) rtDbgModDeferredDbg_Close(PRTDBGMODINT pMod)
385{
386 rtDbgModDeferredReleaseInstanceData((PRTDBGMODDEFERRED)pMod->pvImgPriv);
387 return VINF_SUCCESS;
388}
389
390
391/** @interface_method_impl{RTDBGMODVTDBG,pfnTryOpen} */
392static DECLCALLBACK(int) rtDbgModDeferredDbg_TryOpen(PRTDBGMODINT pMod)
393{
394 return rtDbgModDeferredDoIt(pMod, true /*fForceRetry*/);
395}
396
397
398
399/** Virtual function table for the deferred debug info reader. */
400DECL_HIDDEN_CONST(RTDBGMODVTDBG) const g_rtDbgModVtDbgDeferred =
401{
402 /*.u32Magic = */ RTDBGMODVTDBG_MAGIC,
403 /*.fSupports = */ RT_DBGTYPE_MAP,
404 /*.pszName = */ "deferred",
405 /*.pfnTryOpen = */ rtDbgModDeferredDbg_TryOpen,
406 /*.pfnClose = */ rtDbgModDeferredDbg_Close,
407
408 /*.pfnRvaToSegOff = */ rtDbgModDeferredDbg_RvaToSegOff,
409 /*.pfnImageSize = */ rtDbgModDeferredDbg_ImageSize,
410
411 /*.pfnSegmentAdd = */ rtDbgModDeferredDbg_SegmentAdd,
412 /*.pfnSegmentCount = */ rtDbgModDeferredDbg_SegmentCount,
413 /*.pfnSegmentByIndex = */ rtDbgModDeferredDbg_SegmentByIndex,
414
415 /*.pfnSymbolAdd = */ rtDbgModDeferredDbg_SymbolAdd,
416 /*.pfnSymbolCount = */ rtDbgModDeferredDbg_SymbolCount,
417 /*.pfnSymbolByOrdinal = */ rtDbgModDeferredDbg_SymbolByOrdinal,
418 /*.pfnSymbolByName = */ rtDbgModDeferredDbg_SymbolByName,
419 /*.pfnSymbolByAddr = */ rtDbgModDeferredDbg_SymbolByAddr,
420
421 /*.pfnLineAdd = */ rtDbgModDeferredDbg_LineAdd,
422 /*.pfnLineCount = */ rtDbgModDeferredDbg_LineCount,
423 /*.pfnLineByOrdinal = */ rtDbgModDeferredDbg_LineByOrdinal,
424 /*.pfnLineByAddr = */ rtDbgModDeferredDbg_LineByAddr,
425
426 /*.u32EndMagic = */ RTDBGMODVTDBG_MAGIC
427};
428
429
430
431
432/*
433 *
434 * I m a g e M e t h o d s
435 * I m a g e M e t h o d s
436 * I m a g e M e t h o d s
437 *
438 */
439
440
441/** @interface_method_impl{RTDBGMODVTIMG,pfnUnmapPart} */
442static DECLCALLBACK(int) rtDbgModDeferredImg_UnmapPart(PRTDBGMODINT pMod, size_t cb, void const **ppvMap)
443{
444 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
445 if (RT_SUCCESS(rc))
446 rc = pMod->pImgVt->pfnUnmapPart(pMod, cb, ppvMap);
447 return rc;
448}
449
450
451/** @interface_method_impl{RTDBGMODVTIMG,pfnMapPart} */
452static DECLCALLBACK(int) rtDbgModDeferredImg_MapPart(PRTDBGMODINT pMod, RTFOFF off, size_t cb, void const **ppvMap)
453{
454 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
455 if (RT_SUCCESS(rc))
456 rc = pMod->pImgVt->pfnMapPart(pMod, off, cb, ppvMap);
457 return rc;
458}
459
460
461/** @interface_method_impl{RTDBGMODVTIMG,pfnImageSize} */
462static DECLCALLBACK(RTUINTPTR) rtDbgModDeferredImg_ImageSize(PRTDBGMODINT pMod)
463{
464 PRTDBGMODDEFERRED pThis = (PRTDBGMODDEFERRED)pMod->pvImgPriv;
465 return pThis->cbImage;
466}
467
468
469/** @interface_method_impl{RTDBGMODVTIMG,pfnLinkAddressToSegOffset} */
470static DECLCALLBACK(int) rtDbgModDeferredImg_LinkAddressToSegOffset(PRTDBGMODINT pMod, RTLDRADDR LinkAddress,
471 PRTDBGSEGIDX piSeg, PRTLDRADDR poffSeg)
472{
473 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
474 if (RT_SUCCESS(rc))
475 rc = pMod->pImgVt->pfnLinkAddressToSegOffset(pMod, LinkAddress, piSeg, poffSeg);
476 return rc;
477}
478
479
480/** @interface_method_impl{RTDBGMODVTIMG,pfnEnumSegments} */
481static DECLCALLBACK(int) rtDbgModDeferredImg_EnumSegments(PRTDBGMODINT pMod, PFNRTLDRENUMSEGS pfnCallback, void *pvUser)
482{
483 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
484 if (RT_SUCCESS(rc))
485 rc = pMod->pImgVt->pfnEnumSegments(pMod, pfnCallback, pvUser);
486 return rc;
487}
488
489
490/** @interface_method_impl{RTDBGMODVTIMG,pfnEnumDbgInfo} */
491static DECLCALLBACK(int) rtDbgModDeferredImg_EnumDbgInfo(PRTDBGMODINT pMod, PFNRTLDRENUMDBG pfnCallback, void *pvUser)
492{
493 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
494 if (RT_SUCCESS(rc))
495 rc = pMod->pImgVt->pfnEnumDbgInfo(pMod, pfnCallback, pvUser);
496 return rc;
497}
498
499
500/** @interface_method_impl{RTDBGMODVTIMG,pfnClose} */
501static DECLCALLBACK(int) rtDbgModDeferredImg_Close(PRTDBGMODINT pMod)
502{
503 rtDbgModDeferredReleaseInstanceData((PRTDBGMODDEFERRED)pMod->pvImgPriv);
504 return VINF_SUCCESS;
505}
506
507
508/** @interface_method_impl{RTDBGMODVTIMG,pfnTryOpen} */
509static DECLCALLBACK(int) rtDbgModDeferredImg_TryOpen(PRTDBGMODINT pMod)
510{
511 return rtDbgModDeferredDoIt(pMod, true /*fForceRetry*/);
512}
513
514
515/** Virtual function table for the RTLdr based image reader. */
516DECL_HIDDEN_CONST(RTDBGMODVTIMG) const g_rtDbgModVtImgDeferred =
517{
518 /*.u32Magic = */ RTDBGMODVTIMG_MAGIC,
519 /*.fReserved = */ 0,
520 /*.pszName = */ "deferred",
521 /*.pfnTryOpen = */ rtDbgModDeferredImg_TryOpen,
522 /*.pfnClose = */ rtDbgModDeferredImg_Close,
523 /*.pfnEnumDbgInfo = */ rtDbgModDeferredImg_EnumDbgInfo,
524 /*.pfnEnumSegments = */ rtDbgModDeferredImg_EnumSegments,
525 /*.pfnGetLoadedSize = */ rtDbgModDeferredImg_ImageSize,
526 /*.pfnLinkAddressToSegOffset = */ rtDbgModDeferredImg_LinkAddressToSegOffset,
527 /*.pfnMapPart = */ rtDbgModDeferredImg_MapPart,
528 /*.pfnUnmapPart = */ rtDbgModDeferredImg_UnmapPart,
529
530 /*.u32EndMagic = */ RTDBGMODVTIMG_MAGIC
531};
532
533
534/**
535 * Creates a deferred loading stub for both image and debug info.
536 *
537 * @returns IPRT status code.
538 * @param pDbgMod The debug module.
539 * @param pfnDeferred The callback that will try load the image and
540 * debug info.
541 * @param cbImage The size of the image.
542 * @param hDbgCfg The debug config handle. Can be NIL. A
543 * reference will be retained.
544 * @param ppDeferred Where to return the instance data. Can be NULL.
545 */
546DECLHIDDEN(int) rtDbgModDeferredCreate(PRTDBGMODINT pDbgMod, PFNRTDBGMODDEFERRED pfnDeferred, RTUINTPTR cbImage,
547 RTDBGCFG hDbgCfg, PRTDBGMODDEFERRED *ppDeferred)
548{
549 AssertReturn(!pDbgMod->pDbgVt, VERR_DBG_MOD_IPE);
550
551 PRTDBGMODDEFERRED pDeferred = (PRTDBGMODDEFERRED)RTMemAllocZ(sizeof(*pDeferred));
552 if (!pDeferred)
553 return VERR_NO_MEMORY;
554
555 pDeferred->cbImage = cbImage;
556 pDeferred->cRefs = 1 + (pDbgMod->pImgVt == NULL);
557 if (hDbgCfg != NIL_RTDBGCFG)
558 RTDbgCfgRetain(hDbgCfg);
559 pDeferred->hDbgCfg = hDbgCfg;
560 pDeferred->pfnDeferred = pfnDeferred;
561
562 pDbgMod->pDbgVt = &g_rtDbgModVtDbgDeferred;
563 pDbgMod->pvDbgPriv = pDeferred;
564 if (!pDbgMod->pImgVt)
565 {
566 pDbgMod->pImgVt = &g_rtDbgModVtImgDeferred;
567 pDbgMod->pvImgPriv = pDeferred;
568 }
569 pDbgMod->fDeferred = true;
570 pDbgMod->fDeferredFailed = false;
571
572 if (ppDeferred)
573 *ppDeferred = pDeferred;
574 return VINF_SUCCESS;
575}
576
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