From 332bb90e5224f306e1dc4bdfe858d7d8ff4cc6bb Mon Sep 17 00:00:00 2001 From: Wolfgang Thaller Date: Sun, 30 Aug 2015 15:27:06 +0200 Subject: [PATCH] ppc: MakePEF - fix endian and 64bit issues --- MakePEF/CMakeLists.txt | 2 + MakePEF/MakePEF.cc | 108 +++++++++++++++++++++++++++++++++++------ MakePEF/xcoff.h | 16 +++--- 3 files changed, 104 insertions(+), 22 deletions(-) diff --git a/MakePEF/CMakeLists.txt b/MakePEF/CMakeLists.txt index 15df3e3dfa..ae560e9958 100644 --- a/MakePEF/CMakeLists.txt +++ b/MakePEF/CMakeLists.txt @@ -2,3 +2,5 @@ set(CMAKE_CXX_FLAGS "--std=c++11 -Wall -Werror=return-type -Wno-multichar") include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../CIncludes) add_executable(MakePEF MakePEF.cc xcoff.h powerpc.h external.h) + +install(TARGETS MakePEF RUNTIME DESTINATION bin) diff --git a/MakePEF/MakePEF.cc b/MakePEF/MakePEF.cc index 887399264a..0842f8470e 100755 --- a/MakePEF/MakePEF.cc +++ b/MakePEF/MakePEF.cc @@ -8,11 +8,13 @@ #include #include +#include + #include "powerpc.h" /* Provide minimal definitions from ConfitionalMacros.h. - * ConditionalMacros.h can't deal with our host C compiler.9 + * ConditionalMacros.h can't deal with our host C compiler. */ #define __CONDITIONALMACROS__ #define TYPE_BOOL 1 @@ -22,6 +24,20 @@ #define CALLBACK_API_C(ret,name) ret (*name) #define ONEWORDINLINE(x) #define FOUR_CHAR_CODE(x) (x) +#define PRAGMA_STRUCT_PACKPUSH 1 + + /* Can't use MacTypes.h either, + * as older versions are hardcoded to 32 bit platforms. + */ +#define __MACTYPES__ +typedef uint8_t UInt8; +typedef int8_t SInt8; +typedef uint16_t UInt16; +typedef int16_t SInt16; +typedef uint32_t UInt32; +typedef int32_t SInt32; +typedef uint32_t OSType; + /* Definitions for PEF, from Apple's Universal Interfaces */ #include @@ -90,14 +106,55 @@ bool verboseFlag = false; inline int getI16(char *x) { - return *(short*)x; + return (((unsigned short)x[0]) << 8) | (unsigned short)x[1]; } inline int getI32(char *x) { - return *(int*)x; + return (((unsigned char)x[0]) << 24) | (((unsigned char)x[1]) << 16) + | (((unsigned char)x[2]) << 8) | ((unsigned char)x[3]); } +template +void eswap(T *data, const char * format) +{ + int endianTest = 1; + if(*(char*)&endianTest == 0) + return; + + char *p = reinterpret_cast(data); + const char *q = format; + while(char c = *q++) + { + if(c == 'L') + { + std::swap(p[0], p[3]); + std::swap(p[1], p[2]); + p += 4; + } + else if(c == 's') + { + std::swap(p[0], p[1]); + p += 2; + } + else + { + assert(c == '.'); + ++p; + } + } + + //assert(p == reinterpret_cast(data+1)); + assert(p == reinterpret_cast(data) + sizeof(T)); +} + +const char *SwapPEFContainerHeader = "LLLLLLLLssL"; +const char *SwapPEFSectionHeader = "LLLLLL...."; +const char *SwapPEFLoaderInfoHeader = "LLLLLLLLLLLLLL"; +const char *SwapPEFImportedLibrary = "LLLLL..s"; +const char *SwapPEFImportedSymbol = "L"; +const char *SwapPEFLoaderRelocationHeader = "ssLL"; + class ImportLib { public: @@ -124,6 +181,11 @@ void mkpef(std::istream& in, std::ostream& out, std::string mainSymbol = "__star if(verboseFlag) std::cerr << "flags: " << std::hex << getI16(xcoffHeader.f_flags) << std::dec << std::endl; + if(verboseFlag) + { + std::cerr << "symptr: " << getI32(xcoffHeader.f_symptr) << std::endl; + std::cerr << "nsyms: " << getI32(xcoffHeader.f_nsyms) << std::endl; + } int nSections = getI16(xcoffHeader.f_nscns); @@ -151,9 +213,13 @@ void mkpef(std::istream& in, std::ostream& out, std::string mainSymbol = "__star external_scnhdr xcoffSection; in.read((char*) &xcoffSection, sizeof(xcoffSection)); - + if(verboseFlag) + { std::cerr << "section: " << xcoffSection.s_name << std::endl; + std::cerr << " at: " << getI32(xcoffSection.s_scnptr) << std::endl; + std::cerr << " sz: " << getI32(xcoffSection.s_size) << std::endl; + } xcoffSections[xcoffSection.s_name] = xcoffSection; xcoffSectionNumbers[xcoffSection.s_name] = i+1; xcoffSectionNames[i+1] = xcoffSection.s_name; @@ -174,7 +240,8 @@ void mkpef(std::istream& in, std::ostream& out, std::string mainSymbol = "__star in.read(loaderSectionPtr, getI32(xcoffLoaderSection.s_size)); xcoffLoaderHeader = *(internal_ldhdr*)loaderSectionPtr; - + eswap(&xcoffLoaderHeader, "LLLLLLLLLL"); + char *p = loaderSectionPtr + xcoffLoaderHeader.l_impoff; for(unsigned i=0; i