VirtualBox

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

Last change on this file since 1507 was 1, checked in by vboxsync, 55 years ago

import

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