source: trunk/kLdr/tstkLdrMod.c@ 2875

Last change on this file since 2875 was 2861, checked in by bird, 19 years ago

Put the PE module interpreter thru the wringer and learnt how much the window file mapping API sucks.

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