mirror of
https://github.com/autc04/Retro68.git
synced 2024-11-15 07:07:58 +00:00
ppc: MakePEF - fix endian and 64bit issues
This commit is contained in:
parent
df8031a37e
commit
332bb90e52
@ -2,3 +2,5 @@ set(CMAKE_CXX_FLAGS "--std=c++11 -Wall -Werror=return-type -Wno-multichar")
|
|||||||
|
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../CIncludes)
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../CIncludes)
|
||||||
add_executable(MakePEF MakePEF.cc xcoff.h powerpc.h external.h)
|
add_executable(MakePEF MakePEF.cc xcoff.h powerpc.h external.h)
|
||||||
|
|
||||||
|
install(TARGETS MakePEF RUNTIME DESTINATION bin)
|
||||||
|
@ -8,11 +8,13 @@
|
|||||||
#include <alloca.h>
|
#include <alloca.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "powerpc.h"
|
#include "powerpc.h"
|
||||||
|
|
||||||
|
|
||||||
/* Provide minimal definitions from ConfitionalMacros.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 __CONDITIONALMACROS__
|
||||||
#define TYPE_BOOL 1
|
#define TYPE_BOOL 1
|
||||||
@ -22,6 +24,20 @@
|
|||||||
#define CALLBACK_API_C(ret,name) ret (*name)
|
#define CALLBACK_API_C(ret,name) ret (*name)
|
||||||
#define ONEWORDINLINE(x)
|
#define ONEWORDINLINE(x)
|
||||||
#define FOUR_CHAR_CODE(x) (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 */
|
/* Definitions for PEF, from Apple's Universal Interfaces */
|
||||||
#include <PEFBinaryFormat.h>
|
#include <PEFBinaryFormat.h>
|
||||||
@ -90,14 +106,55 @@ bool verboseFlag = false;
|
|||||||
|
|
||||||
inline int getI16(char *x)
|
inline int getI16(char *x)
|
||||||
{
|
{
|
||||||
return *(short*)x;
|
return (((unsigned short)x[0]) << 8) | (unsigned short)x[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int getI32(char *x)
|
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 <typename T>
|
||||||
|
void eswap(T *data, const char * format)
|
||||||
|
{
|
||||||
|
int endianTest = 1;
|
||||||
|
if(*(char*)&endianTest == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
char *p = reinterpret_cast<char*>(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<char*>(data+1));
|
||||||
|
assert(p == reinterpret_cast<char*>(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
|
class ImportLib
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -124,6 +181,11 @@ void mkpef(std::istream& in, std::ostream& out, std::string mainSymbol = "__star
|
|||||||
|
|
||||||
if(verboseFlag)
|
if(verboseFlag)
|
||||||
std::cerr << "flags: " << std::hex << getI16(xcoffHeader.f_flags) << std::dec << std::endl;
|
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);
|
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;
|
external_scnhdr xcoffSection;
|
||||||
|
|
||||||
in.read((char*) &xcoffSection, sizeof(xcoffSection));
|
in.read((char*) &xcoffSection, sizeof(xcoffSection));
|
||||||
|
|
||||||
if(verboseFlag)
|
if(verboseFlag)
|
||||||
|
{
|
||||||
std::cerr << "section: " << xcoffSection.s_name << std::endl;
|
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;
|
xcoffSections[xcoffSection.s_name] = xcoffSection;
|
||||||
xcoffSectionNumbers[xcoffSection.s_name] = i+1;
|
xcoffSectionNumbers[xcoffSection.s_name] = i+1;
|
||||||
xcoffSectionNames[i+1] = xcoffSection.s_name;
|
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));
|
in.read(loaderSectionPtr, getI32(xcoffLoaderSection.s_size));
|
||||||
|
|
||||||
xcoffLoaderHeader = *(internal_ldhdr*)loaderSectionPtr;
|
xcoffLoaderHeader = *(internal_ldhdr*)loaderSectionPtr;
|
||||||
|
eswap(&xcoffLoaderHeader, "LLLLLLLLLL");
|
||||||
|
|
||||||
char *p = loaderSectionPtr + xcoffLoaderHeader.l_impoff;
|
char *p = loaderSectionPtr + xcoffLoaderHeader.l_impoff;
|
||||||
for(unsigned i=0; i<xcoffLoaderHeader.l_nimpid; i++)
|
for(unsigned i=0; i<xcoffLoaderHeader.l_nimpid; i++)
|
||||||
{
|
{
|
||||||
@ -232,7 +299,7 @@ void mkpef(std::istream& in, std::ostream& out, std::string mainSymbol = "__star
|
|||||||
loaderInfoHeader.termSection = -1;
|
loaderInfoHeader.termSection = -1;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
in.seekg(getI32(xcoffHeader.f_symptr) +
|
in.seekg(getI32(xcoffHeader.f_symptr) +
|
||||||
getI32(xcoffHeader.f_nsyms) * sizeof(external_syment));
|
getI32(xcoffHeader.f_nsyms) * sizeof(external_syment));
|
||||||
int stringTableLen = 0;
|
int stringTableLen = 0;
|
||||||
@ -240,6 +307,8 @@ void mkpef(std::istream& in, std::ostream& out, std::string mainSymbol = "__star
|
|||||||
if(verboseFlag)
|
if(verboseFlag)
|
||||||
std::cerr << "tell: " << in.tellg() << std::endl;
|
std::cerr << "tell: " << in.tellg() << std::endl;
|
||||||
in.read((char*)&stringTableLen, 4);
|
in.read((char*)&stringTableLen, 4);
|
||||||
|
eswap(&stringTableLen, "L");
|
||||||
|
|
||||||
if(verboseFlag)
|
if(verboseFlag)
|
||||||
std::cerr << "string table len: " << stringTableLen << std::endl;
|
std::cerr << "string table len: " << stringTableLen << std::endl;
|
||||||
char *stringTable = new char[stringTableLen+1];
|
char *stringTable = new char[stringTableLen+1];
|
||||||
@ -302,8 +371,9 @@ void mkpef(std::istream& in, std::ostream& out, std::string mainSymbol = "__star
|
|||||||
{
|
{
|
||||||
if(name == mainSymbol)
|
if(name == mainSymbol)
|
||||||
{
|
{
|
||||||
loaderInfoHeader.mainSection = pefSectionNumbers[xcoffSectionNames[getI16(ent.e_scnum)]];
|
std::string secName = xcoffSectionNames[getI16(ent.e_scnum)];
|
||||||
loaderInfoHeader.mainOffset = getI32(ent.e_value);
|
loaderInfoHeader.mainSection = pefSectionNumbers[secName];
|
||||||
|
loaderInfoHeader.mainOffset = getI32(ent.e_value) - getI32(xcoffSections[secName].s_vaddr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -486,30 +556,36 @@ void mkpef(std::istream& in, std::ostream& out, std::string mainSymbol = "__star
|
|||||||
|
|
||||||
if(verboseFlag)
|
if(verboseFlag)
|
||||||
std::cerr << "Writing Headers..." << std::flush;
|
std::cerr << "Writing Headers..." << std::flush;
|
||||||
|
|
||||||
|
eswap(&pefHeader, SwapPEFContainerHeader);
|
||||||
out.write((char*)&pefHeader, sizeof(pefHeader));
|
out.write((char*)&pefHeader, sizeof(pefHeader));
|
||||||
|
eswap(&textSectionHeader, SwapPEFSectionHeader);
|
||||||
out.write((char*)&textSectionHeader, sizeof(textSectionHeader));
|
out.write((char*)&textSectionHeader, sizeof(textSectionHeader));
|
||||||
|
eswap(&dataSectionHeader, SwapPEFSectionHeader);
|
||||||
out.write((char*)&dataSectionHeader, sizeof(dataSectionHeader));
|
out.write((char*)&dataSectionHeader, sizeof(dataSectionHeader));
|
||||||
|
eswap(&loaderSectionHeader, SwapPEFSectionHeader);
|
||||||
out.write((char*)&loaderSectionHeader, sizeof(loaderSectionHeader));
|
out.write((char*)&loaderSectionHeader, sizeof(loaderSectionHeader));
|
||||||
if(verboseFlag)
|
if(verboseFlag)
|
||||||
std::cerr << "done.\nCopying text and data..." << std::flush;
|
std::cerr << "done.\nCopying text and data..." << std::flush;
|
||||||
{
|
{
|
||||||
char *buf = new char[textSectionHeader.containerLength];
|
char *buf = new char[textSize];
|
||||||
|
|
||||||
in.seekg(getI32(xcoffSections[".text"].s_scnptr));
|
in.seekg(getI32(xcoffSections[".text"].s_scnptr));
|
||||||
in.read(buf, textSectionHeader.containerLength);
|
in.read(buf, textSize);
|
||||||
out.write(buf, textSectionHeader.containerLength);
|
out.write(buf, textSize);
|
||||||
delete[] buf;
|
delete[] buf;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
char *buf = new char[dataSectionHeader.containerLength];
|
char *buf = new char[dataSize];
|
||||||
|
|
||||||
in.seekg(getI32(xcoffSections[".data"].s_scnptr));
|
in.seekg(getI32(xcoffSections[".data"].s_scnptr));
|
||||||
in.read(buf, dataSectionHeader.containerLength);
|
in.read(buf, dataSize);
|
||||||
out.write(buf, dataSectionHeader.containerLength);
|
out.write(buf, dataSize);
|
||||||
delete[] buf;
|
delete[] buf;
|
||||||
}
|
}
|
||||||
if(verboseFlag)
|
if(verboseFlag)
|
||||||
std::cerr << "done.\n";
|
std::cerr << "done.\n";
|
||||||
|
eswap(&loaderInfoHeader, SwapPEFLoaderInfoHeader);
|
||||||
out.write((char*)&loaderInfoHeader, sizeof(loaderInfoHeader));
|
out.write((char*)&loaderInfoHeader, sizeof(loaderInfoHeader));
|
||||||
|
|
||||||
int firstImportedSymbol = 0;
|
int firstImportedSymbol = 0;
|
||||||
@ -528,6 +604,7 @@ void mkpef(std::istream& in, std::ostream& out, std::string mainSymbol = "__star
|
|||||||
if(importLibs[i].weak)
|
if(importLibs[i].weak)
|
||||||
impLib.options = kPEFWeakImportLibMask;
|
impLib.options = kPEFWeakImportLibMask;
|
||||||
|
|
||||||
|
eswap(&impLib, SwapPEFImportedLibrary);
|
||||||
out.write((char*)&impLib, sizeof(impLib));
|
out.write((char*)&impLib, sizeof(impLib));
|
||||||
}
|
}
|
||||||
for(unsigned i=1;i<importLibs.size();i++)
|
for(unsigned i=1;i<importLibs.size();i++)
|
||||||
@ -537,6 +614,7 @@ void mkpef(std::istream& in, std::ostream& out, std::string mainSymbol = "__star
|
|||||||
PEFImportedSymbol sym;
|
PEFImportedSymbol sym;
|
||||||
sym.classAndName = PEFComposeImportedSymbol(kPEFTVectorSymbol /* ### */,
|
sym.classAndName = PEFComposeImportedSymbol(kPEFTVectorSymbol /* ### */,
|
||||||
importLibs[i].symNameOffsets[j]);
|
importLibs[i].symNameOffsets[j]);
|
||||||
|
eswap(&sym, SwapPEFImportedSymbol);
|
||||||
out.write((char*)&sym, sizeof(sym));
|
out.write((char*)&sym, sizeof(sym));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -545,10 +623,12 @@ void mkpef(std::istream& in, std::ostream& out, std::string mainSymbol = "__star
|
|||||||
|
|
||||||
if(verboseFlag)
|
if(verboseFlag)
|
||||||
std::cerr << "relocations..." << std::flush;
|
std::cerr << "relocations..." << std::flush;
|
||||||
|
eswap(&dataRelocationHeader, SwapPEFLoaderRelocationHeader);
|
||||||
out.write((char*)&dataRelocationHeader, sizeof(dataRelocationHeader));
|
out.write((char*)&dataRelocationHeader, sizeof(dataRelocationHeader));
|
||||||
for(unsigned i=0;i<relocInstructions.size();i++)
|
for(unsigned i=0;i<relocInstructions.size();i++)
|
||||||
{
|
{
|
||||||
short insn = relocInstructions[i];
|
short insn = relocInstructions[i];
|
||||||
|
eswap(&insn, "s");
|
||||||
out.write((char*)&insn, sizeof(insn));
|
out.write((char*)&insn, sizeof(insn));
|
||||||
}
|
}
|
||||||
if(verboseFlag)
|
if(verboseFlag)
|
||||||
|
@ -132,7 +132,7 @@ struct internal_ldhdr
|
|||||||
/* The version number:
|
/* The version number:
|
||||||
1 : 32 bit
|
1 : 32 bit
|
||||||
2 : 64 bit */
|
2 : 64 bit */
|
||||||
unsigned long l_version;
|
unsigned int/*###*/ l_version;
|
||||||
|
|
||||||
/* The number of symbol table entries. */
|
/* The number of symbol table entries. */
|
||||||
bfd_size_type l_nsyms;
|
bfd_size_type l_nsyms;
|
||||||
@ -176,11 +176,11 @@ struct internal_ldsym
|
|||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
/* Zero if the symbol name is more than SYMNMLEN characters. */
|
/* Zero if the symbol name is more than SYMNMLEN characters. */
|
||||||
long _l_zeroes;
|
int/*###*/ _l_zeroes;
|
||||||
|
|
||||||
/* The offset in the string table if the symbol name is more
|
/* The offset in the string table if the symbol name is more
|
||||||
than SYMNMLEN characters. */
|
than SYMNMLEN characters. */
|
||||||
long _l_offset;
|
int/*###*/ _l_offset;
|
||||||
}
|
}
|
||||||
_l_l;
|
_l_l;
|
||||||
}
|
}
|
||||||
@ -240,7 +240,7 @@ struct xcoff_link_hash_entry
|
|||||||
|
|
||||||
/* Symbol index in output file. Set to -1 initially. Set to -2 if
|
/* Symbol index in output file. Set to -1 initially. Set to -2 if
|
||||||
there is a reloc against this symbol. */
|
there is a reloc against this symbol. */
|
||||||
long indx;
|
int/*###*/ indx;
|
||||||
|
|
||||||
/* If we have created a TOC entry for this symbol, this is the .tc
|
/* If we have created a TOC entry for this symbol, this is the .tc
|
||||||
section which holds it. */
|
section which holds it. */
|
||||||
@ -254,7 +254,7 @@ struct xcoff_link_hash_entry
|
|||||||
|
|
||||||
/* If the TOC entry comes from an input file, this is set to the
|
/* If the TOC entry comes from an input file, this is set to the
|
||||||
symbol index of the C_HIDEXT XMC_TC or XMC_TD symbol. */
|
symbol index of the C_HIDEXT XMC_TC or XMC_TD symbol. */
|
||||||
long toc_indx;
|
int/*###*/ toc_indx;
|
||||||
}
|
}
|
||||||
u;
|
u;
|
||||||
|
|
||||||
@ -270,10 +270,10 @@ struct xcoff_link_hash_entry
|
|||||||
/* If XCOFF_BUILT_LDSYM is set, this is the .loader symbol table
|
/* If XCOFF_BUILT_LDSYM is set, this is the .loader symbol table
|
||||||
index. If XCOFF_BUILD_LDSYM is clear, and XCOFF_IMPORT is set,
|
index. If XCOFF_BUILD_LDSYM is clear, and XCOFF_IMPORT is set,
|
||||||
this is the l_ifile value. */
|
this is the l_ifile value. */
|
||||||
long ldindx;
|
int/*###*/ ldindx;
|
||||||
|
|
||||||
/* Some linker flags. */
|
/* Some linker flags. */
|
||||||
unsigned long flags;
|
unsigned int/*###*/ flags;
|
||||||
|
|
||||||
/* The storage mapping class. */
|
/* The storage mapping class. */
|
||||||
unsigned char smclas;
|
unsigned char smclas;
|
||||||
@ -363,7 +363,7 @@ struct xcoff_link_hash_table
|
|||||||
struct xcoff_import_file *imports;
|
struct xcoff_import_file *imports;
|
||||||
|
|
||||||
/* Required alignment of sections within the output file. */
|
/* Required alignment of sections within the output file. */
|
||||||
unsigned long file_align;
|
unsigned int/*###*/ file_align;
|
||||||
|
|
||||||
/* Whether the .text section must be read-only. */
|
/* Whether the .text section must be read-only. */
|
||||||
bfd_boolean textro;
|
bfd_boolean textro;
|
||||||
|
Loading…
Reference in New Issue
Block a user