VirtualBox

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

Last change on this file since 98103 was 98103, checked in by vboxsync, 23 months ago

Copyright year updates by scm.

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