Index: branches/xZen/src/arm/Make.rules =================================================================== --- branches/xZen/src/arm/Make.rules (revision 1246) +++ branches/xZen/src/arm/Make.rules (revision 1247) @@ -30,5 +30,12 @@ -MD -dependency-file $(OBJROOT)/$*.d @md -u $(OBJROOT)/Makedep -f -d $(OBJROOT)/$*.d +$(OBJROOT)/%.armo: %.s + @echo "\t[AS:I386] $<" + @$(ARM_CC) $(CPPFLAGS) -c $(INC) -arch arm -o $@ $< \ + -MD -dependency-file $*.d + @md -u $(OBJROOT)/Makedep -f -d $*.d + + ACTUAL_OBJECTS := ${ACTUAL_OBJECTS} $(addsuffix .armo, $(addprefix $(OBJROOT)/, $(OBJECTS))) MODULE_OBJECTS := ${MODULE_OBJECTS} $(addsuffix .armo, $(addprefix $(OBJROOT)/, $(MODULE_OBJS))) Index: branches/xZen/src/ppc/Make.rules =================================================================== --- branches/xZen/src/ppc/Make.rules (revision 1246) +++ branches/xZen/src/ppc/Make.rules (revision 1247) @@ -30,5 +30,12 @@ -MD -dependency-file $(OBJROOT)/$*.d @md -u $(OBJROOT)/Makedep -f -d $(OBJROOT)/$*.d +$(OBJROOT)/%.ppco: %.s + @echo "\t[AS:PPC] $<" + @$(PPC_CC) $(CPPFLAGS) -c $(INC) -arch ppc -o $@ $< \ + -MD -dependency-file $*.d + @md -u $(OBJROOT)/Makedep -f -d $*.d + + ACTUAL_OBJECTS := ${ACTUAL_OBJECTS} $(addsuffix .ppco, $(addprefix $(OBJROOT)/, $(OBJECTS))) MODULE_OBJECTS := ${MODULE_OBJECTS} $(addsuffix .ppco, $(addprefix $(OBJROOT)/, $(MODULE_OBJS))) Index: branches/xZen/src/include/unwind.h =================================================================== --- branches/xZen/src/include/unwind.h (revision 1246) +++ branches/xZen/src/include/unwind.h (revision 1247) @@ -38,7 +38,10 @@ #ifdef __cplusplus extern "C" { #endif + + typedef unsigned _Unwind_Exception_Class __attribute__((__mode__(__DI__))); + /* Level 1: Base ABI */ /* @@@ The IA-64 ABI uses uint64 throughout. Most places this is @@ -56,7 +59,6 @@ consumer of an exception. We'll go along with this for now even on 32-bit machines. We'll need to provide some other option for 16-bit machines and for machines with > 8 bits per byte. */ -typedef unsigned _Unwind_Exception_Class __attribute__((__mode__(__DI__))); /* The unwind interface uses reason codes in several contexts to identify the reasons for failures or other actions. */ Index: branches/xZen/src/Make.rules =================================================================== --- branches/xZen/src/Make.rules (revision 1246) +++ branches/xZen/src/Make.rules (revision 1247) @@ -1,6 +1,7 @@ -include $(SRCROOT)/auto.conf -include ${SRCROOT}/i386/Make.rules +#-include ${SRCROOT}/x86_64/Make.rules -include ${SRCROOT}/ppc/Make.rules -include ${SRCROOT}/arm/Make.rules Index: branches/xZen/src/modules/uClibcxx/Makefile =================================================================== --- branches/xZen/src/modules/uClibcxx/Makefile (revision 1246) +++ branches/xZen/src/modules/uClibcxx/Makefile (revision 1247) @@ -7,16 +7,16 @@ MODULE_DEPENDENCIES = klibc DIR = uClibc++ -# sstream.o fstream.o -MODULE_OBJS = uClibc++.o abi.o algorithm.o associative_base.o bitset.o \ - complex.o del_op.o del_opnt.o del_opv.o del_opvnt.o \ - deque.o eh_alloc.o eh_globals.o exception.o \ - func_exception.o iomanip.o char_traits.o \ - iterator.o limits.o list.o locale.o \ - map.o new_handler.o new_op.o new_opnt.o new_opv.o \ - new_opvnt.o numeric.o queue.o set.o \ - stack.o stdexcept.o streambuf.o string.o typeinfo.o \ - utility.o valarray.o vector.o support.o \ - ios.o iostream.o istream.o ostream.o +# sstream fstream +MODULE_OBJS = uClibc++ abi algorithm associative_base bitset \ + complex del_op del_opnt del_opv del_opvnt \ + deque eh_alloc eh_globals exception \ + func_exception iomanip char_traits \ + iterator limits list locale \ + map new_handler new_op new_opnt new_opv \ + new_opvnt numeric queue set \ + stack stdexcept streambuf string typeinfo \ + utility valarray vector support \ + ios iostream istream ostream include ../MakeInc.dir \ No newline at end of file Index: branches/xZen/src/modules/uClibcxx/include/unwind-cxx.h =================================================================== --- branches/xZen/src/modules/uClibcxx/include/unwind-cxx.h (revision 1246) +++ branches/xZen/src/modules/uClibcxx/include/unwind-cxx.h (revision 1247) @@ -38,7 +38,7 @@ #include #include #include -#include "unwind.h" +#include #pragma GCC visibility push(default) @@ -135,30 +135,6 @@ // The current installed user handlers. extern std::terminate_handler __terminate_handler; extern std::unexpected_handler __unexpected_handler; - -// These are explicitly GNU C++ specific. - -// This is the exception class we report -- "GNUCC++\0". -const _Unwind_Exception_Class __gxx_exception_class -= ((((((((_Unwind_Exception_Class) 'G' - << 8 | (_Unwind_Exception_Class) 'N') - << 8 | (_Unwind_Exception_Class) 'U') - << 8 | (_Unwind_Exception_Class) 'C') - << 8 | (_Unwind_Exception_Class) 'C') - << 8 | (_Unwind_Exception_Class) '+') - << 8 | (_Unwind_Exception_Class) '+') - << 8 | (_Unwind_Exception_Class) '\0'); - -// GNU C++ personality routine, Version 0. -extern "C" _Unwind_Reason_Code __gxx_personality_v0 - (int, _Unwind_Action, _Unwind_Exception_Class, - struct _Unwind_Exception *, struct _Unwind_Context *); - -// GNU C++ sjlj personality routine, Version 0. -extern "C" _Unwind_Reason_Code __gxx_personality_sj0 - (int, _Unwind_Action, _Unwind_Exception_Class, - struct _Unwind_Exception *, struct _Unwind_Context *); - #ifdef __UCLIBCXX_EXCEPTION_SUPPORT__ // Acquire the C++ exception header from the C++ object. Index: branches/xZen/src/modules/FileSystem/HFS/Makefile =================================================================== --- branches/xZen/src/modules/FileSystem/HFS/Makefile (revision 1246) +++ branches/xZen/src/modules/FileSystem/HFS/Makefile (revision 1247) @@ -8,6 +8,6 @@ DIR = HelloWorld -MODULE_OBJS = HelloWorld.o +MODULE_OBJS = HelloWorld include ../MakeInc.dir \ No newline at end of file Index: branches/xZen/src/modules/FileSystem/Makefile =================================================================== --- branches/xZen/src/modules/FileSystem/Makefile (revision 1246) +++ branches/xZen/src/modules/FileSystem/Makefile (revision 1247) @@ -9,6 +9,6 @@ DIR = HelloWorld SUBDIRS = HFS -MODULE_OBJS = Main.o FileSystem.o +MODULE_OBJS = Main FileSystem include ../MakeInc.dir \ No newline at end of file Index: branches/xZen/src/modules/MakeInc.dir =================================================================== --- branches/xZen/src/modules/MakeInc.dir (revision 1246) +++ branches/xZen/src/modules/MakeInc.dir (revision 1247) @@ -10,47 +10,48 @@ override OBJROOT = $(ROOT)/obj/boot2_modules/$(DIR) endif -include ${ROOT}/Make.rules - ifeq ($(BUILT_IN),yes) -CFLAGS := $(RC_CFLAGS) $(OPTIM) $(MORECPP) -arch i386 -g -Wmost -Werror \ - -fno-builtin -DSAIO_INTERNAL_USER -static $(OMIT_FRAME_POINTER_CFLAG) \ - -mpreferred-stack-boundary=2 -fno-align-functions -fno-stack-protector \ - -march=pentium4 -msse2 -mfpmath=sse -msoft-float -nostdinc -include $(SRCROOT)/autoconf.h +CFLAGS := $(RC_CFLAGS) $(OPTIM) $(MORECPP) -g -Wmost -Werror \ + -fno-builtin -DSAIO_INTERNAL_USER $(OMIT_FRAME_POINTER_CFLAG) \ + -fno-align-functions -fno-stack-protector \ + -msoft-float -nostdinc -include $(SRCROOT)/autoconf.h -CPPFLAGS := $(CPPFLAGS) -arch i386 -static -nostdinc++ -Wmost -Werror \ - -fno-builtin -mpreferred-stack-boundary=2 \ - -fno-align-functions -fno-stack-protector \ - -march=pentium4 -msse2 -mfpmath=sse -msoft-float \ - -arch i386 -include $(SRCROOT)/autoconf.h +CPPFLAGS := $(CPPFLAGS) -nostdinc++ -Wmost -Werror \ + -fno-builtin -msoft-float \ + -fno-rtti -fno-exceptions \ + -include $(SRCROOT)/autoconf.h else CFLAGS := $(CLFAGS) -nostdinc -Wmost -Werror \ - -fno-builtin -mpreferred-stack-boundary=2 \ + -fno-builtin \ -fno-align-functions -fno-stack-protector \ - -march=pentium4 -msse2 -mfpmath=sse -msoft-float \ - -arch i386 -include $(SRCROOT)/autoconf.h + -msoft-float \ + -include $(SRCROOT)/autoconf.h CPPFLAGS := $(CPPFLAGS) -nostdinc++ -Wmost -Werror \ - -fno-builtin -mpreferred-stack-boundary=2 \ + -fno-builtin \ -fno-align-functions -fno-stack-protector \ - -march=pentium4 -msse2 -mfpmath=sse -msoft-float \ - -arch i386 -include $(SRCROOT)/autoconf.h + -msoft-float \ + -fno-rtti -fno-exceptions \ + -include $(SRCROOT)/autoconf.h endif +include ${ROOT}/Make.rules + + UTILDIR = ../../util LIBSADIR = ../../libsa LIBSAIODIR = ../../libsaio BOOT2DIR = ../../boot2 -MODULE_INCLUDES := $(foreach x,ModuleSystem $(MODULE_DEPENDENCIES),-I$(SRCROOT)/i386/modules/$(x)/include/) +MODULE_INCLUDES := $(foreach x,ModuleSystem $(MODULE_DEPENDENCIES),-I$(SRCROOT)/modules/$(x)/include/) -INC = -I$(SRCROOT)/sym/i386/ -I$(SRCROOT)/i386/modules/include/ -Iinclude/ -I$(SRCROOT)/i386/libsaio/ -I$(SRCROOT)/i386/libsa/ -I$(SRCROOT)/i386/include/ -I$(SRCROOT)/i386/boot2/ $(MODULE_INCLUDES) +INC = -I$(SRCROOT)/include/ -I$(SRCROOT)/sym/ -I$(SRCROOT)/modules/include/ -Iinclude/ -I$(SRCROOT)/i386/libsaio/ -I$(SRCROOT)/i386/libsa/ -I$(SRCROOT)/i386/include/ -I$(SRCROOT)/i386/boot2/ $(MODULE_INCLUDES) DEFINES := -D__KLIBC__ $(DEFINES) MODULE_DEPENDENCIES := $(wildcard $(foreach x,$(MODULE_DEPENDENCIES),$(SYMROOT)/$(x).dylib)) \ @@ -62,7 +63,6 @@ MODULE_DEFINITION := $(CONFIG_$(shell echo $(MODULE_NAME) | tr '[:lower:]' '[:upper:]')_MODULE) - ifeq ($(MODULE_DEFINITION),m) ifneq ($(BUILT_IN),yes) @@ -105,23 +105,58 @@ ###### Build module into the code binary ###### $(SYMROOT)/$(MODULE_NAME).dylib: $(MODULE_DEPENDENCIES) ${MODULE_OBJECTS} $(OBJROOT)/$(MODULE_NAME).desc $(OBJROOT)/$(MODULE_NAME).author Makefile - @echo "\t[LD] $(MODULE_NAME).dylib" + @echo "\t[LD:I386] $(MODULE_NAME).dylib" @ld -arch i386 -undefined dynamic_lookup \ -dylib -read_only_relocs suppress \ -S -x -Z -dead_strip_dylibs \ -no_uuid \ -current_version $(MODULE_VERSION) -compatibility_version $(MODULE_COMPAT_VERSION) \ -final_output $(MODULE_NAME) \ - $(filter %.o,$^) \ + $(filter %.i386o,$^) \ -macosx_version_min 10.6 \ -sectcreate __INFO __author $(OBJROOT)/$(MODULE_NAME).author \ -sectcreate __INFO __description $(OBJROOT)/$(MODULE_NAME).desc \ - -o $(SYMROOT)/modules/$(MODULE_NAME).dylib - + -o $(SYMROOT)/$(MODULE_NAME).i386.dylib + + @echo "\t[LD:PPC] $(MODULE_NAME).dylib" + @ld -arch ppc -undefined dynamic_lookup \ + -dylib -read_only_relocs suppress \ + -S -x -Z -dead_strip_dylibs \ + -no_uuid \ + -current_version $(MODULE_VERSION) -compatibility_version $(MODULE_COMPAT_VERSION) \ + -final_output $(MODULE_NAME) \ + $(filter %.ppco,$^) \ + /usr/lib/dylib1.o \ + -macosx_version_min 10.6 \ + -sectcreate __INFO __author $(OBJROOT)/$(MODULE_NAME).author \ + -sectcreate __INFO __description $(OBJROOT)/$(MODULE_NAME).desc \ + -o $(SYMROOT)/$(MODULE_NAME).ppc.dylib + + @echo "\t[LD:ARM] $(MODULE_NAME).dylib" + @ld -arch arm -undefined dynamic_lookup \ + -dylib -read_only_relocs suppress \ + -S -x -Z -dead_strip_dylibs \ + -no_uuid \ + -current_version $(MODULE_VERSION) -compatibility_version $(MODULE_COMPAT_VERSION) \ + -final_output $(MODULE_NAME) \ + $(filter %.armo,$^) \ + /Developer/Platforms/iPhoneOS.platform//Developer/SDKs/iPhoneOS4.3.sdk/usr/lib/dylib1.o \ + -macosx_version_min 10.6 \ + -sectcreate __INFO __author $(OBJROOT)/$(MODULE_NAME).author \ + -sectcreate __INFO __description $(OBJROOT)/$(MODULE_NAME).desc \ + -o $(SYMROOT)/$(MODULE_NAME).arm.dylib + + @echo "\t[LIPO] $(@F)" + @lipo -create -arch i386 $(SYMROOT)/$(MODULE_NAME).i386.dylib \ + -arch ppc $(SYMROOT)/$(MODULE_NAME).ppc.dylib \ + -arch arm $(SYMROOT)/$(MODULE_NAME).arm.dylib \ + -output $(SYMROOT)/$(MODULE_NAME).dylib + + @rm $(SYMROOT)/$(MODULE_NAME).i386.dylib $(SYMROOT)/$(MODULE_NAME).ppc.dylib $(SYMROOT)/$(MODULE_NAME).arm.dylib else ##### BUild module as a seperate module ##### -$(SYMROOT)/modules/$(MODULE_NAME).dylib: $(MODULE_DEPENDENCIES) ${MODULE_OBJECTS} $(OBJROOT)/$(MODULE_NAME).desc $(OBJROOT)/$(MODULE_NAME).author $(SRCROOT)/obj/i386/boot2/Symbols_LINKER_ONLY.dylib Makefile +$(SYMROOT)/$(MODULE_NAME).dylib: $(MODULE_DEPENDENCIES) ${MODULE_OBJECTS} $(OBJROOT)/$(MODULE_NAME).desc $(OBJROOT)/$(MODULE_NAME).author $(SRCROOT)/obj/i386/boot2/Symbols_LINKER_ONLY.dylib Makefile @echo "\t[LD] $(MODULE_NAME).dylib" @ld -arch i386 \ Index: branches/xZen/src/modules/klibc/memmove.c =================================================================== --- branches/xZen/src/modules/klibc/memmove.c (revision 1246) +++ branches/xZen/src/modules/klibc/memmove.c (revision 1247) @@ -1,9 +1,8 @@ /* * memmove.c */ +#include -#include "libsaio.h" - void *memmove(void *dst, const void *src, size_t n) { const char *p = src; Index: branches/xZen/src/modules/klibc/Makefile =================================================================== --- branches/xZen/src/modules/klibc/Makefile (revision 1246) +++ branches/xZen/src/modules/klibc/Makefile (revision 1247) @@ -8,20 +8,21 @@ DIR = klibc -MODULE_OBJS = klibc.o \ - __ashldi3.o __ashrdi3.o __clzsi2.o __divdi3.o __divsi3.o \ - __lshrdi3.o __moddi3.o __modsi3.o __udivdi3.o \ - __udivmoddi4.o __udivmodsi4.o __udivsi3.o \ - __umoddi3.o __umodsi3.o \ - strntoumax.o strntoimax.o atol.o atoll.o \ - strcasecmp.o strncasecmp.o strlcat.o strndup.o strnlen.o \ - strsep.o strtoimax.o strtok_r.o strtok.o strtol.o strtoll.o strtotimespec.o strtotimeval.o \ - strtoul.o strtoull.o strtoumax.o strxspn.o strpbrk.o \ - bsearch.o calloc.o \ - jrand48.o lrand48.o mrand48.o srand48.o nrand48.o seed48.o \ - memccpy.o memchr.o memmem.o memmove.o memrchr.o memswap.o \ - qsort.o sha1hash.o onexit.o atexit.o exit.o \ - snprintf.o vsnprintf.o sscanf.o vsscanf.o\ - fwrite.o fprintf.o vfprintf.o printf.o +MODULE_OBJS = klibc \ + __ashldi3 __ashrdi3 __clzsi2 __divdi3 __divsi3 \ + __lshrdi3 __moddi3 __modsi3 __udivdi3 \ + __udivmoddi4 __udivmodsi4 __udivsi3 \ + __umoddi3 __umodsi3 \ + strntoumax strntoimax atol atoll \ + strcasecmp strncasecmp strlcat strndup strnlen \ + strsep strtoimax strtok_r strtok strtol strtoll \ + strtotimespec strtotimeval \ + strtoul strtoull strtoumax strxspn strpbrk \ + bsearch calloc \ + jrand48 lrand48 mrand48 srand48 nrand48 seed48 \ + memccpy memchr memmem memmove memrchr memswap \ + qsort sha1hash onexit atexit exit \ + snprintf vsnprintf sscanf vsscanf\ + fwrite fprintf vfprintf printf include ../MakeInc.dir Index: branches/xZen/src/modules/Disk/GUIDPartition.cpp =================================================================== --- branches/xZen/src/modules/Disk/GUIDPartition.cpp (revision 1246) +++ branches/xZen/src/modules/Disk/GUIDPartition.cpp (revision 1247) @@ -47,7 +47,7 @@ UInt32 offset = (mPartitionNumber % 4) * entrySize; - mGPTEntry = (GPTEntry*) /*mLBABUffer*/ BIOS_ADDR + offset; + mGPTEntry = (GPTEntry*) mLBABUffer + offset; // TODO: verify partition type != NULL Index: branches/xZen/src/modules/Disk/Main.cpp =================================================================== --- branches/xZen/src/modules/Disk/Main.cpp (revision 1246) +++ branches/xZen/src/modules/Disk/Main.cpp (revision 1247) @@ -8,7 +8,7 @@ #include #include -#define MAXBIOSDEV 32 +#define MAXDEV 32 #define BIOSBUFFER 512 * 8 /* 4Kb */ extern "C" { @@ -17,7 +17,7 @@ } -BiosDisk* disks[MAXBIOSDEV]; +Disk* disks[MAXDEV]; UInt8 numBiosDisks = 0; UInt8* diskBuffer = NULL; @@ -25,7 +25,7 @@ void Disk_start() { - diskBuffer = (UInt8*)malloc(BIOSBUFFER); + //diskBuffer = (UInt8*)malloc(BIOSBUFFER); /*UInt8* mbr = (UInt8*)malloc(512); disk->Read(0, 1, mbr); @@ -55,7 +55,7 @@ void DetermineDisks() { - char diskName[] = "bios:/hd%s/"; + /*char diskName[] = "bios:/hd%s/"; for(int i = 0; i < MAXBIOSDEV; i++) { @@ -95,4 +95,5 @@ } } + */ } Index: branches/xZen/src/modules/Disk/Makefile =================================================================== --- branches/xZen/src/modules/Disk/Makefile (revision 1246) +++ branches/xZen/src/modules/Disk/Makefile (revision 1247) @@ -8,6 +8,7 @@ DIR = Disk -MODULE_OBJS = Disk.o BiosDisk.o Partition.o FDiskPartition.o GUIDPartition.o Main.o +#i386 only -> BiosDisk +MODULE_OBJS = Disk Partition FDiskPartition GUIDPartition Main include ../MakeInc.dir \ No newline at end of file Index: branches/xZen/src/modules/ModuleSystem/include/modules.h =================================================================== --- branches/xZen/src/modules/ModuleSystem/include/modules.h (revision 1246) +++ branches/xZen/src/modules/ModuleSystem/include/modules.h (revision 1247) @@ -92,7 +92,7 @@ long long(*symbol_handler)(char*, long long, char), void (*section_handler)(char* section, char* segment, long long offset, long long address) ); -unsigned int handle_symtable(UInt32 base, +void* handle_symtable(UInt32 base, struct symtab_command* symtabCommand, long long(*symbol_handler)(char*, long long, char), char is64); Index: branches/xZen/src/modules/ModuleSystem/macho.c =================================================================== --- branches/xZen/src/modules/ModuleSystem/macho.c (revision 0) +++ branches/xZen/src/modules/ModuleSystem/macho.c (revision 1247) @@ -0,0 +1,732 @@ +/* + * Copyright 2010 Evan Lojewski. All rights reserved. + * + */ +#ifndef CONFIG_MACHO_DEBUG +#define CONFIG_MACHO_DEBUG 0 +#endif + + +#include "boot.h" +#include "modules.h" + +extern void start_built_in_modules(); + +#if CONFIG_MACHO_DEBUG +#define DBG(x...) printf(x); +#define DBGPAUSE() getchar() +#else +#define DBG(x...) +#define DBGPAUSE() +#endif + +// NOTE: Global so that modules can link with this +UInt64 textAddress = 0; +UInt64 textSection = 0; + +/********************************************************************************/ +/* Macho Parser */ +/********************************************************************************/ + +/* + * Parse through a macho module. The module will be rebased and binded + * as specified in the macho header. If the module is sucessfuly laoded + * the module iinit address will be returned. + * NOTE; all dependecies will be loaded before this module is started + * NOTE: If the module is unable to load ot completeion, the modules + * symbols will still be available. + */ +void* parse_mach(void* binary, + int(*dylib_loader)(char*), + long long(*symbol_handler)(char*, long long, char), + void (*section_handler)(char* section, char* segment, long long offset, long long address) +) +{ + char is64 = false; + void (*module_start)(void) = NULL; + + // Module info + /*char* moduleName = NULL; + UInt32 moduleVersion = 0; + UInt32 moduleCompat = 0; + */ + // TODO convert all of the structs to a union + struct load_command *loadCommand = NULL; + struct dylib_command* dylibCommand = NULL; + struct dyld_info_command* dyldInfoCommand = NULL; + + struct symtab_command* symtabCommand = NULL; + struct segment_command *segCommand = NULL; + struct segment_command_64 *segCommand64 = NULL; + + //struct dysymtab_command* dysymtabCommand = NULL; + UInt32 binaryIndex = 0; + UInt16 cmd = 0; + + textSection = 0; + textAddress = 0; // reinitialize text location in case it doesn't exist; + + // Parse through the load commands + if(((struct mach_header*)binary)->magic == MH_MAGIC) + { + is64 = false; + binaryIndex += sizeof(struct mach_header); + } + else if(((struct mach_header_64*)binary)->magic == MH_MAGIC_64) + { + // NOTE: modules cannot be 64bit... + is64 = true; + binaryIndex += sizeof(struct mach_header_64); + } + else + { + verbose("Invalid mach magic 0x%X\n", ((struct mach_header*)binary)->magic); + //getchar(); + return NULL; + } + + + + /*if(((struct mach_header*)binary)->filetype != MH_DYLIB) + { + printf("Module is not a dylib. Unable to load.\n"); + getchar(); + return NULL; // Module is in the incorrect format + }*/ + + while(cmd < ((struct mach_header*)binary)->ncmds) + { + cmd++; + + loadCommand = binary + binaryIndex; + UInt32 cmdSize = loadCommand->cmdsize; + + + switch ((loadCommand->cmd & 0x7FFFFFFF)) + { + case LC_SYMTAB: + symtabCommand = binary + binaryIndex; + break; + + case LC_SEGMENT: // 32bit macho + { + segCommand = binary + binaryIndex; + + UInt32 sectionIndex; + + sectionIndex = sizeof(struct segment_command); + + struct section *sect; + + while(sectionIndex < segCommand->cmdsize) + { + sect = binary + binaryIndex + sectionIndex; + + sectionIndex += sizeof(struct section); + + if(section_handler) section_handler(sect->sectname, segCommand->segname, sect->offset, sect->addr); + + + + if((strcmp("__TEXT", segCommand->segname) == 0) && (strcmp("__text", sect->sectname) == 0)) + { + // __TEXT,__text found, save the offset and address for when looking for the calls. + textSection = sect->offset; + textAddress = sect->addr; + } + } + } + break; + case LC_SEGMENT_64: // 64bit macho's + { + segCommand64 = binary + binaryIndex; + UInt32 sectionIndex; + + sectionIndex = sizeof(struct segment_command_64); + + struct section_64 *sect; + + while(sectionIndex < segCommand64->cmdsize) + { + sect = binary + binaryIndex + sectionIndex; + + sectionIndex += sizeof(struct section_64); + + if(section_handler) section_handler(sect->sectname, segCommand->segname, sect->offset, sect->addr); + + + if((strcmp("__TEXT", segCommand->segname) == 0) && (strcmp("__text", sect->sectname) == 0)) + { + // __TEXT,__text found, save the offset and address for when looking for the calls. + textSection = sect->offset; + textAddress = sect->addr; + } + } + } + break; + + + case LC_LOAD_DYLIB: + case LC_LOAD_WEAK_DYLIB ^ LC_REQ_DYLD: + dylibCommand = binary + binaryIndex; + char* module = binary + binaryIndex + ((UInt32)*((UInt32*)&dylibCommand->dylib.name)); + // Possible enhancments: verify version + // = dylibCommand->dylib.current_version; + // = dylibCommand->dylib.compatibility_version; + if(dylib_loader) + { + char* name = malloc(strlen(module) + strlen(".dylib") + 1); + sprintf(name, "%s.dylib", module); + + if (!dylib_loader(name)) + { + // NOTE: any symbols exported by dep will be replace with the void function + free(name); + } + } + + break; + + case LC_ID_DYLIB: + dylibCommand = binary + binaryIndex; + /*moduleName = binary + binaryIndex + ((UInt32)*((UInt32*)&dylibCommand->dylib.name)); + moduleVersion = dylibCommand->dylib.current_version; + moduleCompat = dylibCommand->dylib.compatibility_version; + */ + break; + + case LC_DYLD_INFO: + //case LC_DYLD_INFO_ONLY: // compressed info, 10.6+ macho files, already handeled + // Bind and rebase info is stored here + dyldInfoCommand = binary + binaryIndex; + break; + + case LC_DYSYMTAB: + case LC_UUID: + case LC_UNIXTHREAD: + break; + + default: + DBG("Unhandled loadcommand 0x%X\n", loadCommand->cmd & 0x7FFFFFFF); + break; + + } + + binaryIndex += cmdSize; + } + + // bind_macho uses the symbols, if the textAdd does not exist (Symbols.dylib, no code), addresses are static and not relative + module_start = (void*)handle_symtable((UInt32)binary, symtabCommand, symbol_handler, is64); + + if(dyldInfoCommand) + { + // Rebase the module before binding it. + if(dyldInfoCommand->rebase_off) rebase_macho(binary, (char*)dyldInfoCommand->rebase_off, dyldInfoCommand->rebase_size); + // Bind all symbols. + if(dyldInfoCommand->bind_off) bind_macho(binary, (UInt8*)dyldInfoCommand->bind_off, dyldInfoCommand->bind_size); + if(dyldInfoCommand->weak_bind_off) bind_macho(binary, (UInt8*)dyldInfoCommand->weak_bind_off, dyldInfoCommand->weak_bind_size); + if(dyldInfoCommand->lazy_bind_off) bind_macho(binary, (UInt8*)dyldInfoCommand->lazy_bind_off, dyldInfoCommand->lazy_bind_size); + } + + return module_start; + +} + +/* + * parse the symbol table + * Lookup any undefined symbols + */ + +void* handle_symtable(UInt32 base, struct symtab_command* symtabCommand, long long(*symbol_handler)(char*, long long, char), char is64) +{ + + void* module_start = (void*) -1; + UInt32 symbolIndex = 0; + char* symbolString = base + (char*)symtabCommand->stroff; + + if(!is64) + { + struct nlist* symbolEntry = (void*)base + symtabCommand->symoff; + while(symbolIndex < symtabCommand->nsyms) + { + // If the symbol is exported by this module + if(symbolEntry->n_value && + symbol_handler(symbolString + symbolEntry->n_un.n_strx, textAddress ? (long long)base + symbolEntry->n_value : symbolEntry->n_value, is64) != 0xFFFFFFFF) + { + + // Module start located. Start is an alias so don't register it + module_start = (void*)(textAddress ? base + symbolEntry->n_value : symbolEntry->n_value); + } + + symbolEntry++; + symbolIndex++; // TODO remove + } + } + else + { + /* + struct nlist_64* symbolEntry = (void*)base + symtabCommand->symoff; + // NOTE First entry is *not* correct, but we can ignore it (i'm getting radar:// right now, verify later) + while(symbolIndex < symtabCommand->nsyms) + { + + + // If the symbol is exported by this module + if(symbolEntry->n_value && + symbol_handler(symbolString + symbolEntry->n_un.n_strx, textAddress ? (long long)base + symbolEntry->n_value : symbolEntry->n_value, is64) != 0xFFFFFFFF) + { + + // Module start located. Start is an alias so don't register it + module_start = textAddress ? base + symbolEntry->n_value : symbolEntry->n_value; + } + + symbolEntry++; + symbolIndex++; // TODO remove + } + */ + } + return module_start; +} + +// Based on code from dylibinfo.cpp and ImageLoaderMachOCompressed.cpp +void rebase_macho(void* base, char* rebase_stream, UInt32 size) +{ + rebase_stream += (UInt32)base; + + UInt8 immediate = 0; + UInt8 opcode = 0; + UInt8 type = 0; + UInt32 segmentAddress = 0; + + + UInt32 tmp = 0; + UInt32 tmp2 = 0; + UInt8 bits = 0; + int index = 0; + unsigned int i = 0; + + while(i < size) + { + immediate = rebase_stream[i] & REBASE_IMMEDIATE_MASK; + opcode = rebase_stream[i] & REBASE_OPCODE_MASK; + + + switch(opcode) + { + case REBASE_OPCODE_DONE: + // Rebase complete, reset vars + immediate = 0; + opcode = 0; + type = 0; + segmentAddress = 0; + default: + break; + + + case REBASE_OPCODE_SET_TYPE_IMM: + type = immediate; + break; + + + case REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: + // Locate address to begin rebasing + segmentAddress = 0; + struct segment_command* segCommand = NULL; // NOTE: 32bit only + + unsigned int binIndex = 0; + index = 0; + do + { + segCommand = base + sizeof(struct mach_header) + binIndex; + + + binIndex += segCommand->cmdsize; + index++; + } + while(index <= immediate); + + + segmentAddress = segCommand->fileoff; + + tmp = 0; + bits = 0; + do + { + tmp |= (rebase_stream[++i] & 0x7f) << bits; + bits += 7; + } + while(rebase_stream[i] & 0x80); + + segmentAddress += tmp; + break; + + + case REBASE_OPCODE_ADD_ADDR_ULEB: + // Add value to rebase address + tmp = 0; + bits = 0; + do + { + tmp <<= bits; + tmp |= rebase_stream[++i] & 0x7f; + bits += 7; + } + while(rebase_stream[i] & 0x80); + + segmentAddress += tmp; + break; + + case REBASE_OPCODE_ADD_ADDR_IMM_SCALED: + segmentAddress += immediate * sizeof(void*); + break; + + + case REBASE_OPCODE_DO_REBASE_IMM_TIMES: + index = 0; + for (index = 0; index < immediate; ++index) { + rebase_location(base + segmentAddress, (char*)base, type); + segmentAddress += sizeof(void*); + } + break; + + + case REBASE_OPCODE_DO_REBASE_ULEB_TIMES: + tmp = 0; + bits = 0; + do + { + tmp |= (rebase_stream[++i] & 0x7f) << bits; + bits += 7; + } + while(rebase_stream[i] & 0x80); + + index = 0; + for (index = 0; index < tmp; ++index) { + //DBG("\tRebasing 0x%X\n", segmentAddress); + rebase_location(base + segmentAddress, (char*)base, type); + segmentAddress += sizeof(void*); + } + break; + + case REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: + tmp = 0; + bits = 0; + do + { + tmp |= (rebase_stream[++i] & 0x7f) << bits; + bits += 7; + } + while(rebase_stream[i] & 0x80); + + rebase_location(base + segmentAddress, (char*)base, type); + + segmentAddress += tmp + sizeof(void*); + break; + + case REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: + tmp = 0; + bits = 0; + do + { + tmp |= (rebase_stream[++i] & 0x7f) << bits; + bits += 7; + } + while(rebase_stream[i] & 0x80); + + + tmp2 = 0; + bits = 0; + do + { + tmp2 |= (rebase_stream[++i] & 0x7f) << bits; + bits += 7; + } + while(rebase_stream[i] & 0x80); + + index = 0; + for (index = 0; index < tmp; ++index) { + + rebase_location(base + segmentAddress, (char*)base, type); + + segmentAddress += tmp2 + sizeof(void*); + } + break; + } + i++; + } +} + +inline void rebase_location(UInt32* location, char* base, int type) +{ + switch(type) + { + case REBASE_TYPE_POINTER: + case REBASE_TYPE_TEXT_ABSOLUTE32: + *location += (UInt32)base; + break; + + default: + break; + } +} + + +UInt32 read_uleb(UInt8* bind_stream, unsigned int* i) +{ + // Read in offset + UInt32 tmp = 0; + UInt8 bits = 0; + do + { + if(bits < sizeof(UInt32)*8) // hack + { + tmp |= (bind_stream[++(*i)] & 0x7f) << bits; + bits += 7; + } + else + { + ++(*i); + } + } + while(bind_stream[*i] & 0x80); + return tmp; +} + + +// Based on code from dylibinfo.cpp and ImageLoaderMachOCompressed.cpp +// NOTE: this uses 32bit values, and not 64bit values. +// There is a possibility that this could cause issues, +// however the modules are 32 bits, so it shouldn't matter too much +void bind_macho(void* base, UInt8* bind_stream, UInt32 size) +{ + bind_stream += (UInt32)base; + + UInt8 immediate = 0; + UInt8 opcode = 0; + UInt8 type = BIND_TYPE_POINTER; + + UInt32 segmentAddress = 0; + + UInt32 address = 0; + + SInt32 addend = 0; + SInt32 libraryOrdinal = 0; + + const char* symbolName = NULL; + UInt8 symboFlags = 0; + UInt32 symbolAddr = 0xFFFFFFFF; + + // Temperary variables + UInt32 tmp = 0; + UInt32 tmp2 = 0; + UInt32 index = 0; + unsigned int i = 0; + + while(i < size) + { + immediate = bind_stream[i] & BIND_IMMEDIATE_MASK; + opcode = bind_stream[i] & BIND_OPCODE_MASK; + + + switch(opcode) + { + case BIND_OPCODE_DONE: + // reset vars + type = BIND_TYPE_POINTER; + segmentAddress = 0; + address = 0; + addend = 0; + libraryOrdinal = 0; + symbolAddr = 0xFFFFFFFF; + default: + break; + + case BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: + libraryOrdinal = immediate; + break; + + case BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: + libraryOrdinal = read_uleb(bind_stream, &i); + break; + + case BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: + libraryOrdinal = immediate ? (SInt8)(BIND_OPCODE_MASK | immediate) : immediate; + break; + + case BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: + symboFlags = immediate; + symbolName = (char*)&bind_stream[++i]; + i += strlen((char*)&bind_stream[i]); + + symbolAddr = lookup_all_symbols(symbolName); + break; + + case BIND_OPCODE_SET_TYPE_IMM: + type = immediate; + break; + + case BIND_OPCODE_SET_ADDEND_SLEB: + addend = read_uleb(bind_stream, &i); + if(!(bind_stream[i-1] & 0x40)) addend *= -1; + break; + + case BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: + segmentAddress = 0; + + // Locate address + struct segment_command* segCommand = NULL; // NOTE: 32bit only + + unsigned int binIndex = 0; + index = 0; + do + { + segCommand = base + sizeof(struct mach_header) + binIndex; + binIndex += segCommand->cmdsize; + index++; + } + while(index <= immediate); + + segmentAddress = segCommand->fileoff; + + segmentAddress += read_uleb(bind_stream, &i); + break; + + case BIND_OPCODE_ADD_ADDR_ULEB: + segmentAddress += read_uleb(bind_stream, &i); + break; + + case BIND_OPCODE_DO_BIND: + if(symbolAddr != 0xFFFFFFFF) + { + address = segmentAddress + (UInt32)base; + + bind_location((UInt32*)address, (char*)symbolAddr, addend, type); + } + else + { + printf("Unable to bind symbol %s\n", symbolName); + getchar(); + } + + segmentAddress += sizeof(void*); + break; + + case BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: + // Read in offset + tmp = read_uleb(bind_stream, &i); + + if(symbolAddr != 0xFFFFFFFF) + { + address = segmentAddress + (UInt32)base; + + bind_location((UInt32*)address, (char*)symbolAddr, addend, type); + } + else + { + printf("Unable to bind symbol %s\n", symbolName); + getchar(); + } + + segmentAddress += tmp + sizeof(void*); + + + break; + + case BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: + if(symbolAddr != 0xFFFFFFFF) + { + address = segmentAddress + (UInt32)base; + + bind_location((UInt32*)address, (char*)symbolAddr, addend, type); + } + else + { + printf("Unable to bind symbol %s\n", symbolName); + getchar(); + } + segmentAddress += (immediate * sizeof(void*)) + sizeof(void*); + + + break; + + case BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: + tmp = read_uleb(bind_stream, &i); + + tmp2 = read_uleb(bind_stream, &i); + + if(symbolAddr != 0xFFFFFFFF) + { + for(index = 0; index < tmp; index++) + { + + address = segmentAddress + (UInt32)base; + bind_location((UInt32*)address, (char*)symbolAddr, addend, type); + segmentAddress += tmp2 + sizeof(void*); + } + } + else + { + printf("Unable to bind symbol %s\n", symbolName); + getchar(); + } + break; + } + i++; + } +} + + +inline void bind_location(UInt32* location, char* value, UInt32 addend, int type) +{ + // do actual update + char* newValue = value + addend; + + switch (type) { + case BIND_TYPE_POINTER: + case BIND_TYPE_TEXT_ABSOLUTE32: + break; + + case BIND_TYPE_TEXT_PCREL32: + newValue -= ((UInt32)location + 4); + + break; + default: + return; + } + //DBG("Binding 0x%X to 0x%X (was 0x%X)\n", location, newValue, *location); + *location = (UInt32)newValue; +} + +/* +* Locate the symbol for an already loaded function and modify the beginning of +* the function to jump directly to the new one +* example: replace_function("_HelloWorld_start", &replacement_start); +*/ +int replace_function(const char* symbol, void* newAddress) +{ + UInt32* jumpPointer = malloc(sizeof(UInt32*)); + UInt32 addr = lookup_all_symbols(symbol); + + char* binary = (char*)addr; + if(addr != 0xFFFFFFFF) + { + //DBG("Replacing %s to point to 0x%x\n", symbol, newAddress); + *binary++ = 0xFF; // Jump + *binary++ = 0x25; // Long Jump + *((UInt32*)binary) = (UInt32)jumpPointer; + + *jumpPointer = (UInt32)newAddress; + return 1; + } + return 0; +} + +/********************************************************************************/ +/* dyld / Linker Interface */ +/********************************************************************************/ + +void dyld_stub_binder() +{ + printf("ERROR: dyld_stub_binder was called, should have been take care of by the linker.\n"); + getchar(); +} \ No newline at end of file Index: branches/xZen/src/modules/ModuleSystem/modules.c =================================================================== --- branches/xZen/src/modules/ModuleSystem/modules.c (revision 1246) +++ branches/xZen/src/modules/ModuleSystem/modules.c (revision 1247) @@ -9,7 +9,7 @@ #include "boot.h" #include "modules.h" -#include +//#include extern void start_built_in_modules(); @@ -312,705 +312,12 @@ else return lookup_all_symbols(VOID_SYMBOL); } -/********************************************************************************/ -/* Macho Parser */ -/********************************************************************************/ -/* - * Parse through a macho module. The module will be rebased and binded - * as specified in the macho header. If the module is sucessfuly laoded - * the module iinit address will be returned. - * NOTE; all dependecies will be loaded before this module is started - * NOTE: If the module is unable to load ot completeion, the modules - * symbols will still be available. - */ -void* parse_mach(void* binary, - int(*dylib_loader)(char*), - long long(*symbol_handler)(char*, long long, char), - void (*section_handler)(char* section, char* segment, long long offset, long long address) -) -{ - char is64 = false; - void (*module_start)(void) = NULL; - - // Module info - /*char* moduleName = NULL; - UInt32 moduleVersion = 0; - UInt32 moduleCompat = 0; - */ - // TODO convert all of the structs to a union - struct load_command *loadCommand = NULL; - struct dylib_command* dylibCommand = NULL; - struct dyld_info_command* dyldInfoCommand = NULL; - - struct symtab_command* symtabCommand = NULL; - struct segment_command *segCommand = NULL; - struct segment_command_64 *segCommand64 = NULL; - - //struct dysymtab_command* dysymtabCommand = NULL; - UInt32 binaryIndex = 0; - UInt16 cmd = 0; - - textSection = 0; - textAddress = 0; // reinitialize text location in case it doesn't exist; - - // Parse through the load commands - if(((struct mach_header*)binary)->magic == MH_MAGIC) - { - is64 = false; - binaryIndex += sizeof(struct mach_header); - } - else if(((struct mach_header_64*)binary)->magic == MH_MAGIC_64) - { - // NOTE: modules cannot be 64bit... - is64 = true; - binaryIndex += sizeof(struct mach_header_64); - } - else - { - verbose("Invalid mach magic 0x%X\n", ((struct mach_header*)binary)->magic); - //getchar(); - return NULL; - } - - - - /*if(((struct mach_header*)binary)->filetype != MH_DYLIB) - { - printf("Module is not a dylib. Unable to load.\n"); - getchar(); - return NULL; // Module is in the incorrect format - }*/ - - while(cmd < ((struct mach_header*)binary)->ncmds) - { - cmd++; - - loadCommand = binary + binaryIndex; - UInt32 cmdSize = loadCommand->cmdsize; - - - switch ((loadCommand->cmd & 0x7FFFFFFF)) - { - case LC_SYMTAB: - symtabCommand = binary + binaryIndex; - break; - - case LC_SEGMENT: // 32bit macho - { - segCommand = binary + binaryIndex; - - UInt32 sectionIndex; - - sectionIndex = sizeof(struct segment_command); - - struct section *sect; - - while(sectionIndex < segCommand->cmdsize) - { - sect = binary + binaryIndex + sectionIndex; - - sectionIndex += sizeof(struct section); - - if(section_handler) section_handler(sect->sectname, segCommand->segname, sect->offset, sect->addr); - - - - if((strcmp("__TEXT", segCommand->segname) == 0) && (strcmp("__text", sect->sectname) == 0)) - { - // __TEXT,__text found, save the offset and address for when looking for the calls. - textSection = sect->offset; - textAddress = sect->addr; - } - } - } - break; - case LC_SEGMENT_64: // 64bit macho's - { - segCommand64 = binary + binaryIndex; - UInt32 sectionIndex; - - sectionIndex = sizeof(struct segment_command_64); - - struct section_64 *sect; - - while(sectionIndex < segCommand64->cmdsize) - { - sect = binary + binaryIndex + sectionIndex; - - sectionIndex += sizeof(struct section_64); - - if(section_handler) section_handler(sect->sectname, segCommand->segname, sect->offset, sect->addr); - - - if((strcmp("__TEXT", segCommand->segname) == 0) && (strcmp("__text", sect->sectname) == 0)) - { - // __TEXT,__text found, save the offset and address for when looking for the calls. - textSection = sect->offset; - textAddress = sect->addr; - } - } - } - break; - - - case LC_LOAD_DYLIB: - case LC_LOAD_WEAK_DYLIB ^ LC_REQ_DYLD: - dylibCommand = binary + binaryIndex; - char* module = binary + binaryIndex + ((UInt32)*((UInt32*)&dylibCommand->dylib.name)); - // Possible enhancments: verify version - // = dylibCommand->dylib.current_version; - // = dylibCommand->dylib.compatibility_version; - if(dylib_loader) - { - char* name = malloc(strlen(module) + strlen(".dylib") + 1); - sprintf(name, "%s.dylib", module); - - if (!dylib_loader(name)) - { - // NOTE: any symbols exported by dep will be replace with the void function - free(name); - } - } - - break; - - case LC_ID_DYLIB: - dylibCommand = binary + binaryIndex; - /*moduleName = binary + binaryIndex + ((UInt32)*((UInt32*)&dylibCommand->dylib.name)); - moduleVersion = dylibCommand->dylib.current_version; - moduleCompat = dylibCommand->dylib.compatibility_version; - */ - break; - - case LC_DYLD_INFO: - //case LC_DYLD_INFO_ONLY: // compressed info, 10.6+ macho files, already handeled - // Bind and rebase info is stored here - dyldInfoCommand = binary + binaryIndex; - break; - - case LC_DYSYMTAB: - case LC_UUID: - case LC_UNIXTHREAD: - break; - - default: - DBG("Unhandled loadcommand 0x%X\n", loadCommand->cmd & 0x7FFFFFFF); - break; - - } - - binaryIndex += cmdSize; - } - - // bind_macho uses the symbols, if the textAdd does not exist (Symbols.dylib, no code), addresses are static and not relative - module_start = (void*)handle_symtable((UInt32)binary, symtabCommand, symbol_handler, is64); - - if(dyldInfoCommand) - { - // Rebase the module before binding it. - if(dyldInfoCommand->rebase_off) rebase_macho(binary, (char*)dyldInfoCommand->rebase_off, dyldInfoCommand->rebase_size); - // Bind all symbols. - if(dyldInfoCommand->bind_off) bind_macho(binary, (UInt8*)dyldInfoCommand->bind_off, dyldInfoCommand->bind_size); - if(dyldInfoCommand->weak_bind_off) bind_macho(binary, (UInt8*)dyldInfoCommand->weak_bind_off, dyldInfoCommand->weak_bind_size); - if(dyldInfoCommand->lazy_bind_off) bind_macho(binary, (UInt8*)dyldInfoCommand->lazy_bind_off, dyldInfoCommand->lazy_bind_size); - } - - return module_start; - -} - -/* - * parse the symbol table - * Lookup any undefined symbols - */ - -unsigned int handle_symtable(UInt32 base, struct symtab_command* symtabCommand, long long(*symbol_handler)(char*, long long, char), char is64) -{ - unsigned int module_start = 0xFFFFFFFF; - UInt32 symbolIndex = 0; - char* symbolString = base + (char*)symtabCommand->stroff; - - if(!is64) - { - struct nlist* symbolEntry = (void*)base + symtabCommand->symoff; - while(symbolIndex < symtabCommand->nsyms) - { - // If the symbol is exported by this module - if(symbolEntry->n_value && - symbol_handler(symbolString + symbolEntry->n_un.n_strx, textAddress ? (long long)base + symbolEntry->n_value : symbolEntry->n_value, is64) != 0xFFFFFFFF) - { - - // Module start located. Start is an alias so don't register it - module_start = textAddress ? base + symbolEntry->n_value : symbolEntry->n_value; - } - - symbolEntry++; - symbolIndex++; // TODO remove - } - } - else - { - struct nlist_64* symbolEntry = (void*)base + symtabCommand->symoff; - // NOTE First entry is *not* correct, but we can ignore it (i'm getting radar:// right now, verify later) - while(symbolIndex < symtabCommand->nsyms) - { - - - // If the symbol is exported by this module - if(symbolEntry->n_value && - symbol_handler(symbolString + symbolEntry->n_un.n_strx, textAddress ? (long long)base + symbolEntry->n_value : symbolEntry->n_value, is64) != 0xFFFFFFFF) - { - - // Module start located. Start is an alias so don't register it - module_start = textAddress ? base + symbolEntry->n_value : symbolEntry->n_value; - } - - symbolEntry++; - symbolIndex++; // TODO remove - } - } - return module_start; -} - -// Based on code from dylibinfo.cpp and ImageLoaderMachOCompressed.cpp -void rebase_macho(void* base, char* rebase_stream, UInt32 size) -{ - rebase_stream += (UInt32)base; - - UInt8 immediate = 0; - UInt8 opcode = 0; - UInt8 type = 0; - UInt32 segmentAddress = 0; - - - UInt32 tmp = 0; - UInt32 tmp2 = 0; - UInt8 bits = 0; - int index = 0; - unsigned int i = 0; - - while(i < size) - { - immediate = rebase_stream[i] & REBASE_IMMEDIATE_MASK; - opcode = rebase_stream[i] & REBASE_OPCODE_MASK; - - - switch(opcode) - { - case REBASE_OPCODE_DONE: - // Rebase complete, reset vars - immediate = 0; - opcode = 0; - type = 0; - segmentAddress = 0; - default: - break; - - - case REBASE_OPCODE_SET_TYPE_IMM: - type = immediate; - break; - - - case REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: - // Locate address to begin rebasing - segmentAddress = 0; - struct segment_command* segCommand = NULL; // NOTE: 32bit only - - unsigned int binIndex = 0; - index = 0; - do - { - segCommand = base + sizeof(struct mach_header) + binIndex; - - - binIndex += segCommand->cmdsize; - index++; - } - while(index <= immediate); - - - segmentAddress = segCommand->fileoff; - - tmp = 0; - bits = 0; - do - { - tmp |= (rebase_stream[++i] & 0x7f) << bits; - bits += 7; - } - while(rebase_stream[i] & 0x80); - - segmentAddress += tmp; - break; - - - case REBASE_OPCODE_ADD_ADDR_ULEB: - // Add value to rebase address - tmp = 0; - bits = 0; - do - { - tmp <<= bits; - tmp |= rebase_stream[++i] & 0x7f; - bits += 7; - } - while(rebase_stream[i] & 0x80); - - segmentAddress += tmp; - break; - - case REBASE_OPCODE_ADD_ADDR_IMM_SCALED: - segmentAddress += immediate * sizeof(void*); - break; - - - case REBASE_OPCODE_DO_REBASE_IMM_TIMES: - index = 0; - for (index = 0; index < immediate; ++index) { - rebase_location(base + segmentAddress, (char*)base, type); - segmentAddress += sizeof(void*); - } - break; - - - case REBASE_OPCODE_DO_REBASE_ULEB_TIMES: - tmp = 0; - bits = 0; - do - { - tmp |= (rebase_stream[++i] & 0x7f) << bits; - bits += 7; - } - while(rebase_stream[i] & 0x80); - - index = 0; - for (index = 0; index < tmp; ++index) { - //DBG("\tRebasing 0x%X\n", segmentAddress); - rebase_location(base + segmentAddress, (char*)base, type); - segmentAddress += sizeof(void*); - } - break; - - case REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: - tmp = 0; - bits = 0; - do - { - tmp |= (rebase_stream[++i] & 0x7f) << bits; - bits += 7; - } - while(rebase_stream[i] & 0x80); - - rebase_location(base + segmentAddress, (char*)base, type); - - segmentAddress += tmp + sizeof(void*); - break; - - case REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: - tmp = 0; - bits = 0; - do - { - tmp |= (rebase_stream[++i] & 0x7f) << bits; - bits += 7; - } - while(rebase_stream[i] & 0x80); - - - tmp2 = 0; - bits = 0; - do - { - tmp2 |= (rebase_stream[++i] & 0x7f) << bits; - bits += 7; - } - while(rebase_stream[i] & 0x80); - - index = 0; - for (index = 0; index < tmp; ++index) { - - rebase_location(base + segmentAddress, (char*)base, type); - - segmentAddress += tmp2 + sizeof(void*); - } - break; - } - i++; - } -} - -inline void rebase_location(UInt32* location, char* base, int type) -{ - switch(type) - { - case REBASE_TYPE_POINTER: - case REBASE_TYPE_TEXT_ABSOLUTE32: - *location += (UInt32)base; - break; - - default: - break; - } -} - - -UInt32 read_uleb(UInt8* bind_stream, unsigned int* i) -{ - // Read in offset - UInt32 tmp = 0; - UInt8 bits = 0; - do - { - if(bits < sizeof(UInt32)*8) // hack - { - tmp |= (bind_stream[++(*i)] & 0x7f) << bits; - bits += 7; - } - else - { - ++(*i); - } - } - while(bind_stream[*i] & 0x80); - return tmp; -} - - -// Based on code from dylibinfo.cpp and ImageLoaderMachOCompressed.cpp -// NOTE: this uses 32bit values, and not 64bit values. -// There is a possibility that this could cause issues, -// however the modules are 32 bits, so it shouldn't matter too much -void bind_macho(void* base, UInt8* bind_stream, UInt32 size) -{ - bind_stream += (UInt32)base; - - UInt8 immediate = 0; - UInt8 opcode = 0; - UInt8 type = BIND_TYPE_POINTER; - - UInt32 segmentAddress = 0; - - UInt32 address = 0; - - SInt32 addend = 0; - SInt32 libraryOrdinal = 0; - - const char* symbolName = NULL; - UInt8 symboFlags = 0; - UInt32 symbolAddr = 0xFFFFFFFF; - - // Temperary variables - UInt32 tmp = 0; - UInt32 tmp2 = 0; - UInt32 index = 0; - unsigned int i = 0; - - while(i < size) - { - immediate = bind_stream[i] & BIND_IMMEDIATE_MASK; - opcode = bind_stream[i] & BIND_OPCODE_MASK; - - - switch(opcode) - { - case BIND_OPCODE_DONE: - // reset vars - type = BIND_TYPE_POINTER; - segmentAddress = 0; - address = 0; - addend = 0; - libraryOrdinal = 0; - symbolAddr = 0xFFFFFFFF; - default: - break; - - case BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: - libraryOrdinal = immediate; - break; - - case BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: - libraryOrdinal = read_uleb(bind_stream, &i); - break; - - case BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: - libraryOrdinal = immediate ? (SInt8)(BIND_OPCODE_MASK | immediate) : immediate; - break; - - case BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: - symboFlags = immediate; - symbolName = (char*)&bind_stream[++i]; - i += strlen((char*)&bind_stream[i]); - - symbolAddr = lookup_all_symbols(symbolName); - break; - - case BIND_OPCODE_SET_TYPE_IMM: - type = immediate; - break; - - case BIND_OPCODE_SET_ADDEND_SLEB: - addend = read_uleb(bind_stream, &i); - if(!(bind_stream[i-1] & 0x40)) addend *= -1; - break; - - case BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: - segmentAddress = 0; - - // Locate address - struct segment_command* segCommand = NULL; // NOTE: 32bit only - - unsigned int binIndex = 0; - index = 0; - do - { - segCommand = base + sizeof(struct mach_header) + binIndex; - binIndex += segCommand->cmdsize; - index++; - } - while(index <= immediate); - - segmentAddress = segCommand->fileoff; - - segmentAddress += read_uleb(bind_stream, &i); - break; - - case BIND_OPCODE_ADD_ADDR_ULEB: - segmentAddress += read_uleb(bind_stream, &i); - break; - - case BIND_OPCODE_DO_BIND: - if(symbolAddr != 0xFFFFFFFF) - { - address = segmentAddress + (UInt32)base; - - bind_location((UInt32*)address, (char*)symbolAddr, addend, type); - } - else - { - printf("Unable to bind symbol %s\n", symbolName); - getchar(); - } - - segmentAddress += sizeof(void*); - break; - - case BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: - // Read in offset - tmp = read_uleb(bind_stream, &i); - - if(symbolAddr != 0xFFFFFFFF) - { - address = segmentAddress + (UInt32)base; - - bind_location((UInt32*)address, (char*)symbolAddr, addend, type); - } - else - { - printf("Unable to bind symbol %s\n", symbolName); - getchar(); - } - - segmentAddress += tmp + sizeof(void*); - - - break; - - case BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: - if(symbolAddr != 0xFFFFFFFF) - { - address = segmentAddress + (UInt32)base; - - bind_location((UInt32*)address, (char*)symbolAddr, addend, type); - } - else - { - printf("Unable to bind symbol %s\n", symbolName); - getchar(); - } - segmentAddress += (immediate * sizeof(void*)) + sizeof(void*); - - - break; - - case BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: - tmp = read_uleb(bind_stream, &i); - - tmp2 = read_uleb(bind_stream, &i); - - if(symbolAddr != 0xFFFFFFFF) - { - for(index = 0; index < tmp; index++) - { - - address = segmentAddress + (UInt32)base; - bind_location((UInt32*)address, (char*)symbolAddr, addend, type); - segmentAddress += tmp2 + sizeof(void*); - } - } - else - { - printf("Unable to bind symbol %s\n", symbolName); - getchar(); - } - break; - } - i++; - } -} - - -inline void bind_location(UInt32* location, char* value, UInt32 addend, int type) -{ - // do actual update - char* newValue = value + addend; - - switch (type) { - case BIND_TYPE_POINTER: - case BIND_TYPE_TEXT_ABSOLUTE32: - break; - - case BIND_TYPE_TEXT_PCREL32: - newValue -= ((UInt32)location + 4); - - break; - default: - return; - } - //DBG("Binding 0x%X to 0x%X (was 0x%X)\n", location, newValue, *location); - *location = (UInt32)newValue; -} - /********************************************************************************/ /* Module Hook Interface */ /********************************************************************************/ -/* -* Locate the symbol for an already loaded function and modify the beginning of -* the function to jump directly to the new one -* example: replace_function("_HelloWorld_start", &replacement_start); -*/ -int replace_function(const char* symbol, void* newAddress) -{ - UInt32* jumpPointer = malloc(sizeof(UInt32*)); - UInt32 addr = lookup_all_symbols(symbol); - - char* binary = (char*)addr; - if(addr != 0xFFFFFFFF) - { - //DBG("Replacing %s to point to 0x%x\n", symbol, newAddress); - *binary++ = 0xFF; // Jump - *binary++ = 0x25; // Long Jump - *((UInt32*)binary) = (UInt32)jumpPointer; - - *jumpPointer = (UInt32)newAddress; - return 1; - } - return 0; -} - /* * execute_hook( const char* name ) * name - Name of the module hook Index: branches/xZen/src/modules/ModuleSystem/Makefile =================================================================== --- branches/xZen/src/modules/ModuleSystem/Makefile (revision 1246) +++ branches/xZen/src/modules/ModuleSystem/Makefile (revision 1247) @@ -8,6 +8,6 @@ DIR = ModuleSystem -MODULE_OBJS = modules_support modules +MODULE_OBJS = macho modules_support modules include ../MakeInc.dir \ No newline at end of file Index: branches/xZen/src/modules/HelloWorld/Makefile =================================================================== --- branches/xZen/src/modules/HelloWorld/Makefile (revision 1246) +++ branches/xZen/src/modules/HelloWorld/Makefile (revision 1247) @@ -8,6 +8,6 @@ DIR = HelloWorld -MODULE_OBJS = HelloWorld.o +MODULE_OBJS = HelloWorld include ../MakeInc.dir \ No newline at end of file Index: branches/xZen/src/modules/Makefile =================================================================== --- branches/xZen/src/modules/Makefile (revision 1246) +++ branches/xZen/src/modules/Makefile (revision 1247) @@ -9,10 +9,10 @@ include ${ROOT}/Make.rules # The order of building is important. -SUBDIRS = ModuleSystem klibc uClibcxx HelloWorld Disk FileSystem +SUBDIRS = klibc uClibcxx HelloWorld Disk FileSystem +# ModuleSystem - -CFLAGS= -O3 $(MORECPP) -arch i386 -g -static +CFLAGS= -O3 $(MORECPP) -g -static DEFINES= CONFIG = hd LIBSAIODIR = $(SRCROOT)/i386/libsaio Index: branches/xZen/src/i386/Make.rules =================================================================== --- branches/xZen/src/i386/Make.rules (revision 1246) +++ branches/xZen/src/i386/Make.rules (revision 1247) @@ -22,29 +22,12 @@ -MD -dependency-file $(OBJROOT)/$*.d @md -u $(OBJROOT)/Makedep -f -d $(OBJROOT)/$*.d -##### x86_64 Rules ##### +$(OBJROOT)/%.i386o: %.s + @echo "\t[AS:I386] $<" + @$(X86_CC) $(CPPFLAGS) -c $(INC) -arch i386 -o $@ $< \ + -MD -dependency-file $*.d + @md -u $(OBJROOT)/Makedep -f -d $*.d -$(OBJROOT)/%.x86_64o: %.c $(OBJROOT) - @echo "\t[CC:X86_64] $<" - @$(X86_CC) -arch x86_64 $(CFLAGS) $(DEFINES) -c $(INC) $< -o $@ \ - -MD -dependency-file $(OBJROOT)/$*.d - @md -u $(OBJROOT)/Makedep -f -d $(OBJROOT)/$*.d - -$(OBJROOT)/%.x86_64o: %.m $(OBJROOT) - @echo "\t[M:X86_64] $<" - @$(X86_CC) -arch x86_64 $(CFLAGS) $(DEFINES) -c $(INC) $< -o $@ \ - -MD -dependency-file $(OBJROOT)/$*.d - @md -u $(OBJROOT)/Makedep -f -d $(OBJROOT)/$*.d - -$(OBJROOT)/%.x86_64o: %.x86_64 $(OBJROOT) - @echo "\t[CPP:X86_64] $<" - @$(X86_CPP) -arch i386 $(CPPFLAGS) $(CFLAGS) -c "$<" $(INC) -o $@ \ - -MD -dependency-file $(OBJROOT)/$*.d - @md -u $(OBJROOT)/Makedep -f -d $(OBJROOT)/$*.d - - ACTUAL_OBJECTS := ${ACTUAL_OBJECTS} $(addsuffix .i386o , $(addprefix $(OBJROOT)/, $(OBJECTS))) -ACTUAL_OBJECTS := ${ACTUAL_OBJECTS} $(addsuffix .x86_64o, $(addprefix $(OBJROOT)/, $(OBJECTS))) MODULE_OBJECTS := ${MODULE_OBJECTS} $(addsuffix .i386o, $(addprefix $(OBJROOT)/, $(MODULE_OBJS))) -MODULE_OBJECTS := ${MODULE_OBJECTS} $(addsuffix .x86_64o, $(addprefix $(OBJROOT)/, $(MODULE_OBJS))) \ No newline at end of file Index: branches/xZen/src/i386/libsa/Makefile =================================================================== --- branches/xZen/src/i386/libsa/Makefile (revision 1246) +++ branches/xZen/src/i386/libsa/Makefile (revision 1247) @@ -1,38 +1,35 @@ -ROOT = $(shell pwd)/../../ +ROOT = $(shell pwd)/../../../ +DIR = libsa SRCROOT = ${ROOT}/src -OBJROOT = $(ROOT)/obj/i386 -SYMROOT = $(ROOT)/sym/i386 -DSTROOT = $(ROOT)/dst/usr/standalone/i386 +OBJROOT = $(ROOT)/obj/i386/${DIR} +SYMROOT = $(ROOT)/sym/util +DSTROOT = $(ROOT)/dst/usr/standalone/i386/ DOCROOT = $(ROOT)/doc -DIR = libsa -include ${ROOT}/Make.rules - LIBSAIODIR = ../libsaio -CFLAGS := $(CFLAGS) $(RC_CFLAGS) $(MORECPP) -arch i386 \ - -fno-builtin -static $(OMIT_FRAME_POINTER_CFLAG) \ - -mpreferred-stack-boundary=2 -fno-align-functions -fno-stack-protector \ - -march=pentium4 -msse2 -mfpmath=sse -msoft-float \ - -nostdinc -include $(SRCROOT)/autoconf.h CPPFLAGS := $(CPPFLAGS) -nostdinc++ -INC = -I. -I$(SYMROOT) -I$(LIBSAIODIR) -I${SRCROOT}/i386/include +INC = -I. -I$(SYMROOT) -I$(LIBSAIODIR) -I${SRCROOT}/include -SA_OBJS = prf.o printf.o zalloc.o \ - string.o strtol.o error.o \ - setjmp.o qsort.o efi_tables.o +OBJECTS = prf printf zalloc \ + string strtol error \ + setjmp qsort efi_tables LIBS = libsa.a LIBS := $(addprefix $(SYMROOT)/, $(LIBS)) +include ${SRCROOT}/i386/Make.rules + + + DIRS_NEEDED = $(OBJROOT) $(SYMROOT) all embedtheme: $(DIRS_NEEDED) $(LIBS) +$(warning $(ACTUAL_OBJECTS)) - -$(LIBS): $(addprefix $(OBJROOT)/, $(SA_OBJS)) +$(LIBS): ${ACTUAL_OBJECTS} @echo "\t[RM] $@" @rm -f $@ @echo "\t[AR] $(@F)" @@ -40,5 +37,10 @@ @echo "\t[RANLIB] $(@F)" @ranlib $@ +$(DIRS_NEEDED) $(INSTALLDIR) $(OBJROOT) $(SYMROOT): + @echo "\t[MKDIR] $@" + @$(MKDIRS) $@ + + # dependencies -include $(OBJROOT)/Makedep Index: branches/xZen/src/i386/Makefile =================================================================== --- branches/xZen/src/i386/Makefile (revision 1246) +++ branches/xZen/src/i386/Makefile (revision 1247) @@ -15,7 +15,7 @@ # The order of building is important. SUBDIRS = libsa libsaio boot0 boot1 boot2 cdboot modules -all: +all: ${OBJROOT} ${SYMROOT} @#cd modules; ${MAKE} BUILT_IN=yes $@ @@ -26,17 +26,4 @@ cd $$i; ${MAKE} \ $@ \ ) || exit $$?; \ - done - -config rebuild_config: - @for i in config; \ - do \ - echo ================= make $@ for $$i =================; \ - ( ROOT=$(ROOT); \ - cd $$i; ${MAKE} \ - $@ \ - ) || exit $$?; \ - done - - -.PHONY: config \ No newline at end of file + done \ No newline at end of file Index: branches/xZen/src/util/fdisk/Makefile =================================================================== --- branches/xZen/src/util/fdisk/Makefile (revision 1246) +++ branches/xZen/src/util/fdisk/Makefile (revision 1247) @@ -1,13 +1,11 @@ -SRCROOT = $(shell pwd)/../../../ -override OBJROOT = $(SRCROOT)/obj/i386/util/fdisk -SYMROOT = $(SRCROOT)/sym/i386 -DSTROOT = $(SRCROOT)/dst/i386 -DOCROOT = $(SRCROOT)/doc -IMGROOT = $(SRCROOT)/sym/cache -IMGSKELROOT = $(SRCROOT)/imgskel -CDBOOT = ${IMGROOT}/usr/standalone/i386/cdboot - +ROOT = $(shell pwd)/../../../ DIR = fdisk +SRCROOT = ${ROOT}/src +OBJROOT = $(ROOT)/obj/util/${DIR} +SYMROOT = $(ROOT)/sym/util +DSTROOT = $(ROOT)/dst/usr/bin/ +DOCROOT = $(ROOT)/doc + OBJECTS = cmd disk fdisk getrawpartition mbr misc opendev part user auto LDFLAGS := $(LDFALGS) -mmacosx-version-min=10.5 Index: branches/xZen/src/util/Makefile =================================================================== --- branches/xZen/src/util/Makefile (revision 1246) +++ branches/xZen/src/util/Makefile (revision 1247) @@ -27,14 +27,14 @@ endif -LDFLAGS := $(LDFALGS) -framework IOKit -framework CoreFoundation -mmacosx-version-min=10.5 +LDFLAGS := $(LDFALGS) -framework IOKit -framework CoreFoundation -mmacosx-version-min=10.4 SYMPROG = $(addprefix $(SYMROOT)/, $(PROGRAMS)) DIRS_NEEDED = $(OBJROOT) $(SYMROOT) -include ${SRCROOT}/../Make.rules +include ${ROOT}/Make.rules