Chameleon

Chameleon Svn Source Tree

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

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

Archive Download this file

Revision: 1146