VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstLdr-3.cpp@ 23299

Last change on this file since 23299 was 18357, checked in by vboxsync, 16 years ago

tstLdr-3: cpu mode.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 8.6 KB
Line 
1/* $Id: tstLdr-3.cpp 18357 2009-03-26 23:02:07Z vboxsync $ */
2/** @file
3 * IPRT - Testcase for parts of RTLdr*, manual inspection.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
27 * Clara, CA 95054 USA or visit http://www.sun.com if you need
28 * additional information or have any questions.
29 */
30
31
32/*******************************************************************************
33* Header Files *
34*******************************************************************************/
35#include <iprt/ldr.h>
36#include <iprt/alloc.h>
37#include <iprt/stream.h>
38#include <iprt/assert.h>
39#include <iprt/initterm.h>
40#include <iprt/err.h>
41#include <iprt/string.h>
42#include <VBox/dis.h>
43
44
45static bool MyDisBlock(PDISCPUSTATE pCpu, RTHCUINTPTR pvCodeBlock, int32_t cbMax, RTUINTPTR off, RTUINTPTR Addr)
46{
47 int32_t i = 0;
48 while (i < cbMax)
49 {
50 char szOutput[256];
51 uint32_t cbInstr;
52 if (RT_FAILURE(DISInstr(pCpu, pvCodeBlock + i, off, &cbInstr, szOutput)))
53 return false;
54
55 RTPrintf("%s", szOutput);
56 if (pvCodeBlock + i + off == Addr)
57 RTPrintf("^^^^^^^^\n");
58
59 /* next */
60 i += cbInstr;
61 }
62 return true;
63}
64
65
66
67/**
68 * Resolve an external symbol during RTLdrGetBits().
69 *
70 * @returns iprt status code.
71 * @param hLdrMod The loader module handle.
72 * @param pszModule Module name.
73 * @param pszSymbol Symbol name, NULL if uSymbol should be used.
74 * @param uSymbol Symbol ordinal, ~0 if pszSymbol should be used.
75 * @param pValue Where to store the symbol value (address).
76 * @param pvUser User argument.
77 */
78static DECLCALLBACK(int) testGetImport(RTLDRMOD hLdrMod, const char *pszModule, const char *pszSymbol, unsigned uSymbol, RTUINTPTR *pValue, void *pvUser)
79{
80 RTUINTPTR BaseAddr = *(PCRTUINTPTR)pvUser;
81 *pValue = BaseAddr + UINT32_C(0x604020f0);
82 return VINF_SUCCESS;
83}
84
85
86/**
87 * Enumeration callback function used by RTLdrEnumSymbols().
88 *
89 * @returns iprt status code. Failure will stop the enumeration.
90 * @param hLdrMod The loader module handle.
91 * @param pszSymbol Symbol name. NULL if ordinal only.
92 * @param uSymbol Symbol ordinal, ~0 if not used.
93 * @param Value Symbol value.
94 * @param pvUser The user argument specified to RTLdrEnumSymbols().
95 */
96static DECLCALLBACK(int) testEnumSymbol1(RTLDRMOD hLdrMod, const char *pszSymbol, unsigned uSymbol, RTUINTPTR Value, void *pvUser)
97{
98 RTPrintf(" %RTptr %s (%d)\n", Value, pszSymbol, uSymbol);
99 return VINF_SUCCESS;
100}
101
102/**
103 * Current nearest symbol.
104 */
105typedef struct TESTNEARSYM
106{
107 RTUINTPTR Addr;
108 struct TESTSYM
109 {
110 RTUINTPTR Value;
111 unsigned uSymbol;
112 char szName[512];
113 } aSyms[2];
114} TESTNEARSYM, *PTESTNEARSYM;
115
116/**
117 * Enumeration callback function used by RTLdrEnumSymbols().
118 *
119 * @returns iprt status code. Failure will stop the enumeration.
120 * @param hLdrMod The loader module handle.
121 * @param pszSymbol Symbol name. NULL if ordinal only.
122 * @param uSymbol Symbol ordinal, ~0 if not used.
123 * @param Value Symbol value.
124 * @param pvUser The user argument specified to RTLdrEnumSymbols().
125 */
126static DECLCALLBACK(int) testEnumSymbol2(RTLDRMOD hLdrMod, const char *pszSymbol, unsigned uSymbol, RTUINTPTR Value, void *pvUser)
127{
128 PTESTNEARSYM pSym = (PTESTNEARSYM)pvUser;
129
130 /* less or equal */
131 if ( Value <= pSym->Addr
132 && ( Value > pSym->aSyms[0].Value
133 || ( Value == pSym->aSyms[0].Value
134 && !pSym->aSyms[0].szName[0]
135 && pszSymbol
136 && *pszSymbol
137 )
138 )
139 )
140 {
141 pSym->aSyms[0].Value = Value;
142 pSym->aSyms[0].uSymbol = uSymbol;
143 pSym->aSyms[0].szName[0] = '\0';
144 if (pszSymbol)
145 strncat(pSym->aSyms[0].szName, pszSymbol, sizeof(pSym->aSyms[0].szName));
146 }
147
148 /* above */
149 if ( Value > pSym->Addr
150 && ( Value < pSym->aSyms[1].Value
151 || ( Value == pSym->aSyms[1].Value
152 && !pSym->aSyms[1].szName[1]
153 && pszSymbol
154 && *pszSymbol
155 )
156 )
157 )
158 {
159 pSym->aSyms[1].Value = Value;
160 pSym->aSyms[1].uSymbol = uSymbol;
161 pSym->aSyms[1].szName[0] = '\0';
162 if (pszSymbol)
163 strncat(pSym->aSyms[1].szName, pszSymbol, sizeof(pSym->aSyms[1].szName));
164 }
165
166 return VINF_SUCCESS;
167}
168
169
170int main(int argc, char **argv)
171{
172 RTR3Init();
173
174 int rcRet = 0;
175 if (argc <= 2)
176 {
177 RTPrintf("usage: %s <load-addr> <module> [addr1 []]\n", argv[0]);
178 return 1;
179 }
180
181 /*
182 * Load the module.
183 */
184 RTUINTPTR LoadAddr = (RTUINTPTR)RTStrToUInt64(argv[1]);
185 RTLDRMOD hLdrMod;
186 int rc = RTLdrOpen(argv[2], 0, RTLDRARCH_WHATEVER, &hLdrMod);
187 if (RT_FAILURE(rc))
188 {
189 RTPrintf("tstLdr-3: Failed to open '%s': %Rra\n", argv[2], rc);
190 return 1;
191 }
192
193 void *pvBits = RTMemAlloc(RTLdrSize(hLdrMod));
194 rc = RTLdrGetBits(hLdrMod, pvBits, LoadAddr, testGetImport, &LoadAddr);
195 if (RT_SUCCESS(rc))
196 {
197 if (argc > 3)
198 {
199 for (int i = 3; i < argc; i++)
200 {
201 TESTNEARSYM NearSym = {0};
202 NearSym.Addr = (RTUINTPTR)RTStrToUInt64(argv[i]);
203 NearSym.aSyms[1].Value = ~(RTUINTPTR)0;
204 rc = RTLdrEnumSymbols(hLdrMod, RTLDR_ENUM_SYMBOL_FLAGS_ALL, pvBits, LoadAddr, testEnumSymbol2, &NearSym);
205 if (RT_SUCCESS(rc))
206 {
207 RTPrintf("tstLdr-3: Addr=%RTptr\n"
208 "%RTptr %s (%d) - %RTptr %s (%d)\n",
209 NearSym.Addr,
210 NearSym.aSyms[0].Value, NearSym.aSyms[0].szName, NearSym.aSyms[0].uSymbol,
211 NearSym.aSyms[1].Value, NearSym.aSyms[1].szName, NearSym.aSyms[1].uSymbol);
212 if (NearSym.Addr - NearSym.aSyms[0].Value < 0x10000)
213 {
214 DISCPUSTATE Cpu;
215 memset(&Cpu, 0, sizeof(Cpu));
216#ifdef RT_ARCH_X86 /** @todo select according to the module type. */
217 Cpu.mode = CPUMODE_32BIT;
218#else
219 Cpu.mode = CPUMODE_64BIT;
220#endif
221 uint8_t *pbCode = (uint8_t *)pvBits + (NearSym.aSyms[0].Value - LoadAddr);
222 MyDisBlock(&Cpu, (uintptr_t)pbCode,
223 RT_MAX(NearSym.aSyms[1].Value - NearSym.aSyms[0].Value, 0x20000),
224 NearSym.aSyms[0].Value - (RTUINTPTR)pbCode,
225 NearSym.Addr);
226 }
227 }
228 else
229 {
230 RTPrintf("tstLdr-3: Failed to enumerate symbols: %Rra\n", rc);
231 rcRet++;
232 }
233 }
234 }
235 else
236 {
237 /*
238 * Enumerate symbols.
239 */
240 rc = RTLdrEnumSymbols(hLdrMod, RTLDR_ENUM_SYMBOL_FLAGS_ALL, pvBits, LoadAddr, testEnumSymbol1, NULL);
241 if (RT_FAILURE(rc))
242 {
243 RTPrintf("tstLdr-3: Failed to enumerate symbols: %Rra\n", rc);
244 rcRet++;
245 }
246 }
247 }
248 else
249 {
250 RTPrintf("tstLdr-3: Failed to get bits for '%s' at %RTptr: %Rra\n", argv[2], LoadAddr, rc);
251 rcRet++;
252 }
253 RTMemFree(pvBits);
254 RTLdrClose(hLdrMod);
255
256 /*
257 * Test result summary.
258 */
259 if (!rcRet)
260 RTPrintf("tstLdr-3: SUCCESS\n");
261 else
262 RTPrintf("tstLdr-3: FAILURE - %d errors\n", rcRet);
263 return !!rcRet;
264}
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