VirtualBox

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

Last change on this file since 4071 was 4071, checked in by vboxsync, 17 years ago

Biggest check-in ever. New source code headers for all (C) innotek files.

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