diff --git a/makefile b/makefile index 50f813d75b..bca5d1719a 100644 --- a/makefile +++ b/makefile @@ -169,7 +169,7 @@ endif build-cflags = $(common-cflags) -fPIC -fvisibility=hidden \ "-I$(JAVA_HOME)/include/linux" -I$(src) -pthread -converter-cflags = -D__STDC_CONSTANT_MACROS +converter-cflags = -D__STDC_CONSTANT_MACROS -Isrc/binaryToObject cflags = $(build-cflags) @@ -201,6 +201,15 @@ endif ifeq ($(arch),powerpc) asm = powerpc pointer-size = 4 + + ifneq ($(arch),$(build-arch)) + converter-cflags += -DOPPOSITE_ENDIAN + cxx = powerpc-linux-gnu-g++ + cc = powerpc-linux-gnu-gcc + ar = powerpc-linux-gnu-ar + ranlib = powerpc-linux-gnu-ranlib + strip = powerpc-linux-gnu-strip + endif endif ifeq ($(arch),arm) asm = arm @@ -243,7 +252,7 @@ ifeq ($(platform),darwin) shared = -dynamiclib ifeq ($(arch),powerpc) - ifneq (,$(filter i386 x86_64,$(build-arch))) + ifneq (,$(filter i386 x86_64 arm,$(build-arch))) converter-cflags += -DOPPOSITE_ENDIAN endif openjdk-extra-cflags += -arch ppc -mmacosx-version-min=10.4 diff --git a/src/binaryToObject/elf.cpp b/src/binaryToObject/elf.cpp index 44915282bb..51193dd2c7 100644 --- a/src/binaryToObject/elf.cpp +++ b/src/binaryToObject/elf.cpp @@ -12,6 +12,8 @@ #include "stdio.h" #include "string.h" +#include "endianness.h" + #define EI_NIDENT 16 #define EI_MAG0 0 @@ -218,99 +220,108 @@ writeObject(const uint8_t* data, unsigned size, FILE* out, const unsigned stringTableSectionNumber = 3; FileHeader fileHeader; - fileHeader.e_ident[EI_MAG0] = ELFMAG0; - fileHeader.e_ident[EI_MAG1] = ELFMAG1; - fileHeader.e_ident[EI_MAG2] = ELFMAG2; - fileHeader.e_ident[EI_MAG3] = ELFMAG3; - fileHeader.e_ident[EI_CLASS] = Class; - fileHeader.e_ident[EI_DATA] = encoding; - fileHeader.e_ident[EI_VERSION] = EV_CURRENT; - fileHeader.e_ident[EI_OSABI] = OSABI; - fileHeader.e_ident[EI_ABIVERSION] = 0; - fileHeader.e_type = ET_REL; - fileHeader.e_machine = machine; - fileHeader.e_version = EV_CURRENT; - fileHeader.e_entry = 0; - fileHeader.e_phoff = 0; - fileHeader.e_shoff = sizeof(FileHeader); - fileHeader.e_flags = (machine == EM_ARM ? 0x04000000 : 0); - fileHeader.e_ehsize = sizeof(FileHeader); - fileHeader.e_phentsize = 0; - fileHeader.e_phnum = 0; - fileHeader.e_shentsize = sizeof(SectionHeader); - fileHeader.e_shnum = sectionCount; - fileHeader.e_shstrndx = sectionStringTableSectionNumber; + memset(&fileHeader, 0, sizeof(FileHeader)); + fileHeader.e_ident[EI_MAG0] = V1(ELFMAG0); + fileHeader.e_ident[EI_MAG1] = V1(ELFMAG1); + fileHeader.e_ident[EI_MAG2] = V1(ELFMAG2); + fileHeader.e_ident[EI_MAG3] = V1(ELFMAG3); + fileHeader.e_ident[EI_CLASS] = V1(Class); + fileHeader.e_ident[EI_DATA] = V1(encoding); + fileHeader.e_ident[EI_VERSION] = V1(EV_CURRENT); + fileHeader.e_ident[EI_OSABI] = V1(OSABI); + fileHeader.e_ident[EI_ABIVERSION] = V1(0); + fileHeader.e_type = V2(ET_REL); + fileHeader.e_machine = V2(machine); + fileHeader.e_version = V4(EV_CURRENT); + fileHeader.e_entry = VW(0); + fileHeader.e_phoff = VW(0); + fileHeader.e_shoff = VW(sizeof(FileHeader)); + fileHeader.e_flags = V4(machine == EM_ARM ? 0x04000000 : 0); + fileHeader.e_ehsize = V2(sizeof(FileHeader)); + fileHeader.e_phentsize = V2(0); + fileHeader.e_phnum = V2(0); + fileHeader.e_shentsize = V2(sizeof(SectionHeader)); + fileHeader.e_shnum = V2(sectionCount); + fileHeader.e_shstrndx = V2(sectionStringTableSectionNumber); SectionHeader nullSection; memset(&nullSection, 0, sizeof(SectionHeader)); SectionHeader bodySection; - bodySection.sh_name = sectionNameOffset; - bodySection.sh_type = SHT_PROGBITS; - bodySection.sh_flags = sectionFlags; - bodySection.sh_addr = 0; - bodySection.sh_offset = sizeof(FileHeader) - + (sizeof(SectionHeader) * sectionCount); - bodySection.sh_size = size; - bodySection.sh_link = 0; - bodySection.sh_info = 0; - bodySection.sh_addralign = alignment; - bodySection.sh_entsize = 0; + bodySection.sh_name = V4(sectionNameOffset); + bodySection.sh_type = V4(SHT_PROGBITS); + bodySection.sh_flags = VW(sectionFlags); + bodySection.sh_addr = VW(0); + unsigned bodySectionOffset + = sizeof(FileHeader) + (sizeof(SectionHeader) * sectionCount); + bodySection.sh_offset = VW(bodySectionOffset); + unsigned bodySectionSize = size; + bodySection.sh_size = VW(bodySectionSize); + bodySection.sh_link = V4(0); + bodySection.sh_info = V4(0); + bodySection.sh_addralign = VW(alignment); + bodySection.sh_entsize = VW(0); SectionHeader sectionStringTableSection; - sectionStringTableSection.sh_name = sectionStringTableNameOffset; - sectionStringTableSection.sh_type = SHT_STRTAB; - sectionStringTableSection.sh_flags = 0; - sectionStringTableSection.sh_addr = 0; - sectionStringTableSection.sh_offset - = bodySection.sh_offset + bodySection.sh_size; - sectionStringTableSection.sh_size = sectionStringTableLength; - sectionStringTableSection.sh_link = 0; - sectionStringTableSection.sh_info = 0; - sectionStringTableSection.sh_addralign = 1; - sectionStringTableSection.sh_entsize = 0; + sectionStringTableSection.sh_name = V4(sectionStringTableNameOffset); + sectionStringTableSection.sh_type = V4(SHT_STRTAB); + sectionStringTableSection.sh_flags = VW(0); + sectionStringTableSection.sh_addr = VW(0); + unsigned sectionStringTableSectionOffset + = bodySectionOffset + bodySectionSize; + sectionStringTableSection.sh_offset = VW(sectionStringTableSectionOffset); + unsigned sectionStringTableSectionSize = sectionStringTableLength; + sectionStringTableSection.sh_size = VW(sectionStringTableSectionSize); + sectionStringTableSection.sh_link = V4(0); + sectionStringTableSection.sh_info = V4(0); + sectionStringTableSection.sh_addralign = VW(1); + sectionStringTableSection.sh_entsize = VW(0); SectionHeader stringTableSection; - stringTableSection.sh_name = stringTableNameOffset; - stringTableSection.sh_type = SHT_STRTAB; - stringTableSection.sh_flags = 0; - stringTableSection.sh_addr = 0; - stringTableSection.sh_offset = sectionStringTableSection.sh_offset - + sectionStringTableSection.sh_size; - stringTableSection.sh_size = stringTableLength; - stringTableSection.sh_link = 0; - stringTableSection.sh_info = 0; - stringTableSection.sh_addralign = 1; - stringTableSection.sh_entsize = 0; + stringTableSection.sh_name = V4(stringTableNameOffset); + stringTableSection.sh_type = V4(SHT_STRTAB); + stringTableSection.sh_flags = VW(0); + stringTableSection.sh_addr = VW(0); + unsigned stringTableSectionOffset + = sectionStringTableSectionOffset + sectionStringTableSectionSize; + stringTableSection.sh_offset = VW(stringTableSectionOffset); + unsigned stringTableSectionSize = stringTableLength; + stringTableSection.sh_size = VW(stringTableSectionSize); + stringTableSection.sh_link = V4(0); + stringTableSection.sh_info = V4(0); + stringTableSection.sh_addralign = VW(1); + stringTableSection.sh_entsize = VW(0); SectionHeader symbolTableSection; - symbolTableSection.sh_name = symbolTableNameOffset; - symbolTableSection.sh_type = SHT_SYMTAB; - symbolTableSection.sh_flags = 0; - symbolTableSection.sh_addr = 0; - symbolTableSection.sh_offset = stringTableSection.sh_offset - + stringTableSection.sh_size; - symbolTableSection.sh_size = sizeof(Symbol) * symbolCount; - symbolTableSection.sh_link = stringTableSectionNumber; - symbolTableSection.sh_info = 0; - symbolTableSection.sh_addralign = BITS_PER_WORD / 8; - symbolTableSection.sh_entsize = sizeof(Symbol); + symbolTableSection.sh_name = V4(symbolTableNameOffset); + symbolTableSection.sh_type = V4(SHT_SYMTAB); + symbolTableSection.sh_flags = VW(0); + symbolTableSection.sh_addr = VW(0); + unsigned symbolTableSectionOffset + = stringTableSectionOffset + stringTableSectionSize; + symbolTableSection.sh_offset = VW(symbolTableSectionOffset); + unsigned symbolTableSectionSize = sizeof(Symbol) * symbolCount; + symbolTableSection.sh_size = VW(symbolTableSectionSize); + symbolTableSection.sh_link = V4(stringTableSectionNumber); + symbolTableSection.sh_info = V4(0); + symbolTableSection.sh_addralign = VW(BITS_PER_WORD / 8); + symbolTableSection.sh_entsize = VW(sizeof(Symbol)); Symbol startSymbol; - startSymbol.st_name = startNameOffset; - startSymbol.st_value = 0; - startSymbol.st_size = 0; - startSymbol.st_info = SYMBOL_INFO(STB_GLOBAL, STT_NOTYPE); - startSymbol.st_other = STV_DEFAULT; - startSymbol.st_shndx = bodySectionNumber; + startSymbol.st_name = V4(startNameOffset); + startSymbol.st_value = VW(0); + startSymbol.st_size = VW(0); + startSymbol.st_info = V1(SYMBOL_INFO(STB_GLOBAL, STT_NOTYPE)); + startSymbol.st_other = V1(STV_DEFAULT); + startSymbol.st_shndx = V2(bodySectionNumber); Symbol endSymbol; - endSymbol.st_name = endNameOffset; - endSymbol.st_value = size; - endSymbol.st_size = 0; - endSymbol.st_info = SYMBOL_INFO(STB_GLOBAL, STT_NOTYPE); - endSymbol.st_other = STV_DEFAULT; - endSymbol.st_shndx = bodySectionNumber; + endSymbol.st_name = V4(endNameOffset); + endSymbol.st_value = VW(size); + endSymbol.st_size = VW(0); + endSymbol.st_info = V1(SYMBOL_INFO(STB_GLOBAL, STT_NOTYPE)); + endSymbol.st_other = V1(STV_DEFAULT); + endSymbol.st_shndx = V2(bodySectionNumber); fwrite(&fileHeader, 1, sizeof(fileHeader), out); fwrite(&nullSection, 1, sizeof(nullSection), out); diff --git a/src/binaryToObject/endianness.h b/src/binaryToObject/endianness.h new file mode 100644 index 0000000000..46cfcd8b46 --- /dev/null +++ b/src/binaryToObject/endianness.h @@ -0,0 +1,38 @@ +#ifndef ENDIANNESS_H +#define ENDIANNESS_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 + +#if (BITS_PER_WORD == 64) +# define VW(v) V8(v) +#elif (BITS_PER_WORD == 32) +# define VW(v) V4(v) +#else +# error +#endif + +#endif//ENDIANNESS_H diff --git a/src/binaryToObject/mach-o.cpp b/src/binaryToObject/mach-o.cpp index d832703200..742e3870d1 100644 --- a/src/binaryToObject/mach-o.cpp +++ b/src/binaryToObject/mach-o.cpp @@ -12,31 +12,7 @@ #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 +#include "endianness.h" #define MH_MAGIC_64 0xfeedfacf #define MH_MAGIC 0xfeedface @@ -63,7 +39,6 @@ #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 @@ -71,7 +46,6 @@ # 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