VirtualBox

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

Last change on this file since 28 was 2, checked in by bird, 17 years ago

Imported http://svn.netlabs.org/repos/libc/trunk/kStuff, revision 3612.

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