mirror of
https://github.com/autc04/Retro68.git
synced 2024-09-26 20:56:46 +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)
|
||||
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 <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#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 <PEFBinaryFormat.h>
|
||||
@ -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 <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
|
||||
{
|
||||
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<xcoffLoaderHeader.l_nimpid; i++)
|
||||
{
|
||||
@ -232,7 +299,7 @@ void mkpef(std::istream& in, std::ostream& out, std::string mainSymbol = "__star
|
||||
loaderInfoHeader.termSection = -1;
|
||||
|
||||
{
|
||||
|
||||
|
||||
in.seekg(getI32(xcoffHeader.f_symptr) +
|
||||
getI32(xcoffHeader.f_nsyms) * sizeof(external_syment));
|
||||
int stringTableLen = 0;
|
||||
@ -240,6 +307,8 @@ void mkpef(std::istream& in, std::ostream& out, std::string mainSymbol = "__star
|
||||
if(verboseFlag)
|
||||
std::cerr << "tell: " << in.tellg() << std::endl;
|
||||
in.read((char*)&stringTableLen, 4);
|
||||
eswap(&stringTableLen, "L");
|
||||
|
||||
if(verboseFlag)
|
||||
std::cerr << "string table len: " << stringTableLen << std::endl;
|
||||
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)
|
||||
{
|
||||
loaderInfoHeader.mainSection = pefSectionNumbers[xcoffSectionNames[getI16(ent.e_scnum)]];
|
||||
loaderInfoHeader.mainOffset = getI32(ent.e_value);
|
||||
std::string secName = xcoffSectionNames[getI16(ent.e_scnum)];
|
||||
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)
|
||||
std::cerr << "Writing Headers..." << std::flush;
|
||||
|
||||
eswap(&pefHeader, SwapPEFContainerHeader);
|
||||
out.write((char*)&pefHeader, sizeof(pefHeader));
|
||||
eswap(&textSectionHeader, SwapPEFSectionHeader);
|
||||
out.write((char*)&textSectionHeader, sizeof(textSectionHeader));
|
||||
eswap(&dataSectionHeader, SwapPEFSectionHeader);
|
||||
out.write((char*)&dataSectionHeader, sizeof(dataSectionHeader));
|
||||
eswap(&loaderSectionHeader, SwapPEFSectionHeader);
|
||||
out.write((char*)&loaderSectionHeader, sizeof(loaderSectionHeader));
|
||||
if(verboseFlag)
|
||||
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.read(buf, textSectionHeader.containerLength);
|
||||
out.write(buf, textSectionHeader.containerLength);
|
||||
in.read(buf, textSize);
|
||||
out.write(buf, textSize);
|
||||
delete[] buf;
|
||||
}
|
||||
{
|
||||
char *buf = new char[dataSectionHeader.containerLength];
|
||||
char *buf = new char[dataSize];
|
||||
|
||||
in.seekg(getI32(xcoffSections[".data"].s_scnptr));
|
||||
in.read(buf, dataSectionHeader.containerLength);
|
||||
out.write(buf, dataSectionHeader.containerLength);
|
||||
in.read(buf, dataSize);
|
||||
out.write(buf, dataSize);
|
||||
delete[] buf;
|
||||
}
|
||||
if(verboseFlag)
|
||||
std::cerr << "done.\n";
|
||||
eswap(&loaderInfoHeader, SwapPEFLoaderInfoHeader);
|
||||
out.write((char*)&loaderInfoHeader, sizeof(loaderInfoHeader));
|
||||
|
||||
int firstImportedSymbol = 0;
|
||||
@ -528,6 +604,7 @@ void mkpef(std::istream& in, std::ostream& out, std::string mainSymbol = "__star
|
||||
if(importLibs[i].weak)
|
||||
impLib.options = kPEFWeakImportLibMask;
|
||||
|
||||
eswap(&impLib, SwapPEFImportedLibrary);
|
||||
out.write((char*)&impLib, sizeof(impLib));
|
||||
}
|
||||
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;
|
||||
sym.classAndName = PEFComposeImportedSymbol(kPEFTVectorSymbol /* ### */,
|
||||
importLibs[i].symNameOffsets[j]);
|
||||
eswap(&sym, SwapPEFImportedSymbol);
|
||||
out.write((char*)&sym, sizeof(sym));
|
||||
}
|
||||
}
|
||||
@ -545,10 +623,12 @@ void mkpef(std::istream& in, std::ostream& out, std::string mainSymbol = "__star
|
||||
|
||||
if(verboseFlag)
|
||||
std::cerr << "relocations..." << std::flush;
|
||||
eswap(&dataRelocationHeader, SwapPEFLoaderRelocationHeader);
|
||||
out.write((char*)&dataRelocationHeader, sizeof(dataRelocationHeader));
|
||||
for(unsigned i=0;i<relocInstructions.size();i++)
|
||||
{
|
||||
short insn = relocInstructions[i];
|
||||
eswap(&insn, "s");
|
||||
out.write((char*)&insn, sizeof(insn));
|
||||
}
|
||||
if(verboseFlag)
|
||||
|
@ -132,7 +132,7 @@ struct internal_ldhdr
|
||||
/* The version number:
|
||||
1 : 32 bit
|
||||
2 : 64 bit */
|
||||
unsigned long l_version;
|
||||
unsigned int/*###*/ l_version;
|
||||
|
||||
/* The number of symbol table entries. */
|
||||
bfd_size_type l_nsyms;
|
||||
@ -176,11 +176,11 @@ struct internal_ldsym
|
||||
struct
|
||||
{
|
||||
/* 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
|
||||
than SYMNMLEN characters. */
|
||||
long _l_offset;
|
||||
int/*###*/ _l_offset;
|
||||
}
|
||||
_l_l;
|
||||
}
|
||||
@ -240,7 +240,7 @@ struct xcoff_link_hash_entry
|
||||
|
||||
/* Symbol index in output file. Set to -1 initially. Set to -2 if
|
||||
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
|
||||
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
|
||||
symbol index of the C_HIDEXT XMC_TC or XMC_TD symbol. */
|
||||
long toc_indx;
|
||||
int/*###*/ toc_indx;
|
||||
}
|
||||
u;
|
||||
|
||||
@ -270,10 +270,10 @@ struct xcoff_link_hash_entry
|
||||
/* If XCOFF_BUILT_LDSYM is set, this is the .loader symbol table
|
||||
index. If XCOFF_BUILD_LDSYM is clear, and XCOFF_IMPORT is set,
|
||||
this is the l_ifile value. */
|
||||
long ldindx;
|
||||
int/*###*/ ldindx;
|
||||
|
||||
/* Some linker flags. */
|
||||
unsigned long flags;
|
||||
unsigned int/*###*/ flags;
|
||||
|
||||
/* The storage mapping class. */
|
||||
unsigned char smclas;
|
||||
@ -363,7 +363,7 @@ struct xcoff_link_hash_table
|
||||
struct xcoff_import_file *imports;
|
||||
|
||||
/* Required alignment of sections within the output file. */
|
||||
unsigned long file_align;
|
||||
unsigned int/*###*/ file_align;
|
||||
|
||||
/* Whether the .text section must be read-only. */
|
||||
bfd_boolean textro;
|
||||
|
Loading…
Reference in New Issue
Block a user