VirtualBox

source: kStuff/trunk/kLdr/tstkLdrMod.c@ 89

Last change on this file since 89 was 29, checked in by bird, 15 years ago

Finally got around execute the switch to the MIT license.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 22.7 KB
Line 
1/* $Id: tstkLdrMod.c 29 2009-07-01 20:30:29Z bird $ */
2/** @file
3 * kLdr - Module interpreter testcase.
4 */
5
6/*
7 * Copyright (c) 2006-2007 Knut St. Osmundsen <[email protected]>
8 *
9 * Permission is hereby granted, free of charge, to any person
10 * obtaining a copy of this software and associated documentation
11 * files (the "Software"), to deal in the Software without
12 * restriction, including without limitation the rights to use,
13 * copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following
16 * conditions:
17 *
18 * The above copyright notice and this permission notice shall be
19 * included in all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 * OTHER DEALINGS IN THE SOFTWARE.
29 */
30
31/*******************************************************************************
32* Header Files *
33*******************************************************************************/
34#include <k/kLdr.h>
35#include <k/kErr.h>
36#include <k/kErrors.h>
37
38#include <stdarg.h>
39#include <stdio.h>
40#include <stdlib.h>
41#include <string.h>
42
43
44/*******************************************************************************
45* Defined Constants And Macros *
46*******************************************************************************/
47/** The default base address used in the tests. */
48#define MY_BASEADDRESS 0x2400000
49
50
51/*******************************************************************************
52* Global Variables *
53*******************************************************************************/
54/** The numbers of errors. */
55static int g_cErrors = 0;
56
57
58
59/**
60 * Report failure.
61 */
62static int Failure(const char *pszFormat, ...)
63{
64 va_list va;
65
66 g_cErrors++;
67
68 printf("tstLdrMod: ");
69 va_start(va, pszFormat);
70 vprintf(pszFormat, va);
71 va_end(va);
72 printf("\n");
73 return 1;
74}
75
76
77/** Dummy import resolver callback. */
78static int BasicTestsGetImport(PKLDRMOD pMod, KU32 iImport, KU32 iSymbol, const char *pchSymbol, KSIZE cchSymbol,
79 const char *pszVersion, PKLDRADDR puValue, KU32 *pfKind, void *pvUser)
80{
81 *puValue = 0xdeadface;
82 *pfKind = KLDRSYMKIND_NO_BIT | KLDRSYMKIND_NO_TYPE;
83 return 0;
84}
85
86
87/**
88 * Verbose memcmp().
89 */
90static int TestMemComp(const void *pv1, const void *pv2, KSIZE cb)
91{
92 KSIZE off;
93 const KU8 *pb1 = (const KU8 *)pv1;
94 const KU8 *pb2 = (const KU8 *)pv2;
95 if (!memcmp(pb1, pb2, cb))
96 return 0;
97 printf("Mismatching blocks pv1=%p pv2=%p cb=%#x:\n", pv1, pv2, cb);
98 for (off = 0; off < cb; off++)
99 {
100 if (pb1[off] == pb2[off])
101 continue;
102 printf("%08x %02x != %02x\n", off, pb1[off], pb2[off]);
103 }
104 return memcmp(pb1, pb2, cb); /* lazy */
105}
106
107
108/**
109 * Performs basic relocation tests.
110 */
111static int BasicTestsRelocate(PKLDRMOD pMod, void *pvBits, void *pvBits2)
112{
113 const KSIZE cbImage = (KSIZE)kLdrModSize(pMod);
114 int rc;
115
116 printf("* Relocation test...\n");
117
118 /*
119 * Get the same bits again to check that we get the same result.
120 */
121 memset(pvBits2, 0xfe, cbImage);
122 rc = kLdrModGetBits(pMod, pvBits2, (KUPTR)pvBits, BasicTestsGetImport, NULL);
123 if (rc)
124 return Failure("failed to get image bits, rc=%d (%s) (a)", rc, kErrName(rc));
125 if (TestMemComp(pvBits2, pvBits, cbImage))
126 return Failure("relocation test failed, mismatching bits (a)");
127
128 /*
129 * Short relocation round trip.
130 */
131 rc = kLdrModRelocateBits(pMod, pvBits2, 0x1000, (KUPTR)pvBits, BasicTestsGetImport, NULL);
132 if (rc)
133 return Failure("failed to relocate, rc=%d (%s) (b1)", rc, kErrName(rc));
134 rc = kLdrModRelocateBits(pMod, pvBits2, (KUPTR)pvBits, 0x1000, BasicTestsGetImport, NULL);
135 if (rc)
136 return Failure("failed to relocate, rc=%d (%s) (b2)", rc, kErrName(rc));
137 if (TestMemComp(pvBits2, pvBits, cbImage))
138 return Failure("relocation test failed, mismatching bits (b)");
139
140 /*
141 * Longer trip where we also check the intermediate results.
142 */
143 /* stage one */
144 rc = kLdrModRelocateBits(pMod, pvBits, 0x1000000, (KUPTR)pvBits, BasicTestsGetImport, NULL);
145 if (rc)
146 return Failure("failed to relocate, rc=%d (%s) (c1)", rc, kErrName(rc));
147 memset(pvBits2, 0xfe, cbImage);
148 rc = kLdrModGetBits(pMod, pvBits2, 0x1000000, BasicTestsGetImport, NULL);
149 if (rc)
150 return Failure("failed to get image bits, rc=%d (%s) (c1)", rc, kErrName(rc));
151 if (TestMemComp(pvBits2, pvBits, cbImage))
152 return Failure("relocation test failed, mismatching bits (c1)");
153
154 /* stage two */
155 rc = kLdrModRelocateBits(pMod, pvBits, ~(KUPTR)0x1010000, 0x1000000, BasicTestsGetImport, NULL);
156 if (rc)
157 return Failure("failed to relocate, rc=%d (%s) (c2)", rc, kErrName(rc));
158 memset(pvBits2, 0xef, cbImage);
159 rc = kLdrModGetBits(pMod, pvBits2, ~(KUPTR)0x1010000, BasicTestsGetImport, NULL);
160 if (rc)
161 return Failure("failed to get image bits, rc=%d (%s) (c2)", rc, kErrName(rc));
162 if (TestMemComp(pvBits2, pvBits, cbImage))
163 return Failure("relocation test failed, mismatching bits (c2)");
164
165 /* stage three */
166 rc = kLdrModRelocateBits(pMod, pvBits, MY_BASEADDRESS, ~(KUPTR)0x1010000, BasicTestsGetImport, NULL);
167 if (rc)
168 return Failure("failed to relocate, rc=%d (%s) (c3)", rc, kErrName(rc));
169 memset(pvBits2, 0xef, cbImage);
170 rc = kLdrModGetBits(pMod, pvBits2, MY_BASEADDRESS, BasicTestsGetImport, NULL);
171 if (rc)
172 return Failure("failed to get image bits, rc=%d (%s) (c3)", rc, kErrName(rc));
173 if (TestMemComp(pvBits2, pvBits, cbImage))
174 return Failure("relocation test failed, mismatching bits (c3)");
175
176 /* stage four */
177 rc = kLdrModRelocateBits(pMod, pvBits, ~(KUPTR)0 / 2 - 0x10000, MY_BASEADDRESS, BasicTestsGetImport, NULL);
178 if (rc)
179 return Failure("failed to relocate, rc=%d %(s) (c4)", rc, kErrName(rc));
180 memset(pvBits2, 0xdc, cbImage);
181 rc = kLdrModGetBits(pMod, pvBits2, ~(KUPTR)0 / 2 - 0x10000, BasicTestsGetImport, NULL);
182 if (rc)
183 return Failure("failed to get image bits, rc=%d (%s) (c4)", rc, kErrName(rc));
184 if (TestMemComp(pvBits2, pvBits, cbImage))
185 return Failure("relocation test failed, mismatching bits (c4)");
186
187 /* return */
188 rc = kLdrModRelocateBits(pMod, pvBits, (KUPTR)pvBits, ~(KUPTR)0 / 2 - 0x10000, BasicTestsGetImport, NULL);
189 if (rc)
190 return Failure("failed to relocate, rc=%d (%s) (c5)", rc, kErrName(rc));
191 memset(pvBits2, 0xcd, cbImage);
192 rc = kLdrModGetBits(pMod, pvBits2, (KUPTR)pvBits, BasicTestsGetImport, NULL);
193 if (rc)
194 return Failure("failed to get image bits, rc=%d (%s) (c5)", rc, kErrName(rc));
195 if (TestMemComp(pvBits2, pvBits, cbImage))
196 return Failure("relocation test failed, mismatching bits (c5)");
197
198 return 0;
199}
200
201
202/**
203 * Dump symbols and check that we can query each of them recursivly.
204 */
205static int BasicTestsEnumSymCallback(PKLDRMOD pMod, KU32 iSymbol, const char *pchSymbol, KSIZE cchSymbol,
206 const char *pszVersion, KLDRADDR uValue, KU32 fKind, void *pvUser)
207{
208 KLDRADDR uValue2;
209 KU32 fKind2;
210 int rc;
211
212 /* dump */
213 printf("#0x%08x: %016" PRI_KLDRADDR " %#08x", iSymbol, uValue, fKind);
214 if (pchSymbol)
215 printf(" %.*s", cchSymbol, pchSymbol);
216 printf("\n");
217
218 /* query by ordinal */
219 if (iSymbol != NIL_KLDRMOD_SYM_ORDINAL)
220 {
221 fKind2 = 0;
222 rc = kLdrModQuerySymbol(pMod, pvUser, MY_BASEADDRESS, iSymbol, NULL, 0, NULL, NULL, NULL,
223 &uValue2, &fKind2);
224 if (rc)
225 return Failure("Couldn't find symbol %#x (%.*s) by ordinal. rc=%d (%s)", iSymbol, cchSymbol, pchSymbol, rc, kErrName(rc));
226 if (uValue != uValue2)
227 return Failure("Symbol %#x (%.*s): Value mismatch %016" PRI_KLDRADDR " != %016" PRI_KLDRADDR " (enum!=query/ord) pvBits=%p",
228 iSymbol, cchSymbol, pchSymbol, uValue, uValue2, pvUser);
229 if (fKind != fKind2)
230 return Failure("Symbol %#x (%.*s): Kind mismatch %#x != %#x (enum!=query/ord) pvBits=%p",
231 iSymbol, cchSymbol, pchSymbol, fKind, fKind2, pvUser);
232 }
233
234 /* query by name. */
235 if (pchSymbol)
236 {
237 fKind2 = 0;
238 rc = kLdrModQuerySymbol(pMod, pvUser, MY_BASEADDRESS, NIL_KLDRMOD_SYM_ORDINAL, pchSymbol, cchSymbol, pszVersion,
239 NULL, NULL, &uValue2, &fKind2);
240 if (rc)
241 return Failure("Couldn't find symbol %#x (%.*s) by name. rc=%d (%s)", iSymbol, cchSymbol, pchSymbol, rc, kErrName(rc));
242 if (uValue != uValue2)
243 return Failure("Symbol %#x (%.*s): Value mismatch %016" PRI_KLDRADDR " != %016" PRI_KLDRADDR " (enum!=query/name) pvBits=%p",
244 iSymbol, cchSymbol, pchSymbol, uValue, uValue2, pvUser);
245 if (fKind != fKind2)
246 return Failure("Symbol %#x (%.*s): Kind mismatch %#x != %#x (enum!=query/name) pvBits=%p",
247 iSymbol, cchSymbol, pchSymbol, fKind, fKind2, pvUser);
248 }
249
250 return 0;
251}
252
253
254/**
255 * Dump debugger information and check it for correctness.
256 */
257static int BasicTestEnumDbgInfoCallback(PKLDRMOD pMod, KU32 iDbgInfo, KLDRDBGINFOTYPE enmType,
258 KI16 iMajorVer, KI16 iMinorVer, KLDRFOFF offFile, KLDRADDR LinkAddress,
259 KLDRSIZE cb, const char *pszExtFile, void *pvUser)
260{
261 printf("#0x%08x: enmType=%d %d.%d offFile=0x%" PRI_KLDRADDR " LinkAddress=%" PRI_KLDRADDR " cb=%" PRI_KLDRSIZE " pvUser=%p\n",
262 iDbgInfo, enmType, iMajorVer, iMinorVer, (KLDRADDR)offFile, LinkAddress, cb, pvUser);
263 if (pszExtFile)
264 printf(" pszExtFile=%p '%s'\n", pszExtFile, pszExtFile);
265
266 if (enmType >= KLDRDBGINFOTYPE_END || enmType <= KLDRDBGINFOTYPE_INVALID)
267 return Failure("Bad enmType");
268 if (pvUser != NULL)
269 return Failure("pvUser");
270
271 return 0;
272}
273
274
275/**
276 * Performs the basic module loader test on the specified module and image bits.
277 */
278static int BasicTestsSub2(PKLDRMOD pMod, void *pvBits)
279{
280 KI32 cImports;
281 KI32 i;
282 int rc;
283 KU32 fKind;
284 KLDRADDR Value;
285 KLDRADDR MainEPAddress;
286 KLDRSTACKINFO StackInfo;
287
288 printf("* Testing queries with pvBits=%p...\n", pvBits);
289
290 /*
291 * Get the import modules.
292 */
293 cImports = kLdrModNumberOfImports(pMod, pvBits);
294 printf("cImports=%d\n", cImports);
295 if (cImports < 0)
296 return Failure("failed to query the number of import, cImports=%d", cImports);
297 for (i = 0; i < cImports; i++)
298 {
299 char szImportModule[260];
300 rc = kLdrModGetImport(pMod, pvBits, i, szImportModule, sizeof(szImportModule));
301 if (rc)
302 return Failure("failed to get import module name, rc=%d (%s). (%.260s)", rc, kErrName(rc), szImportModule);
303 printf("import #%d: '%s'\n", i, szImportModule);
304 }
305
306 /*
307 * Query stack info.
308 */
309 StackInfo.Address = ~(KLDRADDR)42;
310 StackInfo.LinkAddress = ~(KLDRADDR)42;
311 StackInfo.cbStack = ~(KLDRSIZE)42;
312 StackInfo.cbStackThread = ~(KLDRSIZE)42;
313 rc = kLdrModGetStackInfo(pMod, pvBits, MY_BASEADDRESS, &StackInfo);
314 if (rc)
315 return Failure("kLdrModGetStackInfo failed with rc=%d (%s)", rc, kErrName(rc));
316 printf("Stack: Address=%016" PRI_KLDRADDR " LinkAddress=%016" PRI_KLDRADDR "\n"
317 " cbStack=%016" PRI_KLDRSIZE " cbStackThread=%016" PRI_KLDRSIZE "\n",
318 StackInfo.Address, StackInfo.LinkAddress, StackInfo.cbStack, StackInfo.cbStackThread);
319 if (StackInfo.Address == ~(KLDRADDR)42)
320 return Failure("Bad StackInfo.Address");
321 if (StackInfo.LinkAddress == ~(KLDRADDR)42)
322 return Failure("Bad StackInfo.LinkAddress");
323 if (StackInfo.cbStack == ~(KLDRSIZE)42)
324 return Failure("Bad StackInfo.cbStack");
325 if (StackInfo.cbStackThread == ~(KLDRSIZE)42)
326 return Failure("Bad StackInfo.cbStackThread");
327
328 /*
329 * Query entrypoint.
330 */
331 MainEPAddress = ~(KLDRADDR)42;
332 rc = kLdrModQueryMainEntrypoint(pMod, pvBits, MY_BASEADDRESS, &MainEPAddress);
333 if (rc)
334 return Failure("kLdrModQueryMainEntrypoint failed with rc=%d (%s)", rc, kErrName(rc));
335 printf("Entrypoint: %016" PRI_KLDRADDR "\n", MainEPAddress);
336 if (MainEPAddress == ~(KLDRADDR)42)
337 return Failure("MainEPAddress wasn't set.");
338 if (MainEPAddress != NIL_KLDRADDR && MainEPAddress < MY_BASEADDRESS)
339 return Failure("Bad MainEPAddress (a).");
340 if (MainEPAddress != NIL_KLDRADDR && MainEPAddress >= MY_BASEADDRESS + kLdrModSize(pMod))
341 return Failure("Bad MainEPAddress (b).");
342
343 /*
344 * Debugger information.
345 */
346 rc = kLdrModHasDbgInfo(pMod, pvBits);
347 if (!rc)
348 printf("Has Debugger Information\n");
349 else if (rc == KLDR_ERR_NO_DEBUG_INFO)
350 printf("NO Debugger Information\n");
351 else
352 return Failure("kLdrModHasDbgInfo failed with rc=%d (%s)", rc, kErrName(rc));
353 rc = kLdrModEnumDbgInfo(pMod, pvBits, BasicTestEnumDbgInfoCallback, NULL);
354 if (rc)
355 return Failure("kLdrModEnumDbgInfo failed with rc=%d (%s)", rc, kErrName(rc));
356
357
358 /*
359 * Negative symbol query tests.
360 */
361 fKind = 0;
362 Value = 0x0badc0de;
363 rc = kLdrModQuerySymbol(pMod, pvBits, MY_BASEADDRESS, NIL_KLDRMOD_SYM_ORDINAL - 20, NULL, 0, NULL, NULL, NULL,
364 &Value, &fKind);
365 if (rc)
366 {
367 if (Value != 0)
368 return Failure("Value wasn't cleared on failure.");
369 }
370
371 fKind = 0;
372 Value = 0x0badc0de;
373 rc = kLdrModQuerySymbol(pMod, pvBits, MY_BASEADDRESS, NIL_KLDRMOD_SYM_ORDINAL, NULL, 0, NULL, NULL, NULL,
374 &Value, &fKind);
375 if (!rc)
376 return Failure("NIL ordinal succeeded!");
377 if (Value != 0)
378 return Failure("Value wasn't cleared on failure.");
379
380 /*
381 * Enumerate and query all symbols.
382 */
383 printf("\n"
384 "Symbols:\n");
385 rc = kLdrModEnumSymbols(pMod, pvBits, MY_BASEADDRESS, 0, BasicTestsEnumSymCallback, pvBits);
386 if (rc)
387 return Failure("kLdrModEnumSymbols failed with rc=%d (%s)", rc, kErrName(rc));
388
389
390/*int kLdrModCanExecuteOn(PKLDRMOD pMod, const void *pvBits, KCPUARCH enmArch, KCPU enmCpu);
391*/
392
393 return 0;
394}
395
396
397/**
398 * Performs the basic module loader test on the specified module
399 */
400static int BasicTestsSub(PKLDRMOD pMod)
401{
402 int rc;
403 KU32 i;
404 void *pvBits;
405 KSIZE cbImage;
406
407 /*
408 * Check/dump the module structure.
409 */
410 printf("pMod=%p u32Magic=%#x cSegments=%d\n", (void *)pMod, pMod->u32Magic, pMod->cSegments);
411 printf("enmType=%d enmFmt=%d enmArch=%d enmCpu=%d enmEndian=%d\n",
412 pMod->enmType, pMod->enmFmt, pMod->enmArch, pMod->enmCpu, pMod->enmEndian);
413 printf("Filename: %s (%d bytes)\n", pMod->pszFilename, pMod->cchFilename);
414 printf(" Name: %s (%d bytes)\n", pMod->pszName, pMod->cchName);
415 printf("\n");
416
417 if (pMod->u32Magic != KLDRMOD_MAGIC)
418 return Failure("Bad u32Magic");
419 if (strlen(pMod->pszFilename) != pMod->cchFilename)
420 return Failure("Bad cchFilename");
421 if (strlen(pMod->pszName) != pMod->cchName)
422 return Failure("Bad cchName");
423 if (pMod->enmFmt >= KLDRFMT_END || pMod->enmFmt <= KLDRFMT_INVALID)
424 return Failure("Bad enmFmt");
425 if (pMod->enmType >= KLDRTYPE_END || pMod->enmType <= KLDRTYPE_INVALID)
426 return Failure("Bad enmType: %d", pMod->enmType);
427 if (!K_ARCH_IS_VALID(pMod->enmArch))
428 return Failure("Bad enmArch");
429 if (pMod->enmCpu >= KCPU_END || pMod->enmCpu <= KCPU_INVALID)
430 return Failure("Bad enmCpu");
431 if (pMod->enmEndian >= KLDRENDIAN_END || pMod->enmEndian <= KLDRENDIAN_INVALID)
432 return Failure("Bad enmEndian");
433
434 for (i = 0; i < pMod->cSegments; i++)
435 {
436 printf("seg #%d: pvUser=%p enmProt=%d Name: '%.*s' (%d bytes)\n",
437 i, pMod->aSegments[i].pvUser, pMod->aSegments[i].enmProt,
438 pMod->aSegments[i].cchName, pMod->aSegments[i].pchName, pMod->aSegments[i].cchName);
439 printf("LinkAddress: %016" PRI_KLDRADDR " cb: %016" PRI_KLDRSIZE " Alignment=%08" PRI_KLDRADDR " \n",
440 pMod->aSegments[i].LinkAddress, pMod->aSegments[i].cb, pMod->aSegments[i].Alignment);
441 printf(" RVA: %016" PRI_KLDRADDR " cbMapped: %016" PRI_KLDRSIZE " MapAddress=%p\n",
442 pMod->aSegments[i].RVA, (KLDRSIZE)pMod->aSegments[i].cbMapped, (void *)pMod->aSegments[i].MapAddress);
443 printf(" offFile: %016" PRI_KLDRADDR " cbFile: %016" PRI_KLDRSIZE "\n",
444 (KLDRADDR)pMod->aSegments[i].offFile, (KLDRSIZE)pMod->aSegments[i].cbFile);
445 printf("\n");
446
447 if (pMod->aSegments[i].pvUser != NULL)
448 return Failure("Bad pvUser");
449 if (pMod->aSegments[i].enmProt >= KPROT_END || pMod->aSegments[i].enmProt <= KPROT_INVALID)
450 return Failure("Bad enmProt");
451 if (pMod->aSegments[i].MapAddress != 0)
452 return Failure("Bad MapAddress");
453 if (pMod->aSegments[i].cbMapped < pMod->aSegments[i].cb)
454 return Failure("Bad cbMapped (1)");
455 if (pMod->aSegments[i].cbMapped && !pMod->aSegments[i].Alignment)
456 return Failure("Bad cbMapped (2)");
457 if (pMod->aSegments[i].cbMapped > kLdrModSize(pMod))
458 return Failure("Bad cbMapped (3)");
459 if ( pMod->aSegments[i].Alignment
460 && (pMod->aSegments[i].RVA & (pMod->aSegments[i].Alignment - 1)))
461 return Failure("Bad RVA (1)");
462 if (pMod->aSegments[i].RVA != NIL_KLDRADDR && !pMod->aSegments[i].Alignment)
463 return Failure("Bad RVA (2)");
464 if ( pMod->aSegments[i].RVA != NIL_KLDRADDR
465 && pMod->aSegments[i].RVA >= kLdrModSize(pMod))
466 return Failure("Bad RVA (3)");
467 if ( pMod->aSegments[i].RVA != NIL_KLDRADDR
468 && pMod->aSegments[i].RVA + pMod->aSegments[i].cbMapped > kLdrModSize(pMod))
469 return Failure("Bad RVA/cbMapped (4)");
470 if (pMod->aSegments[i].LinkAddress != NIL_KLDRADDR && !pMod->aSegments[i].Alignment)
471 return Failure("Bad LinkAddress");
472 if ( pMod->aSegments[i].LinkAddress != NIL_KLDRADDR
473 && (pMod->aSegments[i].LinkAddress) & (pMod->aSegments[i].Alignment - 1))
474 return Failure("Bad LinkAddress alignment");
475 if (pMod->aSegments[i].offFile != -1 && pMod->aSegments[i].cbFile == -1)
476 return Failure("Bad offFile");
477 if (pMod->aSegments[i].offFile == -1 && pMod->aSegments[i].cbFile != -1)
478 return Failure("Bad cbFile");
479 }
480
481
482 /*
483 * Get image the size and query the image bits.
484 */
485 printf("* Testing user mapping...\n");
486
487 cbImage = (KSIZE)kLdrModSize(pMod);
488 if (cbImage != kLdrModSize(pMod))
489 return Failure("aborting test because the image is too huge!");
490 pvBits = malloc((KSIZE)cbImage);
491 if (!pvBits)
492 return Failure("failed to allocate %d bytes for the image", cbImage);
493
494 rc = kLdrModGetBits(pMod, pvBits, (KUPTR)pvBits, BasicTestsGetImport, NULL);
495 if (rc)
496 return Failure("failed to get image bits, rc=%d (%s)", rc, kErrName(rc));
497
498 /*
499 * Another cleanup nesting.
500 */
501 rc = BasicTestsSub2(pMod, pvBits);
502 if (!rc)
503 {
504 /*
505 * Test relocating the bits in a few different ways before we're done with them.
506 */
507 void *pvBits2 = malloc((KSIZE)cbImage);
508 if (pvBits2)
509 {
510 rc = BasicTestsRelocate(pMod, pvBits, pvBits2);
511 free(pvBits2);
512 }
513 else
514 rc = Failure("failed to allocate %d bytes for the 2nd image", cbImage);
515 }
516
517 free(pvBits);
518 return rc;
519}
520
521
522/**
523 * Tests the mapping related api, after mapping.
524 */
525static int BasicTestsSubMap2(PKLDRMOD pMod)
526{
527 int rc;
528
529 rc = kLdrModFixupMapping(pMod, BasicTestsGetImport, NULL);
530 if (rc)
531 return Failure("kLdrModFixupMapping (a) failed, rc=%d (%s)", rc, kErrName(rc));
532
533 rc = kLdrModReload(pMod);
534 if (rc)
535 return Failure("kLdrModReload (a) failed, rc=%d (%s)", rc, kErrName(rc));
536
537 rc = kLdrModReload(pMod);
538 if (rc)
539 return Failure("kLdrModReload (b) failed, rc=%d (%s)", rc, kErrName(rc));
540
541 rc = kLdrModFixupMapping(pMod, BasicTestsGetImport, NULL);
542 if (rc)
543 return Failure("kLdrModFixupMapping (b) failed, rc=%d (%s)", rc, kErrName(rc));
544
545 rc = kLdrModAllocTLS(pMod);
546 if (rc)
547 return Failure("kLdrModAllocTLS (a) failed, rc=%d (%s)", rc, kErrName(rc));
548 kLdrModFreeTLS(pMod);
549
550 rc = kLdrModAllocTLS(pMod);
551 if (rc)
552 return Failure("kLdrModAllocTLS (b) failed, rc=%d (%s)", rc, kErrName(rc));
553 kLdrModFreeTLS(pMod);
554
555 /*
556 * Repeat the BasicTestsSub2 with pvBits as NULL to test module
557 * interpreters that can utilize the mapping.
558 */
559 rc = BasicTestsSub2(pMod, NULL);
560 if (rc)
561 return Failure("BasicTestsSub2 in Map2 failed, rc=%d (%s)", rc, kErrName(rc));
562 return 0;
563}
564
565
566/**
567 * Tests the mapping related api.
568 */
569static int BasicTestsSubMap(PKLDRMOD pMod)
570{
571 int rc, rc2;
572 printf("* Mapping tests...\n");
573
574 rc = kLdrModMap(pMod);
575 if (rc)
576 return Failure("kLdrModMap failed, rc=%d (%s)", rc, kErrName(rc));
577 rc = BasicTestsSubMap2(pMod);
578 rc2 = kLdrModUnmap(pMod);
579 if (rc2)
580 {
581 Failure("kLdrModUnmap failed, rc=%d (%s)", rc2, kErrName(rc2));
582 rc = rc ? rc : rc2;
583 }
584
585 printf("* Mapping tests done.\n");
586 return rc;
587}
588
589
590/**
591 * Performs basic module loader tests on the specified file.
592 */
593static int BasicTests(const char *pszFilename)
594{
595 PKLDRMOD pMod;
596 int rc, rc2;
597
598 printf("tstLdrMod: Testing '%s'", pszFilename);
599 rc = kLdrModOpen(pszFilename, &pMod);
600 if (!rc)
601 {
602 rc = BasicTestsSub(pMod);
603 if (!rc)
604 rc = BasicTestsSubMap(pMod);
605 if (!rc)
606 rc = BasicTestsSub2(pMod, NULL);
607 rc2 = kLdrModClose(pMod);
608 if (rc2)
609 Failure("failed to close '%s', rc=%d (%s)", pszFilename, rc, kErrName(rc));
610 if (rc2 && !rc)
611 rc = rc2;
612 }
613 else
614 Failure("Failed to open '%s', rc=%d (%s)", pszFilename, rc, kErrName(rc));
615 return rc ? 1 : 0;
616}
617
618
619int main(int argc, char **argv)
620{
621 BasicTests(argv[argc-1]);
622
623 if (!g_cErrors)
624 printf("tstLdrMod: SUCCESS\n");
625 else
626 printf("tstLdrMod: FAILURE - %d errors\n", g_cErrors);
627 return !!g_cErrors;
628}
629
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