VirtualBox

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

Last change on this file since 73375 was 73375, checked in by vboxsync, 6 years ago

IPRT: Added RTLDRPROP_UNWIND_INFO to RTLdrQueryPropEx. Added RTDbgModImageQueryProp, RTDbgModImageGetArch, and RTDbgModImageGetFormat.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.9 KB
Line 
1/* $Id: dbgmoddeferred.cpp 73375 2018-07-27 07:59:25Z 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 if ( (fFlags & RTDBGSYMADDR_FLAGS_SKIP_ABS_IN_DEFERRED)
239 && iSeg == RTDBGSEGIDX_ABS)
240 return VERR_SYMBOL_NOT_FOUND;
241
242 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
243 if (RT_SUCCESS(rc))
244 rc = pMod->pDbgVt->pfnSymbolByAddr(pMod, iSeg, off, fFlags, poffDisp, pSymInfo);
245 else
246 {
247 PRTDBGMODDEFERRED pThis = (PRTDBGMODDEFERRED)pMod->pvDbgPriv;
248 if (off == 0)
249 rc = rtDbgModDeferredDbgSymInfo_Start(pThis, pSymInfo);
250 else if (off >= pThis->cbImage - 1 || (fFlags & RTDBGSYMADDR_FLAGS_GREATER_OR_EQUAL))
251 rc = rtDbgModDeferredDbgSymInfo_Last(pThis, pSymInfo);
252 else
253 rc = rtDbgModDeferredDbgSymInfo_Start(pThis, pSymInfo);
254 if (poffDisp)
255 *poffDisp = off - pSymInfo->offSeg;
256 }
257 return rc;
258}
259
260
261/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByName} */
262static DECLCALLBACK(int) rtDbgModDeferredDbg_SymbolByName(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol,
263 PRTDBGSYMBOL pSymInfo)
264{
265 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
266 if (RT_SUCCESS(rc))
267 rc = pMod->pDbgVt->pfnSymbolByName(pMod, pszSymbol, cchSymbol, pSymInfo);
268 else
269 {
270 PRTDBGMODDEFERRED pThis = (PRTDBGMODDEFERRED)pMod->pvDbgPriv;
271 if ( cchSymbol == sizeof("DeferredStart") - 1
272 && !memcmp(pszSymbol, RT_STR_TUPLE("DeferredStart")))
273 rc = rtDbgModDeferredDbgSymInfo_Start(pThis, pSymInfo);
274 else if ( cchSymbol == sizeof("DeferredLast") - 1
275 && !memcmp(pszSymbol, RT_STR_TUPLE("DeferredLast")))
276 rc = rtDbgModDeferredDbgSymInfo_Last(pThis, pSymInfo);
277 else
278 rc = VERR_SYMBOL_NOT_FOUND;
279 }
280 return rc;
281}
282
283
284/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByOrdinal} */
285static DECLCALLBACK(int) rtDbgModDeferredDbg_SymbolByOrdinal(PRTDBGMODINT pMod, uint32_t iOrdinal, PRTDBGSYMBOL pSymInfo)
286{
287 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
288 if (RT_SUCCESS(rc))
289 rc = pMod->pDbgVt->pfnSymbolByOrdinal(pMod, iOrdinal, pSymInfo);
290 else
291 {
292 PRTDBGMODDEFERRED pThis = (PRTDBGMODDEFERRED)pMod->pvDbgPriv;
293 if (iOrdinal == 0)
294 rc = rtDbgModDeferredDbgSymInfo_Start(pThis, pSymInfo);
295 else if (iOrdinal == 1)
296 rc = rtDbgModDeferredDbgSymInfo_Last(pThis, pSymInfo);
297 else
298 rc = VERR_SYMBOL_NOT_FOUND;
299 }
300 return rc;
301}
302
303
304/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolCount} */
305static DECLCALLBACK(uint32_t) rtDbgModDeferredDbg_SymbolCount(PRTDBGMODINT pMod)
306{
307 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
308 if (RT_SUCCESS(rc))
309 return pMod->pDbgVt->pfnSymbolCount(pMod);
310 return 2;
311}
312
313
314/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolAdd} */
315static DECLCALLBACK(int) rtDbgModDeferredDbg_SymbolAdd(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol,
316 RTDBGSEGIDX iSeg, RTUINTPTR off, RTUINTPTR cb, uint32_t fFlags,
317 uint32_t *piOrdinal)
318{
319 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
320 if (RT_SUCCESS(rc))
321 rc = pMod->pDbgVt->pfnSymbolAdd(pMod, pszSymbol, cchSymbol, iSeg, off, cb, fFlags, piOrdinal);
322 return rc;
323}
324
325
326/** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentByIndex} */
327static DECLCALLBACK(int) rtDbgModDeferredDbg_SegmentByIndex(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, PRTDBGSEGMENT pSegInfo)
328{
329 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
330 if (RT_SUCCESS(rc))
331 rc = pMod->pDbgVt->pfnSegmentByIndex(pMod, iSeg, pSegInfo);
332 else if (iSeg == 0)
333 {
334 PRTDBGMODDEFERRED pThis = (PRTDBGMODDEFERRED)pMod->pvDbgPriv;
335 pSegInfo->Address = 0;
336 pSegInfo->uRva = 0;
337 pSegInfo->cb = pThis->cbImage;
338 pSegInfo->fFlags = 0;
339 pSegInfo->iSeg = 0;
340 memcpy(pSegInfo->szName, RT_STR_TUPLE("LATER"));
341 rc = VINF_SUCCESS;
342 }
343 else
344 rc = VERR_DBG_INVALID_SEGMENT_INDEX;
345 return rc;
346}
347
348
349/** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentCount} */
350static DECLCALLBACK(RTDBGSEGIDX) rtDbgModDeferredDbg_SegmentCount(PRTDBGMODINT pMod)
351{
352 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
353 if (RT_SUCCESS(rc))
354 return pMod->pDbgVt->pfnSegmentCount(pMod);
355 return 1;
356}
357
358
359/** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentAdd} */
360static DECLCALLBACK(int) rtDbgModDeferredDbg_SegmentAdd(PRTDBGMODINT pMod, RTUINTPTR uRva, RTUINTPTR cb, const char *pszName,
361 size_t cchName, uint32_t fFlags, PRTDBGSEGIDX piSeg)
362{
363 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
364 if (RT_SUCCESS(rc))
365 rc = pMod->pDbgVt->pfnSegmentAdd(pMod, uRva, cb, pszName, cchName, fFlags, piSeg);
366 return rc;
367}
368
369
370/** @interface_method_impl{RTDBGMODVTDBG,pfnImageSize} */
371static DECLCALLBACK(RTUINTPTR) rtDbgModDeferredDbg_ImageSize(PRTDBGMODINT pMod)
372{
373 PRTDBGMODDEFERRED pThis = (PRTDBGMODDEFERRED)pMod->pvDbgPriv;
374 return pThis->cbImage;
375}
376
377
378/** @interface_method_impl{RTDBGMODVTDBG,pfnRvaToSegOff} */
379static DECLCALLBACK(RTDBGSEGIDX) rtDbgModDeferredDbg_RvaToSegOff(PRTDBGMODINT pMod, RTUINTPTR uRva, PRTUINTPTR poffSeg)
380{
381 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
382 if (RT_SUCCESS(rc))
383 return pMod->pDbgVt->pfnRvaToSegOff(pMod, uRva, poffSeg);
384 return 0;
385}
386
387
388/** @interface_method_impl{RTDBGMODVTDBG,pfnClose} */
389static DECLCALLBACK(int) rtDbgModDeferredDbg_Close(PRTDBGMODINT pMod)
390{
391 rtDbgModDeferredReleaseInstanceData((PRTDBGMODDEFERRED)pMod->pvImgPriv);
392 return VINF_SUCCESS;
393}
394
395
396/** @interface_method_impl{RTDBGMODVTDBG,pfnTryOpen} */
397static DECLCALLBACK(int) rtDbgModDeferredDbg_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch)
398{
399 NOREF(enmArch);
400 return rtDbgModDeferredDoIt(pMod, true /*fForceRetry*/);
401}
402
403
404
405/** Virtual function table for the deferred debug info reader. */
406DECL_HIDDEN_CONST(RTDBGMODVTDBG) const g_rtDbgModVtDbgDeferred =
407{
408 /*.u32Magic = */ RTDBGMODVTDBG_MAGIC,
409 /*.fSupports = */ RT_DBGTYPE_MAP,
410 /*.pszName = */ "deferred",
411 /*.pfnTryOpen = */ rtDbgModDeferredDbg_TryOpen,
412 /*.pfnClose = */ rtDbgModDeferredDbg_Close,
413
414 /*.pfnRvaToSegOff = */ rtDbgModDeferredDbg_RvaToSegOff,
415 /*.pfnImageSize = */ rtDbgModDeferredDbg_ImageSize,
416
417 /*.pfnSegmentAdd = */ rtDbgModDeferredDbg_SegmentAdd,
418 /*.pfnSegmentCount = */ rtDbgModDeferredDbg_SegmentCount,
419 /*.pfnSegmentByIndex = */ rtDbgModDeferredDbg_SegmentByIndex,
420
421 /*.pfnSymbolAdd = */ rtDbgModDeferredDbg_SymbolAdd,
422 /*.pfnSymbolCount = */ rtDbgModDeferredDbg_SymbolCount,
423 /*.pfnSymbolByOrdinal = */ rtDbgModDeferredDbg_SymbolByOrdinal,
424 /*.pfnSymbolByName = */ rtDbgModDeferredDbg_SymbolByName,
425 /*.pfnSymbolByAddr = */ rtDbgModDeferredDbg_SymbolByAddr,
426
427 /*.pfnLineAdd = */ rtDbgModDeferredDbg_LineAdd,
428 /*.pfnLineCount = */ rtDbgModDeferredDbg_LineCount,
429 /*.pfnLineByOrdinal = */ rtDbgModDeferredDbg_LineByOrdinal,
430 /*.pfnLineByAddr = */ rtDbgModDeferredDbg_LineByAddr,
431
432 /*.u32EndMagic = */ RTDBGMODVTDBG_MAGIC
433};
434
435
436
437
438/*
439 *
440 * I m a g e M e t h o d s
441 * I m a g e M e t h o d s
442 * I m a g e M e t h o d s
443 *
444 */
445
446/** @interface_method_impl{RTDBGMODVTIMG,pfnQueryProp} */
447static DECLCALLBACK(int)
448rtDbgModDeferredImg_QueryProp(PRTDBGMODINT pMod, RTLDRPROP enmProp, void *pvBuf, size_t cbBuf, size_t *pcbRet)
449{
450 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
451 if (RT_SUCCESS(rc))
452 rc = pMod->pImgVt->pfnQueryProp(pMod, enmProp, pvBuf, cbBuf, pcbRet);
453 return rc;
454}
455
456
457/** @interface_method_impl{RTDBGMODVTIMG,pfnGetArch} */
458static DECLCALLBACK(RTLDRARCH) rtDbgModDeferredImg_GetArch(PRTDBGMODINT pMod)
459{
460 RTLDRARCH enmArch;
461 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
462 if (RT_SUCCESS(rc))
463 enmArch = pMod->pImgVt->pfnGetArch(pMod);
464 else
465 enmArch = RTLDRARCH_WHATEVER;
466 return enmArch;
467}
468
469
470/** @interface_method_impl{RTDBGMODVTIMG,pfnGetFormat} */
471static DECLCALLBACK(RTLDRFMT) rtDbgModDeferredImg_GetFormat(PRTDBGMODINT pMod)
472{
473 RTLDRFMT enmFmt;
474 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
475 if (RT_SUCCESS(rc))
476 enmFmt = pMod->pImgVt->pfnGetFormat(pMod);
477 else
478 enmFmt = RTLDRFMT_INVALID;
479 return enmFmt;
480}
481
482
483/** @interface_method_impl{RTDBGMODVTIMG,pfnReadAt} */
484static DECLCALLBACK(int) rtDbgModDeferredImg_ReadAt(PRTDBGMODINT pMod, uint32_t iDbgInfoHint, RTFOFF off, void *pvBuf, size_t cb)
485{
486 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
487 if (RT_SUCCESS(rc))
488 rc = pMod->pImgVt->pfnReadAt(pMod, iDbgInfoHint, off, pvBuf, cb);
489 return rc;
490}
491
492
493/** @interface_method_impl{RTDBGMODVTIMG,pfnUnmapPart} */
494static DECLCALLBACK(int) rtDbgModDeferredImg_UnmapPart(PRTDBGMODINT pMod, size_t cb, void const **ppvMap)
495{
496 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
497 if (RT_SUCCESS(rc))
498 rc = pMod->pImgVt->pfnUnmapPart(pMod, cb, ppvMap);
499 return rc;
500}
501
502
503/** @interface_method_impl{RTDBGMODVTIMG,pfnMapPart} */
504static DECLCALLBACK(int) rtDbgModDeferredImg_MapPart(PRTDBGMODINT pMod, uint32_t iDbgInfo, RTFOFF off, size_t cb, void const **ppvMap)
505{
506 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
507 if (RT_SUCCESS(rc))
508 rc = pMod->pImgVt->pfnMapPart(pMod, iDbgInfo, off, cb, ppvMap);
509 return rc;
510}
511
512
513/** @interface_method_impl{RTDBGMODVTIMG,pfnImageSize} */
514static DECLCALLBACK(RTUINTPTR) rtDbgModDeferredImg_ImageSize(PRTDBGMODINT pMod)
515{
516 PRTDBGMODDEFERRED pThis = (PRTDBGMODDEFERRED)pMod->pvImgPriv;
517 return pThis->cbImage;
518}
519
520
521/** @interface_method_impl{RTDBGMODVTIMG,pfnRvaToSegOffset} */
522static DECLCALLBACK(int) rtDbgModDeferredImg_RvaToSegOffset(PRTDBGMODINT pMod, RTLDRADDR Rva,
523 PRTDBGSEGIDX piSeg, PRTLDRADDR poffSeg)
524{
525 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
526 if (RT_SUCCESS(rc))
527 rc = pMod->pImgVt->pfnRvaToSegOffset(pMod, Rva, piSeg, poffSeg);
528 return rc;
529}
530
531
532/** @interface_method_impl{RTDBGMODVTIMG,pfnLinkAddressToSegOffset} */
533static DECLCALLBACK(int) rtDbgModDeferredImg_LinkAddressToSegOffset(PRTDBGMODINT pMod, RTLDRADDR LinkAddress,
534 PRTDBGSEGIDX piSeg, PRTLDRADDR poffSeg)
535{
536 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
537 if (RT_SUCCESS(rc))
538 rc = pMod->pImgVt->pfnLinkAddressToSegOffset(pMod, LinkAddress, piSeg, poffSeg);
539 return rc;
540}
541
542
543/** @interface_method_impl{RTDBGMODVTIMG,pfnEnumSymbols} */
544static DECLCALLBACK(int) rtDbgModDeferredImg_EnumSymbols(PRTDBGMODINT pMod, uint32_t fFlags, RTLDRADDR BaseAddress,
545 PFNRTLDRENUMSYMS pfnCallback, void *pvUser)
546{
547 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
548 if (RT_SUCCESS(rc))
549 rc = pMod->pImgVt->pfnEnumSymbols(pMod, fFlags, BaseAddress, pfnCallback, pvUser);
550 return rc;
551}
552
553
554/** @interface_method_impl{RTDBGMODVTIMG,pfnEnumSegments} */
555static DECLCALLBACK(int) rtDbgModDeferredImg_EnumSegments(PRTDBGMODINT pMod, PFNRTLDRENUMSEGS pfnCallback, void *pvUser)
556{
557 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
558 if (RT_SUCCESS(rc))
559 rc = pMod->pImgVt->pfnEnumSegments(pMod, pfnCallback, pvUser);
560 return rc;
561}
562
563
564/** @interface_method_impl{RTDBGMODVTIMG,pfnEnumDbgInfo} */
565static DECLCALLBACK(int) rtDbgModDeferredImg_EnumDbgInfo(PRTDBGMODINT pMod, PFNRTLDRENUMDBG pfnCallback, void *pvUser)
566{
567 int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
568 if (RT_SUCCESS(rc))
569 rc = pMod->pImgVt->pfnEnumDbgInfo(pMod, pfnCallback, pvUser);
570 return rc;
571}
572
573
574/** @interface_method_impl{RTDBGMODVTIMG,pfnClose} */
575static DECLCALLBACK(int) rtDbgModDeferredImg_Close(PRTDBGMODINT pMod)
576{
577 rtDbgModDeferredReleaseInstanceData((PRTDBGMODDEFERRED)pMod->pvImgPriv);
578 return VINF_SUCCESS;
579}
580
581
582/** @interface_method_impl{RTDBGMODVTIMG,pfnTryOpen} */
583static DECLCALLBACK(int) rtDbgModDeferredImg_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch)
584{
585 NOREF(enmArch);
586 return rtDbgModDeferredDoIt(pMod, true /*fForceRetry*/);
587}
588
589
590/** Virtual function table for the RTLdr based image reader. */
591DECL_HIDDEN_CONST(RTDBGMODVTIMG) const g_rtDbgModVtImgDeferred =
592{
593 /*.u32Magic = */ RTDBGMODVTIMG_MAGIC,
594 /*.fReserved = */ 0,
595 /*.pszName = */ "deferred",
596 /*.pfnTryOpen = */ rtDbgModDeferredImg_TryOpen,
597 /*.pfnClose = */ rtDbgModDeferredImg_Close,
598 /*.pfnEnumDbgInfo = */ rtDbgModDeferredImg_EnumDbgInfo,
599 /*.pfnEnumSegments = */ rtDbgModDeferredImg_EnumSegments,
600 /*.pfnEnumSymbols = */ rtDbgModDeferredImg_EnumSymbols,
601 /*.pfnGetLoadedSize = */ rtDbgModDeferredImg_ImageSize,
602 /*.pfnLinkAddressToSegOffset = */ rtDbgModDeferredImg_LinkAddressToSegOffset,
603 /*.pfnRvaToSegOffset = */ rtDbgModDeferredImg_RvaToSegOffset,
604 /*.pfnMapPart = */ rtDbgModDeferredImg_MapPart,
605 /*.pfnUnmapPart = */ rtDbgModDeferredImg_UnmapPart,
606 /*.pfnReadAt = */ rtDbgModDeferredImg_ReadAt,
607 /*.pfnGetFormat = */ rtDbgModDeferredImg_GetFormat,
608 /*.pfnGetArch = */ rtDbgModDeferredImg_GetArch,
609 /*.pfnQueryProp = */ rtDbgModDeferredImg_QueryProp,
610
611 /*.u32EndMagic = */ RTDBGMODVTIMG_MAGIC
612};
613
614
615/**
616 * Creates a deferred loading stub for both image and debug info.
617 *
618 * @returns IPRT status code.
619 * @param pDbgMod The debug module.
620 * @param pfnDeferred The callback that will try load the image and
621 * debug info.
622 * @param cbImage The size of the image.
623 * @param hDbgCfg The debug config handle. Can be NIL. A
624 * reference will be retained.
625 * @param cbDeferred The size of the deferred instance data, 0 if the
626 * default structure is good enough.
627 * @param ppDeferred Where to return the instance data. Can be NULL.
628 */
629DECLHIDDEN(int) rtDbgModDeferredCreate(PRTDBGMODINT pDbgMod, PFNRTDBGMODDEFERRED pfnDeferred, RTUINTPTR cbImage,
630 RTDBGCFG hDbgCfg, size_t cbDeferred, PRTDBGMODDEFERRED *ppDeferred)
631{
632 AssertReturn(!pDbgMod->pDbgVt, VERR_DBG_MOD_IPE);
633
634 if (cbDeferred < sizeof(RTDBGMODDEFERRED))
635 cbDeferred = sizeof(RTDBGMODDEFERRED);
636 PRTDBGMODDEFERRED pDeferred = (PRTDBGMODDEFERRED)RTMemAllocZ(cbDeferred);
637 if (!pDeferred)
638 return VERR_NO_MEMORY;
639
640 pDeferred->cbImage = cbImage;
641 pDeferred->cRefs = 1 + (pDbgMod->pImgVt == NULL);
642 if (hDbgCfg != NIL_RTDBGCFG)
643 RTDbgCfgRetain(hDbgCfg);
644 pDeferred->hDbgCfg = hDbgCfg;
645 pDeferred->pfnDeferred = pfnDeferred;
646
647 pDbgMod->pDbgVt = &g_rtDbgModVtDbgDeferred;
648 pDbgMod->pvDbgPriv = pDeferred;
649 if (!pDbgMod->pImgVt)
650 {
651 pDbgMod->pImgVt = &g_rtDbgModVtImgDeferred;
652 pDbgMod->pvImgPriv = pDeferred;
653 }
654 pDbgMod->fDeferred = true;
655 pDbgMod->fDeferredFailed = false;
656
657 if (ppDeferred)
658 *ppDeferred = pDeferred;
659 return VINF_SUCCESS;
660}
661
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