]> git.saurik.com Git - apple/bootx.git/blobdiff - bootx.tproj/sl.subproj/macho.c
BootX-81.tar.gz
[apple/bootx.git] / bootx.tproj / sl.subproj / macho.c
index 29604048dbce8470552feeefc03fbf112ed9763c..333cbe135638f2018b8621438a47e3a4a8678b46 100644 (file)
@@ -3,33 +3,31 @@
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
- * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
+ * 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.
  * 
- * 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
+ * This 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE 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
  */
 
+#define __srr0 srr0                    // so we can build in both (conformant/not) worlds
 #include <mach-o/fat.h>
 #include <mach-o/loader.h>
 #include <mach/machine/thread_status.h>
@@ -40,33 +38,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)
 {
-  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;
-      }
+  unsigned long nfat, swapped, size = 0;
+  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;
     }
   }
   
-  // offset will be the start of the 
-  headerBase = kLoadAddr + gPPCOffset;
-  cmdBase = headerBase+ sizeof(struct mach_header);
+  if (length != 0) *length = size;
+  
+  return 0;
+}
+
+long DecodeMachO(void *binary)
+{
+  struct mach_header *mH;
+  long   ncmds, cmdBase, cmd, cmdsize, headerBase, headerAddr, headerSize;
+  long   cnt, ret = 0;
+  
+  gPPCAddress = (unsigned long)binary;
+  
+  headerBase = gPPCAddress;
+  cmdBase = headerBase + sizeof(struct mach_header);
   
   mH = (struct mach_header *)(headerBase);
   if (mH->magic != MH_MAGIC) return -1;
@@ -136,7 +157,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
@@ -148,6 +169,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.
   
@@ -185,11 +209,11 @@ static long DecodeSegment(long cmdBase)
 
 static long DecodeUnixThread(long cmdBase)
 {
-  struct ppc_thread_state *ppcThreadState;
+  ppc_thread_state_t *ppcThreadState;
   
   // The PPC Thread State starts after the thread command stuct plus,
   // 2 longs for the flaver an num longs.
-  ppcThreadState = (struct ppc_thread_state *)
+  ppcThreadState = (ppc_thread_state_t *)
     (cmdBase + sizeof(struct thread_command) + 8);
   
   gKernelEntryPoint = ppcThreadState->srr0;
@@ -231,7 +255,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;