Chameleon

Chameleon Svn Source Tree

Root/branches/slice/i386/boot2/drivers.c

1/*
2 * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 2.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24/*
25 * drivers.c - Driver Loading Functions.
26 *
27 * Copyright (c) 2000 Apple Computer, Inc.
28 *
29 * DRI: Josh de Cesare
30 */
31
32#include <mach-o/fat.h>
33#include <libkern/OSByteOrder.h>
34#include <mach/machine.h>
35
36#include "sl.h"
37#include "boot.h"
38#include "bootstruct.h"
39#include "xml.h"
40#include "ramdisk.h"
41#include "drivers.h"
42#include "modules.h"
43
44//extern char gMacOSVersion; //Slice - defined in boot.h
45
46#ifndef OPTION_ROM
47long (*LoadExtraDrivers_p)(FileLoadDrivers_t FileLoadDrivers_p);
48#endif
49
50//extern unsigned long Adler32( unsigned char * buffer, long length );
51
52long FileLoadDrivers(char *dirSpec, long plugin);
53#ifndef OPTION_ROM
54long NetLoadDrivers(char *dirSpec);
55#endif
56long LoadDriverMKext(char *fileSpec);
57long LoadDriverPList(char *dirSpec, char *name, long bundleType);
58long LoadMatchedModules(void);
59long MatchPersonalities(void);
60long MatchLibraries(void);
61#ifdef NOTDEF
62static ModulePtr FindModule(char *name);
63static void ThinFatFile(void **loadAddrP, unsigned long *lengthP);
64#endif
65static long ParseXML(char *buffer, ModulePtr *module, TagPtr *personalities);
66long InitDriverSupport(void);
67
68static ModulePtr gModuleHead, gModuleTail;
69static TagPtr gPersonalityHead, gPersonalityTail;
70char * gExtensionsSpec;
71char * gDriverSpec;
72char * gFileSpec;
73char * gTempSpec;
74char * gFileName;
75
76unsigned long
77Adler32( unsigned char * buffer, long length )
78{
79 long cnt;
80 unsigned long result, lowHalf, highHalf;
81
82 lowHalf = 1;
83 highHalf = 0;
84
85for ( cnt = 0; cnt < length; cnt++ )
86 {
87 if ((cnt % 5000) == 0)
88 {
89 lowHalf %= 65521L;
90 highHalf %= 65521L;
91 }
92
93 lowHalf += buffer[cnt];
94 highHalf += lowHalf;
95 }
96
97lowHalf %= 65521L;
98highHalf %= 65521L;
99
100result = (highHalf << 16) | lowHalf;
101
102return result;
103}
104
105
106//==========================================================================
107// InitDriverSupport
108
109long
110InitDriverSupport( void )
111{
112 gExtensionsSpec = malloc( 4096 );
113 gDriverSpec = malloc( 4096 );
114 gFileSpec = malloc( 4096 );
115 gTempSpec = malloc( 4096 );
116 gFileName = malloc( 4096 );
117
118 if ( !gExtensionsSpec || !gDriverSpec || !gFileSpec || !gTempSpec || !gFileName )
119 stop("InitDriverSupport error");
120
121 return 0;
122}
123
124//==========================================================================
125// LoadDrivers
126
127long LoadDrivers( char * dirSpec )
128{
129const char * sLoadExtra = "LoadDrivers: Loading Extra drivers %s...\n";
130 char dirSpecExtra[1024];
131
132 if ( InitDriverSupport() != 0 )
133 return 0;
134
135#ifndef OPTION_ROM
136 // Load extra drivers if a hook has been installed.
137 if (LoadExtraDrivers_p != NULL)
138 {
139 (*LoadExtraDrivers_p)(&FileLoadDrivers);
140 }
141
142 if ( gBootFileType == kNetworkDeviceType )
143 {
144 if (NetLoadDrivers(dirSpec) != 0) {
145 error("Could not load drivers from the network\n");
146 return -1;
147 }
148 }
149 else
150#endif
151if ( gBootFileType == kBlockDeviceType )
152{
153// First try to load Extra extensions from the ramdisk if isn't aliased as bt(0,0).
154#ifndef OPTION_ROM
155// First try a specfic OS version folder ie 10.5
156sprintf(dirSpecExtra, "rd(0,0)/Extra/%s/", &gMacOSVersion);
157if (FileLoadDrivers(dirSpecExtra, 0) != 0)
158{
159// Next we'll try the base
160strcpy(dirSpecExtra, "rd(0,0)/Extra/");
161FileLoadDrivers(dirSpecExtra, 0);
162}
163#endif
164
165// First try a specfic OS version folder ie 10.5
166sprintf(dirSpecExtra, "/Extra/%s/", &gMacOSVersion);
167if (FileLoadDrivers(dirSpecExtra, 0) != 0)
168{
169// Next try to load Extra extensions from the selected root partition.
170strcpy(dirSpecExtra, "/Extra/");
171if (FileLoadDrivers(dirSpecExtra, 0) != 0)
172{
173// If failed, then try to load Extra extensions from the boot partition
174// in case we have a separate booter partition or a bt(0,0) aliased ramdisk.
175if ( !(gBIOSBootVolume->biosdev == gBootVolume->biosdev && gBIOSBootVolume->part_no == gBootVolume->part_no)
176#ifndef OPTION_ROM
177|| (gRAMDiskVolume && gRAMDiskBTAliased) )
178#else
179)
180#endif
181{
182// First try a specfic OS version folder ie 10.5
183sprintf(dirSpecExtra, "bt(0,0)/Extra/%s/", &gMacOSVersion);
184if (FileLoadDrivers(dirSpecExtra, 0) != 0)
185{
186// Next we'll try the base
187strcpy(dirSpecExtra, "bt(0,0)/Extra/");
188verbose(sLoadExtra, dirSpecExtra);
189FileLoadDrivers(dirSpecExtra, 0);
190}
191}
192}
193
194}
195// TODO: fix this, the order does matter, and it's not correct now.
196// Also try to load Extensions from boot helper partitions.
197if (gBootVolume->flags & kBVFlagBooter)
198{
199strcpy(dirSpecExtra, "/com.apple.boot.P/System/Library/");
200if (FileLoadDrivers(dirSpecExtra, 0) != 0)
201{
202strcpy(dirSpecExtra, "/com.apple.boot.R/System/Library/");
203if (FileLoadDrivers(dirSpecExtra, 0) != 0)
204{
205strcpy(dirSpecExtra, "/com.apple.boot.S/System/Library/");
206FileLoadDrivers(dirSpecExtra, 0);
207}
208}
209}
210
211if (gMKextName[0] != '\0')
212{
213verbose("LoadDrivers: Loading from [%s]\n", gMKextName);
214if ( LoadDriverMKext(gMKextName) != 0 )
215{
216error("Could not load %s\n", gMKextName);
217return -1;
218}
219}
220else
221{
222strcpy(gExtensionsSpec, dirSpec);
223strcat(gExtensionsSpec, "System/Library/");
224FileLoadDrivers(gExtensionsSpec, 0);
225}
226}
227else
228{
229return 0;
230}
231
232 MatchPersonalities();
233
234 MatchLibraries();
235
236 LoadMatchedModules();
237
238 return 0;
239}
240
241//==========================================================================
242// FileLoadMKext
243
244static long
245FileLoadMKext( const char * dirSpec, const char * extDirSpec )
246{
247long ret, flags, time, time2;
248char altDirSpec[512];
249
250sprintf (altDirSpec, "%s%s", dirSpec, extDirSpec);
251ret = GetFileInfo(altDirSpec, "Extensions.mkext", &flags, &time);
252if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeFlat))
253{
254ret = GetFileInfo(dirSpec, "Extensions", &flags, &time2);
255if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeDirectory) ||
256(((gBootMode & kBootModeSafe) == 0) && (time == (time2 + 1))))
257{
258sprintf(gDriverSpec, "%sExtensions.mkext", altDirSpec);
259verbose("LoadDrivers: Loading from [%s]\n", gDriverSpec);
260if (LoadDriverMKext(gDriverSpec) == 0) return 0;
261}
262}
263return -1;
264}
265
266//==========================================================================
267// FileLoadDrivers
268
269long
270FileLoadDrivers( char * dirSpec, long plugin )
271{
272 long ret, length, flags, time, bundleType;
273 long long index;
274 long result = -1;
275 const char * name;
276
277 if ( !plugin )
278 {
279 // First try 10.6's path for loading Extensions.mkext.
280 if (FileLoadMKext(dirSpec, "Caches/com.apple.kext.caches/Startup/") == 0)
281return 0;
282
283 // Next try the legacy path.
284 else if (FileLoadMKext(dirSpec, "") == 0)
285return 0;
286
287 strcat(dirSpec, "Extensions");
288 }
289
290 index = 0;
291 while (1) {
292 ret = GetDirEntry(dirSpec, &index, &name, &flags, &time);
293 if (ret == -1) break;
294
295 // Make sure this is a directory.
296 if ((flags & kFileTypeMask) != kFileTypeDirectory) continue;
297
298 // Make sure this is a kext.
299 length = strlen(name);
300 if (strcmp(name + length - 5, ".kext")) continue;
301
302 // Save the file name.
303 strcpy(gFileName, name);
304
305 // Determine the bundle type.
306 sprintf(gTempSpec, "%s/%s", dirSpec, gFileName);
307 ret = GetFileInfo(gTempSpec, "Contents", &flags, &time);
308 if (ret == 0) bundleType = kCFBundleType2;
309 else bundleType = kCFBundleType3;
310
311 if (!plugin)
312 sprintf(gDriverSpec, "%s/%s/%sPlugIns", dirSpec, gFileName,
313 (bundleType == kCFBundleType2) ? "Contents/" : "");
314
315 ret = LoadDriverPList(dirSpec, gFileName, bundleType);
316
317 if (result != 0)
318result = ret;
319
320 if (!plugin)
321 FileLoadDrivers(gDriverSpec, 1); //Slice - "result =" as in RC3
322 }
323
324 return result;
325}
326
327//==========================================================================
328//
329#ifndef OPTION_ROM
330long
331NetLoadDrivers( char * dirSpec )
332{
333 long tries;
334
335#if NODEF
336 long cnt;
337
338 // Get the name of the kernel
339 cnt = strlen(gBootFile);
340 while (cnt--) {
341 if ((gBootFile[cnt] == '\\') || (gBootFile[cnt] == ',')) {
342cnt++;
343break;
344 }
345 }
346#endif
347
348 // INTEL modification
349 sprintf(gDriverSpec, "%s%s.mkext", dirSpec, bootInfo->bootFile);
350
351 verbose("NetLoadDrivers: Loading from [%s]\n", gDriverSpec);
352
353 tries = 3;
354 while (tries--)
355 {
356 if (LoadDriverMKext(gDriverSpec) == 0) break;
357 }
358 if (tries == -1) return -1;
359
360 return 0;
361}
362#endif
363//==========================================================================
364// loadDriverMKext
365
366long
367LoadDriverMKext( char * fileSpec )
368{
369 unsigned long driversAddr, driversLength;
370 long length;
371 char segName[32];
372 DriversPackage * package;
373
374#define GetPackageElement(e) OSSwapBigToHostInt32(package->e)
375
376 // Load the MKext.
377 length = LoadThinFatFile(fileSpec, (void **)&package);
378 if (length < sizeof (DriversPackage)) return -1;
379
380// call hook to notify modules that the mkext has been loaded
381execute_hook("LoadDriverMKext", (void*)fileSpec, (void*)package, (void*) &length, NULL);
382
383
384 // Verify the MKext.
385 if (( GetPackageElement(signature1) != kDriverPackageSignature1) ||
386 ( GetPackageElement(signature2) != kDriverPackageSignature2) ||
387 ( GetPackageElement(length) > kLoadSize ) ||
388 ( GetPackageElement(alder32) !=
389 Adler32((unsigned char *)&package->version, GetPackageElement(length) - 0x10) ) )
390 {
391 return -1;
392 }
393
394 // Make space for the MKext.
395 driversLength = GetPackageElement(length);
396 driversAddr = AllocateKernelMemory(driversLength);
397
398 // Copy the MKext.
399 memcpy((void *)driversAddr, (void *)package, driversLength);
400
401 // Add the MKext to the memory map.
402 sprintf(segName, "DriversPackage-%lx", driversAddr);
403 AllocateMemoryRange(segName, driversAddr, driversLength,
404 kBootDriverTypeMKEXT);
405
406 return 0;
407}
408
409//==========================================================================
410// LoadDriverPList
411
412long
413LoadDriverPList( char * dirSpec, char * name, long bundleType )
414{
415 long length, executablePathLength, bundlePathLength;
416 ModulePtr module;
417 TagPtr personalities;
418 char * buffer = 0;
419 char * tmpExecutablePath = 0;
420 char * tmpBundlePath = 0;
421 long ret = -1;
422
423 do {
424 // Save the driver path.
425
426 sprintf(gFileSpec, "%s/%s/%s", dirSpec, name,
427 (bundleType == kCFBundleType2) ? "Contents/MacOS/" : "");
428 executablePathLength = strlen(gFileSpec) + 1;
429
430 tmpExecutablePath = malloc(executablePathLength);
431 if (tmpExecutablePath == 0) break;
432
433 strcpy(tmpExecutablePath, gFileSpec);
434
435 sprintf(gFileSpec, "%s/%s", dirSpec, name);
436 bundlePathLength = strlen(gFileSpec) + 1;
437
438 tmpBundlePath = malloc(bundlePathLength);
439 if (tmpBundlePath == 0) break;
440
441 strcpy(tmpBundlePath, gFileSpec);
442
443 // Construct the file spec to the plist, then load it.
444
445 sprintf(gFileSpec, "%s/%s/%sInfo.plist", dirSpec, name,
446 (bundleType == kCFBundleType2) ? "Contents/" : "");
447
448 length = LoadFile(gFileSpec);
449 if (length == -1) break;
450
451 length = length + 1;
452 buffer = malloc(length);
453 if (buffer == 0) break;
454
455 strlcpy(buffer, (char *)kLoadAddr, length);
456
457 // Parse the plist.
458
459 ret = ParseXML(buffer, &module, &personalities);
460 if (ret != 0) { break; }
461
462 // Allocate memory for the driver path and the plist.
463
464 module->executablePath = tmpExecutablePath;
465 module->bundlePath = tmpBundlePath;
466 module->bundlePathLength = bundlePathLength;
467 module->plistAddr = malloc(length);
468
469 if ((module->executablePath == 0) || (module->bundlePath == 0) || (module->plistAddr == 0))
470 break;
471
472 // Save the driver path in the module.
473 //strcpy(module->driverPath, tmpDriverPath);
474 tmpExecutablePath = 0;
475 tmpBundlePath = 0;
476
477 // Add the plist to the module.
478
479 strlcpy(module->plistAddr, (char *)kLoadAddr, length);
480 module->plistLength = length;
481
482 // Add the module to the end of the module list.
483
484 if (gModuleHead == 0)
485 gModuleHead = module;
486 else
487 gModuleTail->nextModule = module;
488 gModuleTail = module;
489
490 // Add the persionalities to the personality list.
491
492 if (personalities) personalities = personalities->tag;
493 while (personalities != 0)
494 {
495 if (gPersonalityHead == 0)
496 gPersonalityHead = personalities->tag;
497 else
498 gPersonalityTail->tagNext = personalities->tag;
499
500 gPersonalityTail = personalities->tag;
501 personalities = personalities->tagNext;
502 }
503
504 ret = 0;
505 }
506 while (0);
507
508 if ( buffer ) free( buffer );
509 if ( tmpExecutablePath ) free( tmpExecutablePath );
510 if ( tmpBundlePath ) free( tmpBundlePath );
511
512 return ret;
513}
514
515
516//==========================================================================
517// LoadMatchedModules
518
519long LoadMatchedModules( void )
520{
521 TagPtr prop;
522 ModulePtr module;
523 char *fileName, segName[32];
524 DriverInfoPtr driver;
525 long length, driverAddr, driverLength;
526 void *executableAddr = 0;
527
528
529 module = gModuleHead;
530
531 while (module != 0)
532 {
533 if (module->willLoad)
534 {
535 prop = XMLGetProperty(module->dict, kPropCFBundleExecutable);
536
537 if (prop != 0)
538 {
539 fileName = prop->string;
540 sprintf(gFileSpec, "%s%s", module->executablePath, fileName);
541 length = LoadThinFatFile(gFileSpec, &executableAddr);
542if (length == 0)
543{
544length = LoadFile(gFileSpec);
545executableAddr = (void *)kLoadAddr;
546}
547 //printf("%s length = %d addr = 0x%x\n", gFileSpec, length, driverModuleAddr); getc();
548 }
549 else
550 length = 0;
551
552 if (length != -1)
553 {
554//driverModuleAddr = (void *)kLoadAddr;
555 //if (length != 0)
556 //{
557// ThinFatFile(&driverModuleAddr, &length);
558//}
559
560 // Make make in the image area.
561
562execute_hook("LoadMatchedModules", module, &length, executableAddr, NULL);
563
564 driverLength = sizeof(DriverInfo) + module->plistLength + length + module->bundlePathLength;
565 driverAddr = AllocateKernelMemory(driverLength);
566
567 // Set up the DriverInfo.
568 driver = (DriverInfoPtr)driverAddr;
569 driver->plistAddr = (char *)(driverAddr + sizeof(DriverInfo));
570 driver->plistLength = module->plistLength;
571 if (length != 0)
572 {
573 driver->executableAddr = (void *)(driverAddr + sizeof(DriverInfo) +
574 module->plistLength);
575 driver->executableLength = length;
576 }
577 else
578 {
579 driver->executableAddr = 0;
580 driver->executableLength = 0;
581 }
582 driver->bundlePathAddr = (void *)(driverAddr + sizeof(DriverInfo) +
583 module->plistLength + driver->executableLength);
584 driver->bundlePathLength = module->bundlePathLength;
585
586 // Save the plist, module and bundle.
587 strcpy(driver->plistAddr, module->plistAddr);
588 if (length != 0)
589 {
590 memcpy(driver->executableAddr, executableAddr, length);
591 }
592 strcpy(driver->bundlePathAddr, module->bundlePath);
593
594 // Add an entry to the memory map.
595 sprintf(segName, "Driver-%lx", (unsigned long)driver);
596 AllocateMemoryRange(segName, driverAddr, driverLength,
597 kBootDriverTypeKEXT);
598 }
599 }
600 module = module->nextModule;
601 }
602
603 return 0;
604}
605
606//==========================================================================
607// MatchPersonalities
608
609long MatchPersonalities( void )
610{
611 /* IONameMatch support not implemented */
612 return 0;
613}
614
615//==========================================================================
616// MatchLibraries
617
618long MatchLibraries( void )
619{
620 TagPtr prop, prop2;
621 ModulePtr module, module2;
622 long done;
623
624 do {
625 done = 1;
626 module = gModuleHead;
627
628 while (module != 0)
629 {
630 if (module->willLoad == 1)
631 {
632 prop = XMLGetProperty(module->dict, kPropOSBundleLibraries);
633 if (prop != 0)
634 {
635 prop = prop->tag;
636 while (prop != 0)
637 {
638 module2 = gModuleHead;
639 while (module2 != 0)
640 {
641 prop2 = XMLGetProperty(module2->dict, kPropCFBundleIdentifier);
642 if ((prop2 != 0) && (!strcmp(prop->string, prop2->string)))
643 {
644 if (module2->willLoad == 0) module2->willLoad = 1;
645 break;
646 }
647 module2 = module2->nextModule;
648 }
649 prop = prop->tagNext;
650 }
651 }
652 module->willLoad = 2;
653 done = 0;
654 }
655 module = module->nextModule;
656 }
657 }
658 while (!done);
659
660 return 0;
661}
662
663
664//==========================================================================
665// FindModule
666
667#if NOTDEF
668static ModulePtr
669FindModule( char * name )
670{
671 ModulePtr module;
672 TagPtr prop;
673
674 module = gModuleHead;
675
676 while (module != 0)
677 {
678 prop = GetProperty(module->dict, kPropCFBundleIdentifier);
679 if ((prop != 0) && !strcmp(name, prop->string)) break;
680 module = module->nextModule;
681 }
682
683 return module;
684}
685#endif /* NOTDEF */
686
687//==========================================================================
688// ParseXML
689
690static long
691ParseXML( char * buffer, ModulePtr * module, TagPtr * personalities )
692{
693long length, pos;
694TagPtr moduleDict, required;
695ModulePtr tmpModule;
696
697 pos = 0;
698
699 while (1)
700 {
701 length = XMLParseNextTag(buffer + pos, &moduleDict);
702 if (length == -1) break;
703
704 pos += length;
705
706 if (moduleDict == 0) continue;
707 if (moduleDict->type == kTagTypeDict) break;
708
709 XMLFreeTag(moduleDict);
710 }
711
712 if (length == -1) return -1;
713
714 required = XMLGetProperty(moduleDict, kPropOSBundleRequired);
715 if ( (required == 0) ||
716(required->type != kTagTypeString) ||
717!strcmp(required->string, "Safe Boot"))
718 {
719 XMLFreeTag(moduleDict);
720 return -2;
721 }
722
723 tmpModule = (ModulePtr)malloc(sizeof(Module));
724 if (tmpModule == 0)
725 {
726 XMLFreeTag(moduleDict);
727 return -1;
728 }
729 tmpModule->dict = moduleDict;
730
731 // For now, load any module that has OSBundleRequired != "Safe Boot".
732
733 tmpModule->willLoad = 1;
734
735 *module = tmpModule;
736
737 // Get the personalities.
738
739 *personalities = XMLGetProperty(moduleDict, kPropIOKitPersonalities);
740
741 return 0;
742}
743
744#if NOTDEF
745static char gPlatformName[64];
746#endif
747
748long
749DecodeKernel(void *binary, entry_t *rentry, char **raddr, int *rsize)
750{
751 long ret;
752 compressed_kernel_header * kernel_header = (compressed_kernel_header *) binary;
753 u_int32_t uncompressed_size, size;
754 void *buffer;
755unsigned long len;
756
757#if 0
758 verbose("kernel header:\n");
759 verbose("signature: 0x%x\n", kernel_header->signature);
760 verbose("compress_type: 0x%x\n", kernel_header->compress_type);
761 verbose("adler32: 0x%x\n", kernel_header->adler32);
762 verbose("uncompressed_size: 0x%x\n", kernel_header->uncompressed_size);
763 verbose("compressed_size: 0x%x\n", kernel_header->compressed_size);
764 getc();
765#endif
766
767 if (kernel_header->signature == OSSwapBigToHostConstInt32('comp')) {
768 if (kernel_header->compress_type != OSSwapBigToHostConstInt32('lzss')) {
769 error("kernel compression is bad\n");
770 return -1;
771 }
772#if NOTDEF
773 if (kernel_header->platform_name[0] && strcmp(gPlatformName, kernel_header->platform_name))
774 return -1;
775 if (kernel_header->root_path[0] && strcmp(gBootFile, kernel_header->root_path))
776 return -1;
777#endif
778
779 uncompressed_size = OSSwapBigToHostInt32(kernel_header->uncompressed_size);
780 binary = buffer = malloc(uncompressed_size);
781
782 size = decompress_lzss((u_int8_t *) binary, &kernel_header->data[0],
783 OSSwapBigToHostInt32(kernel_header->compressed_size));
784 if (uncompressed_size != size) {
785 error("size mismatch from lzss: %x\n", size);
786 return -1;
787 }
788 if (OSSwapBigToHostInt32(kernel_header->adler32) !=
789 Adler32(binary, uncompressed_size)) {
790 verbose("adler mismatch\n");
791 return -1;
792 }
793 }
794
795ret = ThinFatFile(&binary, &len);
796if (ret == 0 && len == 0 && archCpuType==CPU_TYPE_X86_64)
797{
798archCpuType=CPU_TYPE_I386;
799ret = ThinFatFile(&binary, &len);
800}
801
802//patch_kernel(binary);
803
804ret = DecodeMachO(binary, rentry, raddr, rsize);
805
806if (ret<0 && archCpuType==CPU_TYPE_X86_64)
807{
808archCpuType=CPU_TYPE_I386;
809ret = DecodeMachO(binary, rentry, raddr, rsize);
810}
811
812
813return ret;
814}
815

Archive Download this file

Revision: 689