VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/dbg/dbgmodexports.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: 6.8 KB
Line 
1/* $Id: dbgmodexports.cpp 106061 2024-09-16 14:03:52Z vboxsync $ */
2/** @file
3 * IPRT - Debug Module Using Image Exports.
4 */
5
6/*
7 * Copyright (C) 2013-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#define LOG_GROUP RTLOGGROUP_DBG
42#include <iprt/dbg.h>
43#include "internal/iprt.h"
44
45#include <iprt/alloca.h>
46#include <iprt/assert.h>
47#include <iprt/err.h>
48#include <iprt/log.h>
49#include <iprt/string.h>
50#include "internal/dbgmod.h"
51
52
53/*********************************************************************************************************************************
54* Structures and Typedefs *
55*********************************************************************************************************************************/
56typedef struct RTDBGMODEXPORTARGS
57{
58 PRTDBGMODINT pDbgMod;
59 RTLDRADDR uImageBase;
60 RTLDRADDR uRvaNext;
61 uint32_t cSegs;
62} RTDBGMODEXPORTARGS;
63/** Pointer to an argument package. */
64typedef RTDBGMODEXPORTARGS *PRTDBGMODEXPORTARGS;
65
66
67/**
68 * @callback_method_impl{FNRTLDRENUMSYMS,
69 * Copies the symbols over into the container} */
70static DECLCALLBACK(int) rtDbgModExportsAddSymbolCallback(RTLDRMOD hLdrMod, const char *pszSymbol, unsigned uSymbol,
71 RTLDRADDR Value, void *pvUser)
72{
73 PRTDBGMODEXPORTARGS pArgs = (PRTDBGMODEXPORTARGS)pvUser;
74 NOREF(hLdrMod);
75
76 if (Value >= pArgs->uImageBase)
77 {
78 char szOrdinalNm[48];
79 if (!pszSymbol || *pszSymbol == '\0')
80 {
81 RTStrPrintf(szOrdinalNm, sizeof(szOrdinalNm), "Ordinal%u", uSymbol);
82 pszSymbol = szOrdinalNm;
83 }
84
85 int rc = RTDbgModSymbolAdd(pArgs->pDbgMod, pszSymbol, RTDBGSEGIDX_RVA, Value - pArgs->uImageBase,
86 0 /*cb*/, 0 /* fFlags */, NULL /*piOrdinal*/);
87 Log(("Symbol #%05u %#018RTptr %s [%Rrc]\n", uSymbol, Value, pszSymbol, rc)); NOREF(rc);
88 }
89 else
90 Log(("Symbol #%05u %#018RTptr %s [SKIPPED - INVALID ADDRESS]\n", uSymbol, Value, pszSymbol));
91 return VINF_SUCCESS;
92}
93
94
95/** @callback_method_impl{FNRTLDRENUMSEGS,
96 * Copies the segments over into the container} */
97static DECLCALLBACK(int) rtDbgModExportsAddSegmentsCallback(RTLDRMOD hLdrMod, PCRTLDRSEG pSeg, void *pvUser)
98{
99 PRTDBGMODEXPORTARGS pArgs = (PRTDBGMODEXPORTARGS)pvUser;
100 Log(("Segment %.*s: LinkAddress=%#llx RVA=%#llx cb=%#llx\n",
101 pSeg->cchName, pSeg->pszName, (uint64_t)pSeg->LinkAddress, (uint64_t)pSeg->RVA, pSeg->cb));
102 NOREF(hLdrMod);
103
104 pArgs->cSegs++;
105
106 /* Add dummy segments for segments that doesn't get mapped. */
107 if ( pSeg->LinkAddress == NIL_RTLDRADDR
108 || pSeg->RVA == NIL_RTLDRADDR)
109 return RTDbgModSegmentAdd(pArgs->pDbgMod, 0, 0, pSeg->pszName, 0 /*fFlags*/, NULL);
110
111 RTLDRADDR uRva = pSeg->RVA;
112#if 0 /* Kluge for the .data..percpu segment in 64-bit linux kernels and similar. (Moved to ELF.) */
113 if (uRva < pArgs->uRvaNext)
114 uRva = RT_ALIGN_T(pArgs->uRvaNext, pSeg->Alignment, RTLDRADDR);
115#endif
116
117 /* Find the best base address for the module. */
118 if ( ( !pArgs->uImageBase
119 || pArgs->uImageBase > pSeg->LinkAddress)
120 && ( pSeg->LinkAddress != 0 /* .data..percpu again. */
121 || pArgs->cSegs == 1))
122 pArgs->uImageBase = pSeg->LinkAddress;
123
124 /* Add it. */
125 RTLDRADDR cb = RT_MAX(pSeg->cb, pSeg->cbMapped);
126 pArgs->uRvaNext = uRva + cb;
127 return RTDbgModSegmentAdd(pArgs->pDbgMod, uRva, cb, pSeg->pszName, 0 /*fFlags*/, NULL);
128}
129
130
131/**
132 * Creates the debug info side of affairs based on exports and segments found in
133 * the image part.
134 *
135 * The image part must be successfully initialized prior to the call, while the
136 * debug bits must not be present of course.
137 *
138 * @returns IPRT status code
139 * @param pDbgMod The debug module structure.
140 */
141DECLHIDDEN(int) rtDbgModCreateForExports(PRTDBGMODINT pDbgMod)
142{
143 AssertReturn(!pDbgMod->pDbgVt, VERR_DBG_MOD_IPE);
144 AssertReturn(pDbgMod->pImgVt, VERR_DBG_MOD_IPE);
145 RTUINTPTR cbImage = pDbgMod->pImgVt->pfnImageSize(pDbgMod);
146 AssertReturn(cbImage > 0, VERR_DBG_MOD_IPE);
147
148 /*
149 * We simply use a container type for this work.
150 */
151 int rc = rtDbgModContainerCreate(pDbgMod, 0);
152 if (RT_FAILURE(rc))
153 return rc;
154 pDbgMod->fExports = true;
155
156 /*
157 * Copy the segments and symbols.
158 */
159 RTDBGMODEXPORTARGS Args;
160 Args.pDbgMod = pDbgMod;
161 Args.uImageBase = 0;
162 Args.uRvaNext = 0;
163 Args.cSegs = 0;
164 rc = pDbgMod->pImgVt->pfnEnumSegments(pDbgMod, rtDbgModExportsAddSegmentsCallback, &Args);
165 if (RT_SUCCESS(rc))
166 {
167 rc = pDbgMod->pImgVt->pfnEnumSymbols(pDbgMod, RTLDR_ENUM_SYMBOL_FLAGS_ALL | RTLDR_ENUM_SYMBOL_FLAGS_NO_FWD,
168 Args.uImageBase ? Args.uImageBase : 0x10000,
169 rtDbgModExportsAddSymbolCallback, &Args);
170 if (RT_FAILURE(rc))
171 Log(("rtDbgModCreateForExports: Error during symbol enum: %Rrc\n", rc));
172 }
173 else
174 Log(("rtDbgModCreateForExports: Error during segment enum: %Rrc\n", rc));
175
176 /* This won't fail. */
177 if (RT_SUCCESS(rc))
178 rc = VINF_SUCCESS;
179 else
180 rc = -rc; /* Change it into a warning. */
181 return rc;
182}
183
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