VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/dbg/dbgmodldr.cpp

Last change on this file was 106061, checked in by vboxsync, 3 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: 10.3 KB
Line 
1/* $Id: dbgmodldr.cpp 106061 2024-09-16 14:03:52Z vboxsync $ */
2/** @file
3 * IPRT - Debug Module Image Interpretation by RTLdr.
4 */
5
6/*
7 * Copyright (C) 2011-2024 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/assert.h>
45#include <iprt/errcore.h>
46#include <iprt/file.h>
47#include <iprt/ldr.h>
48#include <iprt/mem.h>
49#include <iprt/param.h>
50#include <iprt/path.h>
51#include <iprt/string.h>
52#include "internal/dbgmod.h"
53#include "internal/ldr.h"
54#include "internal/magics.h"
55
56
57/*********************************************************************************************************************************
58* Structures and Typedefs *
59*********************************************************************************************************************************/
60/**
61 * The instance data of the RTLdr based image reader.
62 */
63typedef struct RTDBGMODLDR
64{
65 /** Magic value (RTDBGMODLDR_MAGIC). */
66 uint32_t u32Magic;
67 /** The loader handle. */
68 RTLDRMOD hLdrMod;
69} RTDBGMODLDR;
70/** Pointer to instance data NM map reader. */
71typedef RTDBGMODLDR *PRTDBGMODLDR;
72
73
74
75/** @interface_method_impl{RTDBGMODVTDBG,pfnUnwindFrame} */
76static DECLCALLBACK(int) rtDbgModLdr_UnwindFrame(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off, PRTDBGUNWINDSTATE pState)
77{
78 PRTDBGMODLDR pThis = (PRTDBGMODLDR)pMod->pvImgPriv;
79 Assert(pThis->u32Magic == RTDBGMODLDR_MAGIC);
80 return RTLdrUnwindFrame(pThis->hLdrMod, NULL, iSeg, off, pState);
81}
82
83
84/** @interface_method_impl{RTDBGMODVTIMG,pfnQueryProp} */
85static DECLCALLBACK(int) rtDbgModLdr_QueryProp(PRTDBGMODINT pMod, RTLDRPROP enmProp, void *pvBuf, size_t cbBuf, size_t *pcbRet)
86{
87 PRTDBGMODLDR pThis = (PRTDBGMODLDR)pMod->pvImgPriv;
88 Assert(pThis->u32Magic == RTDBGMODLDR_MAGIC);
89 return RTLdrQueryPropEx(pThis->hLdrMod, enmProp, NULL /*pvBits*/, pvBuf, cbBuf, pcbRet);
90}
91
92
93/** @interface_method_impl{RTDBGMODVTIMG,pfnGetArch} */
94static DECLCALLBACK(RTLDRARCH) rtDbgModLdr_GetArch(PRTDBGMODINT pMod)
95{
96 PRTDBGMODLDR pThis = (PRTDBGMODLDR)pMod->pvImgPriv;
97 Assert(pThis->u32Magic == RTDBGMODLDR_MAGIC);
98 return RTLdrGetArch(pThis->hLdrMod);
99}
100
101
102/** @interface_method_impl{RTDBGMODVTIMG,pfnGetFormat} */
103static DECLCALLBACK(RTLDRFMT) rtDbgModLdr_GetFormat(PRTDBGMODINT pMod)
104{
105 PRTDBGMODLDR pThis = (PRTDBGMODLDR)pMod->pvImgPriv;
106 Assert(pThis->u32Magic == RTDBGMODLDR_MAGIC);
107 return RTLdrGetFormat(pThis->hLdrMod);
108}
109
110
111/** @interface_method_impl{RTDBGMODVTIMG,pfnReadAt} */
112static DECLCALLBACK(int) rtDbgModLdr_ReadAt(PRTDBGMODINT pMod, uint32_t iDbgInfoHint, RTFOFF off, void *pvBuf, size_t cb)
113{
114 PRTDBGMODLDR pThis = (PRTDBGMODLDR)pMod->pvImgPriv;
115 Assert(pThis->u32Magic == RTDBGMODLDR_MAGIC);
116 RT_NOREF_PV(iDbgInfoHint);
117 return rtLdrReadAt(pThis->hLdrMod, pvBuf, UINT32_MAX /** @todo iDbgInfo*/, off, cb);
118}
119
120
121/** @interface_method_impl{RTDBGMODVTIMG,pfnUnmapPart} */
122static DECLCALLBACK(int) rtDbgModLdr_UnmapPart(PRTDBGMODINT pMod, size_t cb, void const **ppvMap)
123{
124 Assert(((PRTDBGMODLDR)pMod->pvImgPriv)->u32Magic == RTDBGMODLDR_MAGIC);
125 NOREF(pMod); NOREF(cb);
126 RTMemFree((void *)*ppvMap);
127 *ppvMap = NULL;
128 return VINF_SUCCESS;
129}
130
131
132/** @interface_method_impl{RTDBGMODVTIMG,pfnMapPart} */
133static DECLCALLBACK(int) rtDbgModLdr_MapPart(PRTDBGMODINT pMod, uint32_t iDbgInfo, RTFOFF off, size_t cb, void const **ppvMap)
134{
135 PRTDBGMODLDR pThis = (PRTDBGMODLDR)pMod->pvImgPriv;
136 Assert(pThis->u32Magic == RTDBGMODLDR_MAGIC);
137
138 void *pvMap = RTMemAlloc(cb);
139 if (!pvMap)
140 return VERR_NO_MEMORY;
141
142 int rc = rtLdrReadAt(pThis->hLdrMod, pvMap, iDbgInfo, off, cb);
143 if (RT_SUCCESS(rc))
144 *ppvMap = pvMap;
145 else
146 {
147 RTMemFree(pvMap);
148 *ppvMap = NULL;
149 }
150 return rc;
151}
152
153
154/** @interface_method_impl{RTDBGMODVTIMG,pfnImageSize} */
155static DECLCALLBACK(RTUINTPTR) rtDbgModLdr_ImageSize(PRTDBGMODINT pMod)
156{
157 PRTDBGMODLDR pThis = (PRTDBGMODLDR)pMod->pvImgPriv;
158 Assert(pThis->u32Magic == RTDBGMODLDR_MAGIC);
159 return RTLdrSize(pThis->hLdrMod);
160}
161
162
163/** @interface_method_impl{RTDBGMODVTIMG,pfnRvaToSegOffset} */
164static DECLCALLBACK(int) rtDbgModLdr_RvaToSegOffset(PRTDBGMODINT pMod, RTLDRADDR Rva, PRTDBGSEGIDX piSeg, PRTLDRADDR poffSeg)
165{
166 PRTDBGMODLDR pThis = (PRTDBGMODLDR)pMod->pvImgPriv;
167 Assert(pThis->u32Magic == RTDBGMODLDR_MAGIC);
168 return RTLdrRvaToSegOffset(pThis->hLdrMod, Rva, piSeg, poffSeg);
169}
170
171
172/** @interface_method_impl{RTDBGMODVTIMG,pfnLinkAddressToSegOffset} */
173static DECLCALLBACK(int) rtDbgModLdr_LinkAddressToSegOffset(PRTDBGMODINT pMod, RTLDRADDR LinkAddress,
174 PRTDBGSEGIDX piSeg, PRTLDRADDR poffSeg)
175{
176 PRTDBGMODLDR pThis = (PRTDBGMODLDR)pMod->pvImgPriv;
177 Assert(pThis->u32Magic == RTDBGMODLDR_MAGIC);
178 return RTLdrLinkAddressToSegOffset(pThis->hLdrMod, LinkAddress, piSeg, poffSeg);
179}
180
181
182/** @interface_method_impl{RTDBGMODVTIMG,pfnEnumSymbols} */
183static DECLCALLBACK(int) rtDbgModLdr_EnumSymbols(PRTDBGMODINT pMod, uint32_t fFlags, RTLDRADDR BaseAddress,
184 PFNRTLDRENUMSYMS pfnCallback, void *pvUser)
185{
186 PRTDBGMODLDR pThis = (PRTDBGMODLDR)pMod->pvImgPriv;
187 Assert(pThis->u32Magic == RTDBGMODLDR_MAGIC);
188 return RTLdrEnumSymbols(pThis->hLdrMod, fFlags, NULL /*pvBits*/, BaseAddress, pfnCallback, pvUser);
189}
190
191
192/** @interface_method_impl{RTDBGMODVTIMG,pfnEnumSegments} */
193static DECLCALLBACK(int) rtDbgModLdr_EnumSegments(PRTDBGMODINT pMod, PFNRTLDRENUMSEGS pfnCallback, void *pvUser)
194{
195 PRTDBGMODLDR pThis = (PRTDBGMODLDR)pMod->pvImgPriv;
196 Assert(pThis->u32Magic == RTDBGMODLDR_MAGIC);
197 return RTLdrEnumSegments(pThis->hLdrMod, pfnCallback, pvUser);
198}
199
200
201/** @interface_method_impl{RTDBGMODVTIMG,pfnEnumDbgInfo} */
202static DECLCALLBACK(int) rtDbgModLdr_EnumDbgInfo(PRTDBGMODINT pMod, PFNRTLDRENUMDBG pfnCallback, void *pvUser)
203{
204 PRTDBGMODLDR pThis = (PRTDBGMODLDR)pMod->pvImgPriv;
205 Assert(pThis->u32Magic == RTDBGMODLDR_MAGIC);
206 return RTLdrEnumDbgInfo(pThis->hLdrMod, NULL, pfnCallback, pvUser);
207}
208
209
210/** @interface_method_impl{RTDBGMODVTIMG,pfnClose} */
211static DECLCALLBACK(int) rtDbgModLdr_Close(PRTDBGMODINT pMod)
212{
213 PRTDBGMODLDR pThis = (PRTDBGMODLDR)pMod->pvImgPriv;
214 AssertPtr(pThis);
215 Assert(pThis->u32Magic == RTDBGMODLDR_MAGIC);
216
217 int rc = RTLdrClose(pThis->hLdrMod); AssertRC(rc);
218 pThis->hLdrMod = NIL_RTLDRMOD;
219 pThis->u32Magic = RTDBGMODLDR_MAGIC_DEAD;
220
221 RTMemFree(pThis);
222
223 return VINF_SUCCESS;
224}
225
226
227/** @interface_method_impl{RTDBGMODVTIMG,pfnTryOpen} */
228static DECLCALLBACK(int) rtDbgModLdr_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch, uint32_t fLdrFlags)
229{
230 RTLDRMOD hLdrMod;
231 int rc = RTLdrOpen(pMod->pszImgFile, RTLDR_O_FOR_DEBUG | fLdrFlags, enmArch, &hLdrMod);
232 if (RT_SUCCESS(rc))
233 {
234 rc = rtDbgModLdrOpenFromHandle(pMod, hLdrMod);
235 if (RT_FAILURE(rc))
236 RTLdrClose(hLdrMod);
237 }
238 return rc;
239}
240
241
242/** Virtual function table for the RTLdr based image reader. */
243DECL_HIDDEN_CONST(RTDBGMODVTIMG) const g_rtDbgModVtImgLdr =
244{
245 /*.u32Magic = */ RTDBGMODVTIMG_MAGIC,
246 /*.fReserved = */ 0,
247 /*.pszName = */ "RTLdr",
248 /*.pfnTryOpen = */ rtDbgModLdr_TryOpen,
249 /*.pfnClose = */ rtDbgModLdr_Close,
250 /*.pfnEnumDbgInfo = */ rtDbgModLdr_EnumDbgInfo,
251 /*.pfnEnumSegments = */ rtDbgModLdr_EnumSegments,
252 /*.pfnEnumSymbols = */ rtDbgModLdr_EnumSymbols,
253 /*.pfnImageSize = */ rtDbgModLdr_ImageSize,
254 /*.pfnLinkAddressToSegOffset = */ rtDbgModLdr_LinkAddressToSegOffset,
255 /*.pfnRvaToSegOffset= */ rtDbgModLdr_RvaToSegOffset,
256 /*.pfnMapPart = */ rtDbgModLdr_MapPart,
257 /*.pfnUnmapPart = */ rtDbgModLdr_UnmapPart,
258 /*.pfnReadAt = */ rtDbgModLdr_ReadAt,
259 /*.pfnGetFormat = */ rtDbgModLdr_GetFormat,
260 /*.pfnGetArch = */ rtDbgModLdr_GetArch,
261 /*.pfnQueryProp = */ rtDbgModLdr_QueryProp,
262 /*.pfnUnwindFrame = */ rtDbgModLdr_UnwindFrame,
263
264 /*.u32EndMagic = */ RTDBGMODVTIMG_MAGIC
265};
266
267
268/**
269 * Open PE-image trick.
270 *
271 * @returns IPRT status code
272 * @param pDbgMod The debug module instance.
273 * @param hLdrMod The module to open a image debug backend for.
274 */
275DECLHIDDEN(int) rtDbgModLdrOpenFromHandle(PRTDBGMODINT pDbgMod, RTLDRMOD hLdrMod)
276{
277 PRTDBGMODLDR pThis = (PRTDBGMODLDR)RTMemAllocZ(sizeof(RTDBGMODLDR));
278 if (!pThis)
279 return VERR_NO_MEMORY;
280
281 pThis->u32Magic = RTDBGMODLDR_MAGIC;
282 pThis->hLdrMod = hLdrMod;
283 pDbgMod->pvImgPriv = pThis;
284 return VINF_SUCCESS;
285}
286
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