X-Git-Url: https://git.saurik.com/apple/bootx.git/blobdiff_plain/04fee52ee8aaaa7cd8b91379e26320dc877075f7..HEAD:/bootx.tproj/sl.subproj/macho.c diff --git a/bootx.tproj/sl.subproj/macho.c b/bootx.tproj/sl.subproj/macho.c index b2ef134..333cbe1 100644 --- a/bootx.tproj/sl.subproj/macho.c +++ b/bootx.tproj/sl.subproj/macho.c @@ -22,11 +22,12 @@ /* * 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 #include #include @@ -37,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; @@ -133,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 @@ -145,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. @@ -182,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; @@ -228,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;