VirtualBox

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

Last change on this file was 98103, checked in by vboxsync, 17 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
RevLine 
[45997]1/* $Id: dbgmodexports.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
[45994]2/** @file
3 * IPRT - Debug Module Using Image Exports.
4 */
5
6/*
[98103]7 * Copyright (C) 2013-2023 Oracle and/or its affiliates.
[45994]8 *
[96407]9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
[45994]11 *
[96407]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 *
[45994]25 * The contents of this file may alternatively be used under the terms
26 * of the Common Development and Distribution License Version 1.0
[96407]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
[45994]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.
[96407]33 *
34 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
[45994]35 */
36
37
[57358]38/*********************************************************************************************************************************
39* Header Files *
40*********************************************************************************************************************************/
[46113]41#define LOG_GROUP RTLOGGROUP_DBG
[45994]42#include <iprt/dbg.h>
43#include "internal/iprt.h"
44
[46113]45#include <iprt/alloca.h>
[45994]46#include <iprt/assert.h>
47#include <iprt/err.h>
[46113]48#include <iprt/log.h>
[45994]49#include <iprt/string.h>
50#include "internal/dbgmod.h"
51
52
[57358]53/*********************************************************************************************************************************
54* Structures and Typedefs *
55*********************************************************************************************************************************/
[46113]56typedef struct RTDBGMODEXPORTARGS
57{
58 PRTDBGMODINT pDbgMod;
59 RTLDRADDR uImageBase;
[47290]60 RTLDRADDR uRvaNext;
61 uint32_t cSegs;
[46113]62} RTDBGMODEXPORTARGS;
63/** Pointer to an argument package. */
64typedef RTDBGMODEXPORTARGS *PRTDBGMODEXPORTARGS;
[45994]65
66
[57974]67/**
68 * @callback_method_impl{FNRTLDRENUMSYMS,
[57944]69 * Copies the symbols over into the container} */
[46113]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);
[45994]75
[46113]76 if (Value >= pArgs->uImageBase)
77 {
[62243]78 char szOrdinalNm[48];
[73760]79 if (!pszSymbol || *pszSymbol == '\0')
[62243]80 {
81 RTStrPrintf(szOrdinalNm, sizeof(szOrdinalNm), "Ordinal%u", uSymbol);
82 pszSymbol = szOrdinalNm;
83 }
84
[46113]85 int rc = RTDbgModSymbolAdd(pArgs->pDbgMod, pszSymbol, RTDBGSEGIDX_RVA, Value - pArgs->uImageBase,
86 0 /*cb*/, 0 /* fFlags */, NULL /*piOrdinal*/);
[51450]87 Log(("Symbol #%05u %#018RTptr %s [%Rrc]\n", uSymbol, Value, pszSymbol, rc)); NOREF(rc);
[46113]88 }
89 else
[51450]90 Log(("Symbol #%05u %#018RTptr %s [SKIPPED - INVALID ADDRESS]\n", uSymbol, Value, pszSymbol));
[46113]91 return VINF_SUCCESS;
92}
[45994]93
[46113]94
95/** @callback_method_impl{FNRTLDRENUMSEGS,
[57944]96 * Copies the segments over into the container} */
[46113]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",
[46266]101 pSeg->cchName, pSeg->pszName, (uint64_t)pSeg->LinkAddress, (uint64_t)pSeg->RVA, pSeg->cb));
[46113]102 NOREF(hLdrMod);
103
[47290]104 pArgs->cSegs++;
[46113]105
[46199]106 /* Add dummy segments for segments that doesn't get mapped. */
[49768]107 if ( pSeg->LinkAddress == NIL_RTLDRADDR
108 || pSeg->RVA == NIL_RTLDRADDR)
[46266]109 return RTDbgModSegmentAdd(pArgs->pDbgMod, 0, 0, pSeg->pszName, 0 /*fFlags*/, NULL);
[46199]110
[47290]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. */
[46113]125 RTLDRADDR cb = RT_MAX(pSeg->cb, pSeg->cbMapped);
[47290]126 pArgs->uRvaNext = uRva + cb;
127 return RTDbgModSegmentAdd(pArgs->pDbgMod, uRva, cb, pSeg->pszName, 0 /*fFlags*/, NULL);
[46113]128}
129
130
[45994]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 */
[46113]151 int rc = rtDbgModContainerCreate(pDbgMod, 0);
[45994]152 if (RT_FAILURE(rc))
153 return rc;
[46113]154 pDbgMod->fExports = true;
[45994]155
156 /*
[46113]157 * Copy the segments and symbols.
[45994]158 */
[46113]159 RTDBGMODEXPORTARGS Args;
160 Args.pDbgMod = pDbgMod;
161 Args.uImageBase = 0;
[47290]162 Args.uRvaNext = 0;
163 Args.cSegs = 0;
[46113]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));
[45994]175
[46113]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;
[45994]182}
183
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use