VirtualBox

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

Last change on this file since 72778 was 69111, checked in by vboxsync, 7 years ago

(C) year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.7 KB
Line 
1/* $Id: dbgmoddeferred.cpp 69111 2017-10-17 14:26:02Z vboxsync $ */
2/** @file
3 * IPRT - Debug Module Deferred Loading Stub.
4 */
5
6/*
7 * Copyright (C) 2013-2017 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 Rva,
518 PRTDBGSEGIDX piSeg, PRTLDRADDR poffSeg)
519{
520 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
521 if (RT_SUCCESS(rc))
522 rc = pMod->pImgVt->pfnRvaToSegOffset(pMod, Rva, 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