VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstLdr-4.cpp@ 65358

最後變更 在這個檔案從65358是 65358,由 vboxsync 提交於 8 年 前

tstLdr-4: ELF import SomeImportFunction, don't forget to handle it.

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id Revision
檔案大小: 9.2 KB
 
1/* $Id: tstLdr-4.cpp 65358 2017-01-18 10:49:39Z vboxsync $ */
2/** @file
3 * IPRT - Testcase for RTLdrOpen using ldrLdrObjR0.r0.
4 */
5
6/*
7 * Copyright (C) 2006-2016 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.alldomusa.eu.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
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include <iprt/ldr.h>
32#include <iprt/alloc.h>
33#include <iprt/log.h>
34#include <iprt/stream.h>
35#include <iprt/assert.h>
36#include <iprt/param.h>
37#include <iprt/path.h>
38#include <iprt/initterm.h>
39#include <iprt/err.h>
40#include <iprt/string.h>
41
42
43extern "C" DECLEXPORT(int) DisasmTest1(void);
44
45
46/**
47 * Resolve an external symbol during RTLdrGetBits().
48 *
49 * @returns iprt status code.
50 * @param hLdrMod The loader module handle.
51 * @param pszModule Module name.
52 * @param pszSymbol Symbol name, NULL if uSymbol should be used.
53 * @param uSymbol Symbol ordinal, ~0 if pszSymbol should be used.
54 * @param pValue Where to store the symbol value (address).
55 * @param pvUser User argument.
56 */
57static DECLCALLBACK(int) testGetImport(RTLDRMOD hLdrMod, const char *pszModule, const char *pszSymbol, unsigned uSymbol, RTUINTPTR *pValue, void *pvUser)
58{
59 RT_NOREF4(hLdrMod, pszModule, uSymbol, pvUser);
60 if ( !strcmp(pszSymbol, "RTAssertMsg1Weak") || !strcmp(pszSymbol, "_RTAssertMsg1Weak"))
61 *pValue = (uintptr_t)RTAssertMsg1Weak;
62 else if (!strcmp(pszSymbol, "RTAssertMsg2Weak") || !strcmp(pszSymbol, "_RTAssertMsg2Weak"))
63 *pValue = (uintptr_t)RTAssertMsg1Weak;
64 else if (!strcmp(pszSymbol, "RTAssertMsg1") || !strcmp(pszSymbol, "_RTAssertMsg1"))
65 *pValue = (uintptr_t)RTAssertMsg1;
66 else if (!strcmp(pszSymbol, "RTAssertMsg2") || !strcmp(pszSymbol, "_RTAssertMsg2"))
67 *pValue = (uintptr_t)RTAssertMsg2;
68 else if (!strcmp(pszSymbol, "RTAssertMsg2V") || !strcmp(pszSymbol, "_RTAssertMsg2V"))
69 *pValue = (uintptr_t)RTAssertMsg2V;
70 else if (!strcmp(pszSymbol, "RTAssertMayPanic") || !strcmp(pszSymbol, "_RTAssertMayPanic"))
71 *pValue = (uintptr_t)RTAssertMayPanic;
72 else if (!strcmp(pszSymbol, "RTLogDefaultInstanceEx") || !strcmp(pszSymbol, "RTLogDefaultInstanceEx"))
73 *pValue = (uintptr_t)RTLogDefaultInstanceEx;
74 else if (!strcmp(pszSymbol, "RTLogLoggerExV") || !strcmp(pszSymbol, "_RTLogLoggerExV"))
75 *pValue = (uintptr_t)RTLogLoggerExV;
76 else if (!strcmp(pszSymbol, "RTLogPrintfV") || !strcmp(pszSymbol, "_RTLogPrintfV"))
77 *pValue = (uintptr_t)RTLogPrintfV;
78 else if (!strcmp(pszSymbol, "RTR0AssertPanicSystem")|| !strcmp(pszSymbol, "_RTR0AssertPanicSystem"))
79 *pValue = (uintptr_t)0;
80 else if (!strcmp(pszSymbol, "MyPrintf") || !strcmp(pszSymbol, "_MyPrintf"))
81 *pValue = (uintptr_t)RTPrintf;
82 else if (!strcmp(pszSymbol, "SomeImportFunction") || !strcmp(pszSymbol, "_SomeImportFunction"))
83 *pValue = (uintptr_t)0;
84 else
85 {
86 RTPrintf("tstLdr-4: Unexpected import '%s'!\n", pszSymbol);
87 return VERR_SYMBOL_NOT_FOUND;
88 }
89 return VINF_SUCCESS;
90}
91
92
93/**
94 * One test iteration with one file.
95 *
96 * The test is very simple, we load the file three times
97 * into two different regions. The first two into each of the
98 * regions the for compare usage. The third is loaded into one
99 * and then relocated between the two and other locations a few times.
100 *
101 * @returns number of errors.
102 * @param pszFilename The file to load the mess with.
103 */
104static int testLdrOne(const char *pszFilename)
105{
106 int cErrors = 0;
107 size_t cbImage = 0;
108 struct Load
109 {
110 RTLDRMOD hLdrMod;
111 void *pvBits;
112 size_t cbBits;
113 const char *pszName;
114 } aLoads[6] =
115 {
116 { NULL, NULL, 0, "foo" },
117 { NULL, NULL, 0, "bar" },
118 { NULL, NULL, 0, "foobar" },
119 { NULL, NULL, 0, "kLdr-foo" },
120 { NULL, NULL, 0, "kLdr-bar" },
121 { NULL, NULL, 0, "kLdr-foobar" }
122 };
123 unsigned i;
124 int rc;
125
126 /*
127 * Load them.
128 */
129 for (i = 0; i < RT_ELEMENTS(aLoads); i++)
130 {
131 if (!strncmp(aLoads[i].pszName, RT_STR_TUPLE("kLdr-")))
132 rc = RTLdrOpenkLdr(pszFilename, 0, RTLDRARCH_WHATEVER, &aLoads[i].hLdrMod);
133 else
134 rc = RTLdrOpen(pszFilename, 0, RTLDRARCH_WHATEVER, &aLoads[i].hLdrMod);
135 if (RT_FAILURE(rc))
136 {
137 RTPrintf("tstLdr-4: Failed to open '%s'/%d, rc=%Rrc. aborting test.\n", pszFilename, i, rc);
138 Assert(aLoads[i].hLdrMod == NIL_RTLDRMOD);
139 cErrors++;
140 break;
141 }
142
143 /* size it */
144 size_t cb = RTLdrSize(aLoads[i].hLdrMod);
145 if (cbImage && cb != cbImage)
146 {
147 RTPrintf("tstLdr-4: Size mismatch '%s'/%d. aborting test.\n", pszFilename, i);
148 cErrors++;
149 break;
150 }
151 aLoads[i].cbBits = cbImage = cb;
152
153 /* Allocate bits. */
154 aLoads[i].pvBits = RTMemExecAlloc(cb);
155 if (!aLoads[i].pvBits)
156 {
157 RTPrintf("tstLdr-4: Out of memory '%s'/%d cbImage=%d. aborting test.\n", pszFilename, i, cbImage);
158 cErrors++;
159 break;
160 }
161
162 /* Get the bits. */
163 rc = RTLdrGetBits(aLoads[i].hLdrMod, aLoads[i].pvBits, (uintptr_t)aLoads[i].pvBits, testGetImport, NULL);
164 if (RT_FAILURE(rc))
165 {
166 RTPrintf("tstLdr-4: Failed to get bits for '%s'/%d, rc=%Rrc. aborting test\n", pszFilename, i, rc);
167 cErrors++;
168 break;
169 }
170 }
171
172 /*
173 * Execute the code.
174 */
175 if (!cErrors)
176 {
177 for (i = 0; i < RT_ELEMENTS(aLoads); i += 1)
178 {
179 /* get the pointer. */
180 RTUINTPTR Value;
181 rc = RTLdrGetSymbolEx(aLoads[i].hLdrMod, aLoads[i].pvBits, (uintptr_t)aLoads[i].pvBits,
182 UINT32_MAX, "DisasmTest1", &Value);
183 if (rc == VERR_SYMBOL_NOT_FOUND)
184 rc = RTLdrGetSymbolEx(aLoads[i].hLdrMod, aLoads[i].pvBits, (uintptr_t)aLoads[i].pvBits,
185 UINT32_MAX, "_DisasmTest1", &Value);
186 if (RT_FAILURE(rc))
187 {
188 RTPrintf("tstLdr-4: Failed to get symbol \"DisasmTest1\" from load #%d: %Rrc\n", i, rc);
189 cErrors++;
190 break;
191 }
192 DECLCALLBACKPTR(int, pfnDisasmTest1)(void) = (DECLCALLBACKPTR(int, RT_NOTHING)(void))(uintptr_t)Value; /* eeeh. */
193 RTPrintf("tstLdr-4: pfnDisasmTest1=%p / add-symbol-file %s %#x\n", pfnDisasmTest1, pszFilename, aLoads[i].pvBits);
194
195 /* call the test function. */
196 rc = pfnDisasmTest1();
197 if (rc)
198 {
199 RTPrintf("tstLdr-4: load #%d Test1 -> %#x\n", i, rc);
200 cErrors++;
201 }
202 }
203 }
204
205
206 /*
207 * Clean up.
208 */
209 for (i = 0; i < RT_ELEMENTS(aLoads); i++)
210 {
211 if (aLoads[i].pvBits)
212 RTMemExecFree(aLoads[i].pvBits, aLoads[i].cbBits);
213 if (aLoads[i].hLdrMod)
214 {
215 rc = RTLdrClose(aLoads[i].hLdrMod);
216 if (RT_FAILURE(rc))
217 {
218 RTPrintf("tstLdr-4: Failed to close '%s' i=%d, rc=%Rrc.\n", pszFilename, i, rc);
219 cErrors++;
220 }
221 }
222 }
223
224 return cErrors;
225}
226
227
228
229int main(int argc, char **argv)
230{
231 int cErrors = 0;
232 RTR3InitExe(argc, &argv, 0);
233
234 /*
235 * Sanity check.
236 */
237 int rc = DisasmTest1();
238 if (rc)
239 {
240 RTPrintf("tstLdr-4: FATAL ERROR - DisasmTest1 is buggy: rc=%#x\n", rc);
241 return 1;
242 }
243
244 /*
245 * Execute the test.
246 */
247 char szPath[RTPATH_MAX];
248 rc = RTPathExecDir(szPath, sizeof(szPath) - sizeof("/tstLdrObjR0.r0"));
249 if (RT_SUCCESS(rc))
250 {
251 strcat(szPath, "/tstLdrObjR0.r0");
252 RTPrintf("tstLdr-4: TESTING '%s'...\n", szPath);
253 cErrors += testLdrOne(szPath);
254 }
255 else
256 {
257 RTPrintf("tstLdr-4: RTPathExecDir -> %Rrc\n", rc);
258 cErrors++;
259 }
260
261 /*
262 * Test result summary.
263 */
264 if (!cErrors)
265 RTPrintf("tstLdr-4: SUCCESS\n");
266 else
267 RTPrintf("tstLdr-4: FAILURE - %d errors\n", cErrors);
268 return !!cErrors;
269}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette