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.
This commit is contained in:
Joel Dice 2010-11-14 18:45:37 -07:00
parent f64d6c857b
commit 8e23893af0
3 changed files with 104 additions and 66 deletions

View File

@ -151,7 +151,8 @@ endif
ifeq ($(platform),darwin) ifeq ($(platform),darwin)
build-cflags = $(common-cflags) -fPIC -fvisibility=hidden -I$(src) 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) ifeq ($(bootimage),true)
bootimage-lflags = -Wl,-segprot,__RWX,rwx,rwx bootimage-lflags = -Wl,-segprot,__RWX,rwx,rwx
endif endif
@ -161,18 +162,27 @@ ifeq ($(platform),darwin)
shared = -dynamiclib shared = -dynamiclib
ifeq ($(arch),powerpc) ifeq ($(arch),powerpc)
ifneq (,$(filter i386 x86_64,$(build-arch)))
converter-cflags = -DOPPOSITE_ENDIAN
endif
cflags += -arch ppc cflags += -arch ppc
asmflags += -arch ppc asmflags += -arch ppc
lflags += -arch ppc lflags += -arch ppc
endif endif
ifeq ($(arch),i386) ifeq ($(arch),i386)
ifeq ($(build-arch),powerpc)
converter-cflags = -DOPPOSITE_ENDIAN
endif
cflags += -arch i386 cflags += -arch i386
asmflags += -arch i386 asmflags += -arch i386
lflags += -arch i386 lflags += -arch i386
endif endif
ifeq ($(arch),x86_64) ifeq ($(arch),x86_64)
ifeq ($(build-arch),powerpc)
converter-cflags = -DOPPOSITE_ENDIAN
endif
cflags += -arch x86_64 cflags += -arch x86_64
asmflags += -arch x86_64 asmflags += -arch x86_64
lflags += -arch x86_64 lflags += -arch x86_64
@ -640,19 +650,19 @@ $(native-build)/binaryToObject-main.o: $(src)/binaryToObject/main.cpp
$(build-cxx) -c $(^) -o $(@) $(build-cxx) -c $(^) -o $(@)
$(native-build)/binaryToObject-elf64.o: $(src)/binaryToObject/elf.cpp $(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 $(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 $(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 $(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 $(native-build)/binaryToObject-pe.o: $(src)/binaryToObject/pe.cpp
$(build-cxx) -c $(^) -o $(@) $(build-cxx) $(converter-cflags) -c $(^) -o $(@)
$(converter): $(converter-objects) $(converter): $(converter-objects)
$(build-cxx) $(^) -o $(@) $(build-cxx) $(^) -o $(@)

View File

@ -12,6 +12,32 @@
#include "stdio.h" #include "stdio.h"
#include "string.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<uint64_t>(v) >> 56) & UINT64_C(0x00000000000000FF)) | \
((static_cast<uint64_t>(v) >> 40) & UINT64_C(0x000000000000FF00)) | \
((static_cast<uint64_t>(v) >> 24) & UINT64_C(0x0000000000FF0000)) | \
((static_cast<uint64_t>(v) >> 8) & UINT64_C(0x00000000FF000000)) | \
((static_cast<uint64_t>(v) << 8) & UINT64_C(0x000000FF00000000)) | \
((static_cast<uint64_t>(v) << 24) & UINT64_C(0x0000FF0000000000)) | \
((static_cast<uint64_t>(v) << 40) & UINT64_C(0x00FF000000000000)) | \
((static_cast<uint64_t>(v) << 56)))
#else
# define V2(v) v
# define V4(v) v
# define V8(v) v
#endif
#define MH_MAGIC_64 0xfeedfacf #define MH_MAGIC_64 0xfeedfacf
#define MH_MAGIC 0xfeedface #define MH_MAGIC 0xfeedface
@ -37,6 +63,7 @@
#define CPU_SUBTYPE_POWERPC_ALL 0 #define CPU_SUBTYPE_POWERPC_ALL 0
#if (BITS_PER_WORD == 64) #if (BITS_PER_WORD == 64)
# define VW(v) V8(v)
# define Magic MH_MAGIC_64 # define Magic MH_MAGIC_64
# define Segment LC_SEGMENT_64 # define Segment LC_SEGMENT_64
# define FileHeader mach_header_64 # define FileHeader mach_header_64
@ -44,6 +71,7 @@
# define Section section_64 # define Section section_64
# define NList struct nlist_64 # define NList struct nlist_64
#elif (BITS_PER_WORD == 32) #elif (BITS_PER_WORD == 32)
# define VW(v) V4(v)
# define Magic MH_MAGIC # define Magic MH_MAGIC
# define Segment LC_SEGMENT # define Segment LC_SEGMENT
# define FileHeader mach_header # define FileHeader mach_header
@ -191,32 +219,32 @@ writeObject(const uint8_t* data, unsigned size, FILE* out,
unsigned endNameLength = strlen(endName) + 1; unsigned endNameLength = strlen(endName) + 1;
FileHeader header = { FileHeader header = {
Magic, // magic V4(Magic), // magic
cpuType, V4(cpuType),
cpuSubType, V4(cpuSubType),
MH_OBJECT, // filetype, V4(MH_OBJECT), // filetype,
2, // ncmds V4(2), // ncmds
sizeof(SegmentCommand) V4(sizeof(SegmentCommand)
+ sizeof(Section) + sizeof(Section)
+ sizeof(symtab_command), // sizeofcmds + sizeof(symtab_command)), // sizeofcmds
0 // flags V4(0) // flags
}; };
SegmentCommand segment = { SegmentCommand segment = {
Segment, // cmd V4(Segment), // cmd
sizeof(SegmentCommand) + sizeof(Section), // cmdsize V4(sizeof(SegmentCommand) + sizeof(Section)), // cmdsize
"", // segname "", // segname
0, // vmaddr VW(0), // vmaddr
pad(size), // vmsize VW(pad(size)), // vmsize
sizeof(FileHeader) VW(sizeof(FileHeader)
+ sizeof(SegmentCommand) + sizeof(SegmentCommand)
+ sizeof(Section) + sizeof(Section)
+ sizeof(symtab_command), // fileoff + sizeof(symtab_command)), // fileoff
pad(size), // filesize VW(pad(size)), // filesize
7, // maxprot V4(7), // maxprot
7, // initprot V4(7), // initprot
1, // nsects V4(1), // nsects
0 // flags V4(0) // flags
}; };
strncpy(segment.segname, segmentName, sizeof(segment.segname)); strncpy(segment.segname, segmentName, sizeof(segment.segname));
@ -224,55 +252,55 @@ writeObject(const uint8_t* data, unsigned size, FILE* out,
Section sect = { Section sect = {
"", // sectname "", // sectname
"", // segname "", // segname
0, // addr VW(0), // addr
pad(size), // size VW(pad(size)), // size
sizeof(FileHeader) V4(sizeof(FileHeader)
+ sizeof(SegmentCommand) + sizeof(SegmentCommand)
+ sizeof(Section) + sizeof(Section)
+ sizeof(symtab_command), // offset + sizeof(symtab_command)), // offset
log(alignment), // align V4(log(alignment)), // align
0, // reloff V4(0), // reloff
0, // nreloc V4(0), // nreloc
S_REGULAR, // flags V4(S_REGULAR), // flags
0, // reserved1 V4(0), // reserved1
0, // reserved2 V4(0), // reserved2
}; };
strncpy(sect.segname, segmentName, sizeof(sect.segname)); strncpy(sect.segname, segmentName, sizeof(sect.segname));
strncpy(sect.sectname, sectionName, sizeof(sect.sectname)); strncpy(sect.sectname, sectionName, sizeof(sect.sectname));
symtab_command symbolTable = { symtab_command symbolTable = {
LC_SYMTAB, // cmd V4(LC_SYMTAB), // cmd
sizeof(symtab_command), // cmdsize V4(sizeof(symtab_command)), // cmdsize
sizeof(FileHeader) V4(sizeof(FileHeader)
+ sizeof(SegmentCommand) + sizeof(SegmentCommand)
+ sizeof(Section) + sizeof(Section)
+ sizeof(symtab_command) + sizeof(symtab_command)
+ pad(size), // symoff + pad(size)), // symoff
2, // nsyms V4(2), // nsyms
sizeof(FileHeader) V4(sizeof(FileHeader)
+ sizeof(SegmentCommand) + sizeof(SegmentCommand)
+ sizeof(Section) + sizeof(Section)
+ sizeof(symtab_command) + sizeof(symtab_command)
+ pad(size) + pad(size)
+ (sizeof(NList) * 2), // stroff + (sizeof(NList) * 2)), // stroff
1 + startNameLength + endNameLength, // strsize V4(1 + startNameLength + endNameLength), // strsize
}; };
NList symbolList[] = { NList symbolList[] = {
{ {
1, // n_un V4(1), // n_un
N_SECT | N_EXT, // n_type V1(N_SECT | N_EXT), // n_type
1, // n_sect V1(1), // n_sect
0, // n_desc V2(0), // n_desc
0 // n_value VW(0) // n_value
}, },
{ {
1 + startNameLength, // n_un V4(1 + startNameLength), // n_un
N_SECT | N_EXT, // n_type V1(N_SECT | N_EXT), // n_type
1, // n_sect V1(1), // n_sect
0, // n_desc V2(0), // n_desc
size // n_value VW(size) // n_value
} }
}; };

View File

@ -15,7 +15,7 @@
#include "common.h" #include "common.h"
#ifdef __APPLE__ #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 IP_REGISTER(context) (context->uc_mcontext->__ss.__srr0)
# define STACK_REGISTER(context) (context->uc_mcontext->__ss.__r1) # define STACK_REGISTER(context) (context->uc_mcontext->__ss.__r1)
# define THREAD_REGISTER(context) (context->uc_mcontext->__ss.__r13) # define THREAD_REGISTER(context) (context->uc_mcontext->__ss.__r13)