From 8e23893af090632467a08c593cc9a35d85144496 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Sun, 14 Nov 2010 18:45:37 -0700 Subject: [PATCH] fix PowerPC builds on OS X 10.5+ The primary change is to ensure we output a Mach-O file of appropriate endianness when cross-compiling for an opposite-endian architecture. Earlier versions of XCode's linker accepted files of either endianness, reguardless of architecture, but later versions don't, hence the change. --- makefile | 22 +++-- src/binaryToObject/mach-o.cpp | 146 ++++++++++++++++++++-------------- src/powerpc.h | 2 +- 3 files changed, 104 insertions(+), 66 deletions(-) diff --git a/makefile b/makefile index f0dcab31a5..7c14992ac4 100644 --- a/makefile +++ b/makefile @@ -151,7 +151,8 @@ endif ifeq ($(platform),darwin) build-cflags = $(common-cflags) -fPIC -fvisibility=hidden -I$(src) - lflags = $(common-lflags) -ldl -framework CoreFoundation -framework CoreServices + lflags = $(common-lflags) -ldl -framework CoreFoundation \ + -framework CoreServices ifeq ($(bootimage),true) bootimage-lflags = -Wl,-segprot,__RWX,rwx,rwx endif @@ -161,18 +162,27 @@ ifeq ($(platform),darwin) shared = -dynamiclib ifeq ($(arch),powerpc) + ifneq (,$(filter i386 x86_64,$(build-arch))) + converter-cflags = -DOPPOSITE_ENDIAN + endif cflags += -arch ppc asmflags += -arch ppc lflags += -arch ppc endif ifeq ($(arch),i386) + ifeq ($(build-arch),powerpc) + converter-cflags = -DOPPOSITE_ENDIAN + endif cflags += -arch i386 asmflags += -arch i386 lflags += -arch i386 endif ifeq ($(arch),x86_64) + ifeq ($(build-arch),powerpc) + converter-cflags = -DOPPOSITE_ENDIAN + endif cflags += -arch x86_64 asmflags += -arch x86_64 lflags += -arch x86_64 @@ -640,19 +650,19 @@ $(native-build)/binaryToObject-main.o: $(src)/binaryToObject/main.cpp $(build-cxx) -c $(^) -o $(@) $(native-build)/binaryToObject-elf64.o: $(src)/binaryToObject/elf.cpp - $(build-cxx) -DBITS_PER_WORD=64 -c $(^) -o $(@) + $(build-cxx) $(converter-cflags) -DBITS_PER_WORD=64 -c $(^) -o $(@) $(native-build)/binaryToObject-elf32.o: $(src)/binaryToObject/elf.cpp - $(build-cxx) -DBITS_PER_WORD=32 -c $(^) -o $(@) + $(build-cxx) $(converter-cflags) -DBITS_PER_WORD=32 -c $(^) -o $(@) $(native-build)/binaryToObject-mach-o64.o: $(src)/binaryToObject/mach-o.cpp - $(build-cxx) -DBITS_PER_WORD=64 -c $(^) -o $(@) + $(build-cxx) $(converter-cflags) -DBITS_PER_WORD=64 -c $(^) -o $(@) $(native-build)/binaryToObject-mach-o32.o: $(src)/binaryToObject/mach-o.cpp - $(build-cxx) -DBITS_PER_WORD=32 -c $(^) -o $(@) + $(build-cxx) $(converter-cflags) -DBITS_PER_WORD=32 -c $(^) -o $(@) $(native-build)/binaryToObject-pe.o: $(src)/binaryToObject/pe.cpp - $(build-cxx) -c $(^) -o $(@) + $(build-cxx) $(converter-cflags) -c $(^) -o $(@) $(converter): $(converter-objects) $(build-cxx) $(^) -o $(@) diff --git a/src/binaryToObject/mach-o.cpp b/src/binaryToObject/mach-o.cpp index d153694b5c..527130a8db 100644 --- a/src/binaryToObject/mach-o.cpp +++ b/src/binaryToObject/mach-o.cpp @@ -12,6 +12,32 @@ #include "stdio.h" #include "string.h" +#define V1(v) v + +#ifdef OPPOSITE_ENDIAN +# define V2(v) \ + ((((v) >> 8) & 0xFF) | \ + (((v) << 8))) +# define V4(v) \ + ((((v) >> 24) & 0x000000FF) | \ + (((v) >> 8) & 0x0000FF00) | \ + (((v) << 8) & 0x00FF0000) | \ + (((v) << 24))) +# define V8(v) \ + (((static_cast(v) >> 56) & UINT64_C(0x00000000000000FF)) | \ + ((static_cast(v) >> 40) & UINT64_C(0x000000000000FF00)) | \ + ((static_cast(v) >> 24) & UINT64_C(0x0000000000FF0000)) | \ + ((static_cast(v) >> 8) & UINT64_C(0x00000000FF000000)) | \ + ((static_cast(v) << 8) & UINT64_C(0x000000FF00000000)) | \ + ((static_cast(v) << 24) & UINT64_C(0x0000FF0000000000)) | \ + ((static_cast(v) << 40) & UINT64_C(0x00FF000000000000)) | \ + ((static_cast(v) << 56))) +#else +# define V2(v) v +# define V4(v) v +# define V8(v) v +#endif + #define MH_MAGIC_64 0xfeedfacf #define MH_MAGIC 0xfeedface @@ -37,6 +63,7 @@ #define CPU_SUBTYPE_POWERPC_ALL 0 #if (BITS_PER_WORD == 64) +# define VW(v) V8(v) # define Magic MH_MAGIC_64 # define Segment LC_SEGMENT_64 # define FileHeader mach_header_64 @@ -44,6 +71,7 @@ # define Section section_64 # define NList struct nlist_64 #elif (BITS_PER_WORD == 32) +# define VW(v) V4(v) # define Magic MH_MAGIC # define Segment LC_SEGMENT # define FileHeader mach_header @@ -191,32 +219,32 @@ writeObject(const uint8_t* data, unsigned size, FILE* out, unsigned endNameLength = strlen(endName) + 1; FileHeader header = { - Magic, // magic - cpuType, - cpuSubType, - MH_OBJECT, // filetype, - 2, // ncmds - sizeof(SegmentCommand) - + sizeof(Section) - + sizeof(symtab_command), // sizeofcmds - 0 // flags + V4(Magic), // magic + V4(cpuType), + V4(cpuSubType), + V4(MH_OBJECT), // filetype, + V4(2), // ncmds + V4(sizeof(SegmentCommand) + + sizeof(Section) + + sizeof(symtab_command)), // sizeofcmds + V4(0) // flags }; SegmentCommand segment = { - Segment, // cmd - sizeof(SegmentCommand) + sizeof(Section), // cmdsize + V4(Segment), // cmd + V4(sizeof(SegmentCommand) + sizeof(Section)), // cmdsize "", // segname - 0, // vmaddr - pad(size), // vmsize - sizeof(FileHeader) - + sizeof(SegmentCommand) - + sizeof(Section) - + sizeof(symtab_command), // fileoff - pad(size), // filesize - 7, // maxprot - 7, // initprot - 1, // nsects - 0 // flags + VW(0), // vmaddr + VW(pad(size)), // vmsize + VW(sizeof(FileHeader) + + sizeof(SegmentCommand) + + sizeof(Section) + + sizeof(symtab_command)), // fileoff + VW(pad(size)), // filesize + V4(7), // maxprot + V4(7), // initprot + V4(1), // nsects + V4(0) // flags }; strncpy(segment.segname, segmentName, sizeof(segment.segname)); @@ -224,55 +252,55 @@ writeObject(const uint8_t* data, unsigned size, FILE* out, Section sect = { "", // sectname "", // segname - 0, // addr - pad(size), // size - sizeof(FileHeader) - + sizeof(SegmentCommand) - + sizeof(Section) - + sizeof(symtab_command), // offset - log(alignment), // align - 0, // reloff - 0, // nreloc - S_REGULAR, // flags - 0, // reserved1 - 0, // reserved2 + VW(0), // addr + VW(pad(size)), // size + V4(sizeof(FileHeader) + + sizeof(SegmentCommand) + + sizeof(Section) + + sizeof(symtab_command)), // offset + V4(log(alignment)), // align + V4(0), // reloff + V4(0), // nreloc + V4(S_REGULAR), // flags + V4(0), // reserved1 + V4(0), // reserved2 }; strncpy(sect.segname, segmentName, sizeof(sect.segname)); strncpy(sect.sectname, sectionName, sizeof(sect.sectname)); symtab_command symbolTable = { - LC_SYMTAB, // cmd - sizeof(symtab_command), // cmdsize - sizeof(FileHeader) - + sizeof(SegmentCommand) - + sizeof(Section) - + sizeof(symtab_command) - + pad(size), // symoff - 2, // nsyms - sizeof(FileHeader) - + sizeof(SegmentCommand) - + sizeof(Section) - + sizeof(symtab_command) - + pad(size) - + (sizeof(NList) * 2), // stroff - 1 + startNameLength + endNameLength, // strsize + V4(LC_SYMTAB), // cmd + V4(sizeof(symtab_command)), // cmdsize + V4(sizeof(FileHeader) + + sizeof(SegmentCommand) + + sizeof(Section) + + sizeof(symtab_command) + + pad(size)), // symoff + V4(2), // nsyms + V4(sizeof(FileHeader) + + sizeof(SegmentCommand) + + sizeof(Section) + + sizeof(symtab_command) + + pad(size) + + (sizeof(NList) * 2)), // stroff + V4(1 + startNameLength + endNameLength), // strsize }; NList symbolList[] = { { - 1, // n_un - N_SECT | N_EXT, // n_type - 1, // n_sect - 0, // n_desc - 0 // n_value + V4(1), // n_un + V1(N_SECT | N_EXT), // n_type + V1(1), // n_sect + V2(0), // n_desc + VW(0) // n_value }, { - 1 + startNameLength, // n_un - N_SECT | N_EXT, // n_type - 1, // n_sect - 0, // n_desc - size // n_value + V4(1 + startNameLength), // n_un + V1(N_SECT | N_EXT), // n_type + V1(1), // n_sect + V2(0), // n_desc + VW(size) // n_value } }; diff --git a/src/powerpc.h b/src/powerpc.h index 9a55c13266..d252039b89 100644 --- a/src/powerpc.h +++ b/src/powerpc.h @@ -15,7 +15,7 @@ #include "common.h" #ifdef __APPLE__ -# if __DARWIN_UNIX03 && defined(_STRUCT_X86_EXCEPTION_STATE32) +# if __DARWIN_UNIX03 && defined(_STRUCT_PPC_EXCEPTION_STATE) # define IP_REGISTER(context) (context->uc_mcontext->__ss.__srr0) # define STACK_REGISTER(context) (context->uc_mcontext->__ss.__r1) # define THREAD_REGISTER(context) (context->uc_mcontext->__ss.__r13)