source: trunk/kLdr/testcase/tst-0-driver.c@ 3442

Last change on this file since 3442 was 2965, checked in by bird, 19 years ago

messing about...

  • Property svn:keywords set to Id
File size: 20.9 KB
Line 
1/* $Id: tst-0-driver.c 2965 2007-02-13 21:04:40Z bird $ */
2/** @file
3 *
4 * kLdr - Dynamic Loader testcase no. 0, Driver.
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 "tst.h"
33#include <stdarg.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37
38
39/*******************************************************************************
40* Defined Constants And Macros *
41*******************************************************************************/
42/** Select the appropriate KLDRSYMKIND bit define. */
43#define MY_KLDRSYMKIND_BITS ( sizeof(void *) == 4 ? KLDRSYMKIND_32BIT : KLDRSYMKIND_64BIT )
44
45
46/*******************************************************************************
47* Global Variables *
48*******************************************************************************/
49/** The numbers of errors. */
50static int g_cErrors = 0;
51
52
53
54/**
55 * Report failure.
56 */
57static int Failure(const char *pszFormat, ...)
58{
59 va_list va;
60
61 g_cErrors++;
62
63 printf("tst-0-driver: ");
64 va_start(va, pszFormat);
65 vprintf(pszFormat, va);
66 va_end(va);
67 printf("\n");
68 return 1;
69}
70
71
72int main(int argc, char **argv)
73{
74 const char *pszErrInit = "Error, szErr wasn't zapped";
75 char szErr[512];
76 char szBuf[512];
77 char *psz;
78 size_t cch;
79 HKLDRMOD hMod;
80 int rc;
81
82 /*
83 * The first thing to do is a simple load / unload test
84 * using the tst-0-a library (it'll drag in tst-0-d).
85 */
86 printf("tst-0-driver: Basic API test using 'tst-0-a'...\n");
87 hMod = (HKLDRMOD)0xffffeeee;
88 strcpy(szErr, pszErrInit);
89 rc = kLdrDyldLoad("tst-0-a", NULL, NULL, KLDRDYLD_SEARCH_HOST,
90 KLDRDYLD_LOAD_FLAGS_RECURSIVE_INIT, &hMod, szErr, sizeof(szErr));
91 if (rc)
92 Failure("kLdrDyldLoad(\"tst-0\",...) failed, rc=%d (%#x). szErr='%s'.\n", rc, rc, szErr);
93 if (!strcmp(szErr, pszErrInit))
94 Failure("szErr wasn't set.\n");
95 if (hMod == (HKLDRMOD)0xffffeeee)
96 Failure("hMod wasn't set.\n");
97 if (hMod == NIL_HKLDRMOD && !rc)
98 Failure("rc=0 but hMod=NIL_HKLDRMOD\n");
99 if (!rc)
100 {
101 HKLDRMOD hMod2;
102 HKLDRMOD hMod3;
103 printf("tst-0-driver: hMod=%p ('tst-0-a')\n", (void *)hMod);
104
105 /*
106 * Simple test of kLdrDyldFindByName.
107 */
108 hMod2 = (HKLDRMOD)0xffffeeee;
109 rc = kLdrDyldFindByName("tst-0", NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hMod2);
110 if (!rc)
111 Failure("kLdrDyldFindByName(\"tst-0\",,,) didn't fail!\n");
112 if (rc && hMod2 != NIL_HKLDRMOD)
113 Failure("hMod2 wasn't set correctly on kLdrDyldFindByName failure!\n");
114
115 hMod2 = (HKLDRMOD)0xffffeeee;
116 rc = kLdrDyldFindByName("tst-0-a", NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hMod2);
117 if (rc)
118 Failure("kLdrDyldFindByName(\"tst-0-a\",,,) failed, rc=%d (%#x)\n", rc, rc);
119 if (!rc && hMod2 != hMod)
120 Failure("kLdrDyldFindByName(\"tst-0-a\",,,) returned the wrong module handle: %p instead of %p\n",
121 (void *)hMod2, (void *)hMod);
122
123 hMod2 = (HKLDRMOD)0xffffeeee;
124 rc = kLdrDyldFindByName("tst-0-d", NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hMod2);
125 if (!rc)
126 printf("tst-0-driver: hMod2=%p ('tst-0-d')\n", (void *)hMod2);
127 else
128 Failure("kLdrDyldFindByName(\"tst-0-d\",,,) failed, rc=%d (%#x)\n", rc, rc);
129
130 /*
131 * Get the name and filename for each of the two modules.
132 */
133 rc = kLdrDyldGetName(hMod2, szBuf, sizeof(szBuf));
134 if (!rc)
135 {
136 printf("tst-0-driver: name: '%s' ('tst-0-d')\n", szBuf);
137 psz = strstr(szBuf, "-0-");
138 if ( !psz
139 || strnicmp(psz, "-0-d", sizeof("-0-d") - 1))
140 Failure("kLdrDyldGetName(\"tst-0-d\",,,) -> '%s': pattern '-0-d' not found\n", szBuf);
141
142 /* overflow test. */
143 cch = strlen(szBuf);
144 szBuf[cch + 1] = szBuf[cch] = szBuf[cch - 1] = 'x';
145 szBuf[cch + 2] = '\0';
146 rc = kLdrDyldGetName(hMod2, szBuf, cch);
147 if (rc == KLDR_ERR_BUFFER_OVERFLOW)
148 {
149 if (!szBuf[0])
150 Failure("kLdrDyldGetName didn't return partial result on overflow\n");
151 else if (szBuf[cch - 1])
152 Failure("kLdrDyldGetName didn't terminate partial result correctly overflow: '%s'\n", szBuf);
153 else if (szBuf[cch] != 'x')
154 Failure("kLdrDyldGetName exceeded the buffer limit on partial overflow: '%s'\n", szBuf);
155 }
156 else
157 Failure("kLdrDyldGetName(\"tst-0-d\",,,) -> rc=%d (%#x) instead of KLDR_ERR_BUFFER_OVERFLOW\n", rc, rc);
158
159 /* check that we can query the module by the returned name. */
160 rc = kLdrDyldGetName(hMod2, szBuf, sizeof(szBuf));
161 if (!rc)
162 {
163 hMod3 = (HKLDRMOD)0xffffeeee;
164 rc = kLdrDyldFindByName(szBuf, NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hMod3);
165 if (rc || hMod3 != hMod2)
166 Failure("kLdrDyldFindByName(\"%s\",,,) failed, rc=%d (%#x) hMod3=%p hMod2=%p\n",
167 szBuf, rc, rc, (void *)hMod3, (void *)hMod2);
168 }
169 else
170 Failure("kLdrDyldGetName(\"tst-0-d\",,,) failed (b), rc=%d (%#x)\n", rc, rc);
171 }
172 else
173 Failure("kLdrDyldGetName(\"tst-0-d\",,,) failed, rc=%d (%#x)\n", rc, rc);
174
175 rc = kLdrDyldGetFilename(hMod2, szBuf, sizeof(szBuf));
176 if (!rc)
177 {
178 printf("tst-0-driver: filename: '%s' ('tst-0-d')\n", szBuf);
179
180 /* overflow test. */
181 cch = strlen(szBuf);
182 szBuf[cch + 1] = szBuf[cch] = szBuf[cch - 1] = 'x';
183 szBuf[cch + 2] = '\0';
184 rc = kLdrDyldGetFilename(hMod2, szBuf, cch);
185 if (rc == KLDR_ERR_BUFFER_OVERFLOW)
186 {
187 if (!szBuf[0])
188 Failure("kLdrDyldGetFilename didn't return partial result on overflow\n");
189 else if (szBuf[cch - 1])
190 Failure("kLdrDyldGetFilename didn't terminate partial result correctly overflow: '%s'\n", szBuf);
191 else if (szBuf[cch] != 'x')
192 Failure("kLdrDyldGetFilename exceeded the buffer limit on partial overflow: '%s'\n", szBuf);
193 }
194 else
195 Failure("kLdrDyldGetFilename(\"tst-0-d\",,,) -> rc=%d (%#x) instead of KLDR_ERR_BUFFER_OVERFLOW\n", rc, rc);
196
197 /* check that we can query the module by the returned filename. */
198 rc = kLdrDyldGetFilename(hMod2, szBuf, sizeof(szBuf));
199 if (!rc)
200 {
201 hMod3 = (HKLDRMOD)0xffffeeee;
202 rc = kLdrDyldFindByName(szBuf, NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hMod3);
203 if (rc || hMod3 != hMod2)
204 Failure("kLdrDyldFindByName(\"%s\",,,) failed, rc=%d (%#x) hMod3=%p hMod2=%p\n",
205 szBuf, rc, rc, (void *)hMod3, (void *)hMod2);
206 }
207 else
208 Failure("kLdrDyldGetName(\"tst-0-d\",,,) failed (b), rc=%d (%#x)\n", rc, rc);
209 }
210 else
211 Failure("kLdrDyldGetFilename(\"tst-0-d\",,,) failed, rc=%d (%#x)\n", rc, rc);
212
213 /* the other module */
214 rc = kLdrDyldGetName(hMod, szBuf, sizeof(szBuf));
215 if (!rc)
216 {
217 printf("tst-0-driver: name: '%s' ('tst-0-a')\n", szBuf);
218 psz = strstr(szBuf, "-0-");
219 if ( !psz
220 || strnicmp(psz, "-0-a", sizeof("-0-a") - 1))
221 Failure("kLdrDyldGetName(\"tst-0-a\",,,) -> '%s': pattern '-0-a' not found\n", szBuf);
222
223 /* check that we can query the module by the returned name. */
224 hMod3 = (HKLDRMOD)0xffffeeee;
225 rc = kLdrDyldFindByName(szBuf, NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hMod3);
226 if (rc || hMod3 != hMod)
227 Failure("kLdrDyldFindByName(\"%s\",,,) failed, rc=%d (%#x) hMod3=%p hMod=%p\n",
228 szBuf, rc, rc, (void *)hMod3, (void *)hMod);
229 }
230 else
231 Failure("kLdrDyldGetName(\"tst-0-a\",,,) failed, rc=%d (%#x)\n", rc, rc);
232
233 rc = kLdrDyldGetFilename(hMod, szBuf, sizeof(szBuf));
234 if (!rc)
235 {
236 printf("tst-0-driver: filename: '%s' ('tst-0-a')\n", szBuf);
237
238 /* check that we can query the module by the returned filename. */
239 hMod3 = (HKLDRMOD)0xffffeeee;
240 rc = kLdrDyldFindByName(szBuf, NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hMod3);
241 if (rc || hMod3 != hMod)
242 Failure("kLdrDyldFindByName(\"%s\",,,) failed, rc=%d (%#x) hMod3=%p hMod=%p\n",
243 szBuf, rc, rc, (void *)hMod3, (void *)hMod);
244 }
245 else
246 Failure("kLdrDyldGetFilename(\"tst-0-a\",,,) failed, rc=%d (%#x)\n", rc, rc);
247
248
249 /*
250 * Resolve the symbol exported by each of the two modules and call them.
251 */
252 if (!g_cErrors)
253 {
254 uintptr_t uValue;
255 uint32_t fKind;
256
257 fKind = 0xffeeffee;
258 uValue = ~(uintptr_t)42;
259 rc = kLdrDyldQuerySymbol(hMod, NIL_KLDRMOD_SYM_ORDINAL, MY_NAME("FuncA"), &uValue, &fKind);
260 if (!rc)
261 {
262 if (uValue == ~(uintptr_t)42)
263 Failure("kLdrDyldQuerySymbol(\"tst-0-a\",,\"FuncA\",): uValue wasn't set.\n");
264 if (fKind == 0xffeeffee)
265 Failure("kLdrDyldQuerySymbol(\"tst-0-a\",,\"FuncA\",): fKind wasn't set.\n");
266 if ( (fKind & KLDRSYMKIND_BIT_MASK) != KLDRSYMKIND_NO_BIT
267 && (fKind & KLDRSYMKIND_BIT_MASK) != MY_KLDRSYMKIND_BITS)
268 Failure("fKind=%#x indicates a different code 'bit' mode than we running at.\n", fKind);
269 if ( (fKind & KLDRSYMKIND_TYPE_MASK) != KLDRSYMKIND_NO_TYPE
270 && (fKind & KLDRSYMKIND_TYPE_MASK) != KLDRSYMKIND_CODE)
271 Failure("fKind=%#x indicates that \"FuncA\" isn't code.\n", fKind);
272 if (fKind & KLDRSYMKIND_FORWARDER)
273 Failure("fKind=%#x indicates that \"FuncA\" is a forwarder. it isn't.\n", fKind);
274
275 /* call it. */
276 if (!g_cErrors)
277 {
278 int (*pfnFuncA)(void) = (int (*)(void))uValue;
279 rc = pfnFuncA();
280 if (rc != 0x42000042)
281 Failure("FuncA returned %#x expected 0x42000042\n", rc);
282 }
283
284 /*
285 * Test kLdrDyldFindByAddress now that we've got an address.
286 */
287 hMod3 = (HKLDRMOD)0xeeeeffff;
288 rc = kLdrDyldFindByAddress(uValue, &hMod3, NULL, NULL);
289 if (!rc)
290 {
291 uintptr_t offSegment;
292 uint32_t iSegment;
293
294 if (hMod3 != hMod)
295 Failure("kLdrDyldFindByAddress(%#p/*FuncA*/, \"tst-0-a\",,,) return incorrect hMod3=%p instead of %p.\n",
296 uValue, hMod3, hMod);
297
298 hMod3 = (HKLDRMOD)0xeeeeffff;
299 iSegment = 0x42424242;
300 rc = kLdrDyldFindByAddress(uValue, &hMod3, &iSegment, &offSegment);
301 if (!rc)
302 {
303 if (hMod3 != hMod)
304 Failure("Bad hMod3 on 2nd kLdrDyldFindByAddress call.\n");
305 if (iSegment > 0x1000) /* safe guess */
306 Failure("Bad iSegment=%#x\n", iSegment);
307 if (offSegment > 0x100000) /* guesswork */
308 Failure("Bad offSegment=%p\n", (void *)offSegment);
309 }
310 else
311 Failure("kLdrDyldFindByAddress(%#p/*FuncA*/, \"tst-0-a\",,,) failed (b), rc=%d (%#x)\n",
312 uValue, rc, rc);
313
314 /* negative test */
315 hMod3 = (HKLDRMOD)0xeeeeffff;
316 iSegment = 0x42424242;
317 offSegment = 0x87654321;
318 rc = kLdrDyldFindByAddress(~(uintptr_t)16, &hMod3, &iSegment, &offSegment);
319 if (!rc)
320 Failure("negative kLdrDyldFindByAddress test returned successfully!\n");
321 if (iSegment != ~(uint32_t)0)
322 Failure("negative kLdrDyldFindByAddress: bad iSegment=%#x\n", iSegment);
323 if (offSegment != ~(uintptr_t)0)
324 Failure("negative kLdrDyldFindByAddress: bad offSegment=%p\n", (void *)offSegment);
325 if (hMod3 != NIL_HKLDRMOD)
326 Failure("negative kLdrDyldFindByAddress: bad hMod3=%p\n", (void *)hMod3);
327 }
328 else
329 Failure("kLdrDyldFindByAddress(%#p/*FuncA*/, \"tst-0-a\",,,) failed, rc=%d (%#x)\n",
330 uValue, rc, rc);
331 }
332 else
333 Failure("kLdrDyldQuerySymbol(\"tst-0-a\",,\"FuncA\",) failed, rc=%d (%#x)\n", rc, rc);
334
335 fKind = 0xffeeffee;
336 uValue = ~(uintptr_t)42;
337 rc = kLdrDyldQuerySymbol(hMod2, NIL_KLDRMOD_SYM_ORDINAL, MY_NAME("FuncD"), &uValue, &fKind);
338 if (!rc)
339 {
340 if (uValue == ~(uintptr_t)42)
341 Failure("kLdrDyldQuerySymbol(\"tst-0-d\",,\"FuncD\",): uValue wasn't set.\n");
342 if (fKind == 0xffeeffee)
343 Failure("kLdrDyldQuerySymbol(\"tst-0-d\",,\"FuncD\",): fKind wasn't set.\n");
344 if ( (fKind & KLDRSYMKIND_BIT_MASK) != KLDRSYMKIND_NO_BIT
345 && (fKind & KLDRSYMKIND_BIT_MASK) != MY_KLDRSYMKIND_BITS)
346 Failure("fKind=%#x indicates a different code 'bit' mode than we running at.\n", fKind);
347 if ( (fKind & KLDRSYMKIND_TYPE_MASK) != KLDRSYMKIND_NO_TYPE
348 && (fKind & KLDRSYMKIND_TYPE_MASK) != KLDRSYMKIND_CODE)
349 Failure("fKind=%#x indicates that \"FuncD\" isn't code.\n", fKind);
350 if (fKind & KLDRSYMKIND_FORWARDER)
351 Failure("fKind=%#x indicates that \"FuncD\" is a forwarder. it isn't.\n", fKind);
352
353 /* call it. */
354 if (!g_cErrors)
355 {
356 int (*pfnFuncD)(void) = (int (*)(void))uValue;
357 rc = pfnFuncD();
358 if (rc != 0x42000000)
359 Failure("FuncD returned %#x expected 0x42000000\n", rc);
360 }
361
362 /* use the address to get the module handle. */
363 hMod3 = (HKLDRMOD)0xeeeeffff;
364 rc = kLdrDyldFindByAddress(uValue, &hMod3, NULL, NULL);
365 if (!rc)
366 {
367 if (hMod3 != hMod2)
368 Failure("kLdrDyldFindByAddress(%#p/*FuncD*/,,,) return incorrect hMod3=%p instead of %p.\n",
369 uValue, hMod3, hMod2);
370 }
371 else
372 Failure("kLdrDyldFindByAddress(%#p/*FuncD*/,,,) failed, rc=%d (%#x)\n",
373 uValue, rc, rc);
374 }
375 else
376 Failure("kLdrDyldQuerySymbol(\"tst-0-a\",,\"FuncA\",) failed, rc=%d (%#x)\n", rc, rc);
377
378 }
379
380 /*
381 * Finally unload it.
382 */
383 rc = kLdrDyldUnload(hMod);
384 if (rc)
385 Failure("kLdrDyldUnload() failed. rc=%d (%#x)\n", rc, rc);
386 if (!rc)
387 {
388 rc = kLdrDyldFindByName("tst-0-d", NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hMod2);
389 if (rc != KLDR_ERR_MODULE_NOT_FOUND)
390 Failure("kLdrDyldFindByName(\"tst-0-d\",,,) return rc=%d (%#x), expected KLDR_ERR_MODULE_NOT_FOUND\n", rc, rc);
391
392 rc = kLdrDyldFindByName("tst-0-a", NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hMod2);
393 if (rc != KLDR_ERR_MODULE_NOT_FOUND)
394 Failure("kLdrDyldFindByName(\"tst-0-a\",,,) return rc=%d (%#x), expected KLDR_ERR_MODULE_NOT_FOUND\n", rc, rc);
395 }
396 }
397
398 /*
399 * Now do what tst-0 would do; load the three dlls, resolve and call their functions.
400 */
401 if (!g_cErrors)
402 {
403 HKLDRMOD hModA;
404 int (*pfnFuncA)(void);
405 HKLDRMOD hModB;
406 int (*pfnFuncB)(void);
407 HKLDRMOD hModC;
408 int (*pfnFuncC)(void);
409 uintptr_t uValue;
410
411 rc = kLdrDyldLoad("tst-0-a", NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hModA, NULL, 0);
412 if (rc)
413 Failure("kLdrDyldLoad(\"tst-0-a\",,,,) -> %d (%#x)\n", rc, rc);
414 if (!rc)
415 {
416 rc = kLdrDyldLoad("tst-0-b", NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hModB, szErr, sizeof(szErr));
417 if (rc)
418 Failure("kLdrDyldLoad(\"tst-0-b\",,,,) -> %d (%#x) szErr='%s'\n", rc, rc, szErr);
419 }
420 if (!rc)
421 {
422 rc = kLdrDyldLoad("tst-0-c", NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hModC, szErr, sizeof(szErr));
423 if (rc)
424 Failure("kLdrDyldLoad(\"tst-0-c\",,,,) -> %d (%#x) szErr='%s'\n", rc, rc, szErr);
425 }
426 if (!rc)
427 {
428 rc = kLdrDyldQuerySymbol(hModA, NIL_KLDRMOD_SYM_ORDINAL, MY_NAME("FuncA"), &uValue, NULL);
429 if (!rc)
430 pfnFuncA = (int (*)(void))uValue;
431 else
432 Failure("kLdrDyldQuerySymbol(,,\"FuncA\",,) -> %d (%#x)\n", rc, rc);
433 }
434 if (!rc)
435 {
436 rc = kLdrDyldQuerySymbol(hModB, NIL_KLDRMOD_SYM_ORDINAL, MY_NAME("FuncB"), &uValue, NULL);
437 if (!rc)
438 pfnFuncB = (int (*)(void))uValue;
439 else
440 Failure("kLdrDyldQuerySymbol(,,\"FuncB\",,) -> %d (%#x)\n", rc, rc);
441 }
442 if (!rc)
443 {
444 rc = kLdrDyldQuerySymbol(hModC, NIL_KLDRMOD_SYM_ORDINAL, MY_NAME("FuncC"), &uValue, NULL);
445 if (!rc)
446 pfnFuncC = (int (*)(void))uValue;
447 else
448 Failure("kLdrDyldQuerySymbol(,,\"FuncA\",,) -> %d (%#x)\n", rc, rc);
449 }
450 if (!rc)
451 {
452 int u = pfnFuncA() | pfnFuncB() | pfnFuncC();
453 if (u == 0x42424242)
454 printf("tst-0-driver: FuncA/B/C => %#x (correct)\n", u);
455 else
456 Failure("FuncA/B/C => %#x\n", u);
457
458 rc = kLdrDyldUnload(hModA);
459 if (rc)
460 Failure("Unload A failed, rc=%d (%#x)\n", rc, rc);
461 u = pfnFuncB() | pfnFuncC();
462 if (u != 0x42424200)
463 Failure("FuncB/C returns %#x instead of 0x42424200 after unloading A\n", u);
464
465 rc = kLdrDyldUnload(hModB);
466 if (rc)
467 Failure("Unload B failed, rc=%d (%#x)\n", rc, rc);
468 u = pfnFuncC();
469 if (u != 0x42420000)
470 Failure("FuncC returns %#x instead of 0x42420000 after unloading A\n", u);
471
472 rc = kLdrDyldUnload(hModC);
473 if (rc)
474 Failure("Unload C failed, rc=%d (%#x)\n", rc, rc);
475
476 rc = kLdrDyldFindByName("tst-0-d", NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hMod);
477 if (rc != KLDR_ERR_MODULE_NOT_FOUND)
478 Failure("Query for \"tst-0-d\" after unloading A,B and C returns rc=%d (%#x) instead of KLDR_ERR_MODULE_NOT_FOUND\n",
479 rc, rc);
480 }
481 }
482
483 /*
484 * Now invoke the executable stub which launches the tst-0 program.
485 */
486 if (!g_cErrors)
487 {
488 /// @todo
489 }
490
491 /*
492 * Summary
493 */
494 if (!g_cErrors)
495 printf("tst-0-driver: SUCCESS\n");
496 else
497 printf("tst-0-driver: FAILURE - %d errors\n", g_cErrors);
498 return !!g_cErrors;
499}
500
Note: See TracBrowser for help on using the repository browser.