Chameleon Applications

Chameleon Applications Svn Source Tree

Root/branches/iFabio/Chameleon/i386/boot2/drivers.c

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

Archive Download this file

Revision: 307