]> git.saurik.com Git - apple/bootx.git/blobdiff - bootx.tproj/sl.subproj/macho.c
BootX-59.tar.gz
[apple/bootx.git] / bootx.tproj / sl.subproj / macho.c
index b2ef134687f1a2aa6c6cb7957e04368836c2e24b..c352e67513c88b64d8d407f660ccbdd659f5b5ed 100644 (file)
@@ -3,26 +3,29 @@
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
  * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
 /*
  *  macho.c - Functions for decoding a Mach-o Kernel.
  *
- *  Copyright (c) 1998-2000 Apple Computer, Inc.
+ *  Copyright (c) 1998-2003 Apple Computer, Inc.
  *
  *  DRI: Josh de Cesare
  */
@@ -37,33 +40,56 @@ static long DecodeSegment(long cmdBase);
 static long DecodeUnixThread(long cmdBase);
 static long DecodeSymbolTable(long cmdBase);
 
-static long gPPCOffset;
+static unsigned long gPPCAddress;
 
 // Public Functions
 
-long DecodeMachO(void)
+long ThinFatBinaryMachO(void **binary, unsigned long *length)
+{
+  unsigned long nfat, swapped, size;
+  struct fat_header *fhp = (struct fat_header *)*binary;
+  struct fat_arch   *fap =
+    (struct fat_arch *)((unsigned long)*binary + sizeof(struct fat_header));
+  
+  if (fhp->magic == FAT_MAGIC) {
+    nfat = fhp->nfat_arch;
+    swapped = 0;
+  } else if (fhp->magic == FAT_CIGAM) {
+    nfat = NXSwapInt(fhp->nfat_arch);
+    swapped = 1;
+  } else {
+    return -1;
+  }
+  
+  for (; nfat > 0; nfat--, fap++) {
+    if (swapped) {
+      fap->cputype = NXSwapInt(fap->cputype);
+      fap->offset = NXSwapInt(fap->offset);
+      fap->size = NXSwapInt(fap->size);
+    }
+    
+    if (fap->cputype == CPU_TYPE_POWERPC) {
+      *binary = (void *) ((unsigned long)*binary + fap->offset);
+      size = fap->size;
+      break;
+    }
+  }
+  
+  if (length != 0) *length = size;
+  
+  return 0;
+}
+
+long DecodeMachO(void *binary)
 {
-  struct fat_header  *fH;
-  struct fat_arch    *fA;
   struct mach_header *mH;
   long   ncmds, cmdBase, cmd, cmdsize, headerBase, headerAddr, headerSize;
   long   cnt, ret;
   
-  // Test for a fat header.
-  fH = (struct fat_header *)kLoadAddr;
-  if (fH->magic == FAT_MAGIC) {
-    fA = (struct fat_arch *)(kLoadAddr + sizeof(struct fat_header));
-    // see if the there is one for PPC.
-    for (cnt = 0; cnt < fH->nfat_arch; cnt++) {
-      if (fA[cnt].cputype == CPU_TYPE_POWERPC) {
-       gPPCOffset = fA[cnt].offset;
-      }
-    }
-  }
+  gPPCAddress = (unsigned long)binary;
   
-  // offset will be the start of the 
-  headerBase = kLoadAddr + gPPCOffset;
-  cmdBase = headerBase+ sizeof(struct mach_header);
+  headerBase = gPPCAddress;
+  cmdBase = headerBase + sizeof(struct mach_header);
   
   mH = (struct mach_header *)(headerBase);
   if (mH->magic != MH_MAGIC) return -1;
@@ -133,7 +159,7 @@ static long DecodeSegment(long cmdBase)
   vmaddr = (char *)segCmd->vmaddr;
   vmsize = segCmd->vmsize;
   
-  fileaddr = (char *)(kLoadAddr + gPPCOffset + segCmd->fileoff);
+  fileaddr = (char *)(gPPCAddress + segCmd->fileoff);
   filesize = segCmd->filesize;
   
 #if 0
@@ -145,6 +171,9 @@ static long DecodeSegment(long cmdBase)
   // Add the Segment to the memory-map.
   sprintf(rangeName, "Kernel-%s", segCmd->segname);
   AllocateMemoryRange(rangeName, (long)vmaddr, vmsize);
+
+  if (vmsize && (strcmp(segCmd->segname, "__PRELINK") == 0))
+    gHaveKernelCache = 1;
   
   // Handle special segments first.
   
@@ -228,7 +257,7 @@ static long DecodeSymbolTable(long cmdBase)
   symTableSave->stroff = tmpAddr + symsSize;
   symTableSave->strsize = symTab->strsize;
   
-  bcopy((char *)(kLoadAddr + gPPCOffset + symTab->symoff),
+  bcopy((char *)(gPPCAddress + symTab->symoff),
        (char *)tmpAddr, totalSize);
   
   return 0;