mirror of
https://github.com/autc04/Retro68.git
synced 2024-11-26 06:49:33 +00:00
ppc: PEFTools: closer to working
This commit is contained in:
parent
4577098201
commit
59827d52b4
@ -4,5 +4,6 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../CIncludes)
|
|||||||
add_executable(MakePEF MakePEF.cc xcoff.h powerpc.h external.h PEF.h)
|
add_executable(MakePEF MakePEF.cc xcoff.h powerpc.h external.h PEF.h)
|
||||||
|
|
||||||
add_executable(MakeImport MakeImport.cc PEF.h)
|
add_executable(MakeImport MakeImport.cc PEF.h)
|
||||||
|
target_link_libraries(MakeImport ResourceFiles)
|
||||||
|
|
||||||
install(TARGETS MakePEF RUNTIME DESTINATION bin)
|
install(TARGETS MakePEF MakeImport RUNTIME DESTINATION bin)
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
#include "PEF.h"
|
#include "PEF.h"
|
||||||
|
|
||||||
|
#include "ResourceFile.h"
|
||||||
|
|
||||||
using std::cout;
|
using std::cout;
|
||||||
using std::cerr;
|
using std::cerr;
|
||||||
using std::endl;
|
using std::endl;
|
||||||
@ -24,29 +26,53 @@ using std::string;
|
|||||||
using std::ofstream;
|
using std::ofstream;
|
||||||
using std::ios_base;
|
using std::ios_base;
|
||||||
|
|
||||||
// Change this to support little-endian hosts:
|
UInt16 eu16(UInt16 x)
|
||||||
UInt16 eu16(UInt16 x) { return x; }
|
{
|
||||||
UInt32 eu32(UInt32 x) { return x; }
|
int little = 1;
|
||||||
SInt16 es16(SInt16 x) { return x; }
|
if(*(char*)&little)
|
||||||
SInt32 es32(SInt32 x) { return x; }
|
{
|
||||||
|
return (x << 8) | (x >> 8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UInt32 eu32(UInt32 x)
|
||||||
|
{
|
||||||
|
int little = 1;
|
||||||
|
if(*(char*)&little)
|
||||||
|
{
|
||||||
|
return (x << 24)
|
||||||
|
| ((x & 0xFF00) << 8)
|
||||||
|
| ((x >> 8) & 0xFF00)
|
||||||
|
| (x >> 24);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SInt16 es16(SInt16 x) { return eu16(x); }
|
||||||
|
SInt32 es32(SInt32 x) { return eu32(x); }
|
||||||
|
|
||||||
void MakeImportLibrary(char *pefptr, size_t pefsize, string libname, string name)
|
void MakeImportLibrary(const char *pefptr, size_t pefsize, string libname, string name)
|
||||||
{
|
{
|
||||||
PEFContainerHeader *containerHeader = (PEFContainerHeader*) pefptr;
|
PEFContainerHeader *containerHeader = (PEFContainerHeader*) pefptr;
|
||||||
|
|
||||||
assert(eu32(containerHeader->tag1) == 'Joy!');
|
assert(eu32(containerHeader->tag1) == 'Joy!');
|
||||||
assert(eu32(containerHeader->tag2) == 'peff');
|
assert(eu32(containerHeader->tag2) == 'peff');
|
||||||
|
|
||||||
PEFSectionHeader *sectionHeaders
|
const PEFSectionHeader *sectionHeaders
|
||||||
= (PEFSectionHeader*) (pefptr + kPEFFirstSectionHeaderOffset);
|
= (const PEFSectionHeader*) (pefptr + kPEFFirstSectionHeaderOffset);
|
||||||
|
|
||||||
PEFSectionHeader *loaderHeader = NULL;
|
const PEFSectionHeader *loaderHeader = NULL;
|
||||||
UInt16 n = eu16(containerHeader->sectionCount);
|
UInt16 n = eu16(containerHeader->sectionCount);
|
||||||
for(UInt16 i=0; i < n; i++)
|
for(UInt16 i=0; i < n; i++)
|
||||||
if(sectionHeaders[i].sectionKind == kPEFLoaderSection)
|
if(sectionHeaders[i].sectionKind == kPEFLoaderSection)
|
||||||
loaderHeader = §ionHeaders[i];
|
loaderHeader = §ionHeaders[i];
|
||||||
|
|
||||||
PEFLoaderInfoHeader *loaderInfoHeader
|
const PEFLoaderInfoHeader *loaderInfoHeader
|
||||||
= (PEFLoaderInfoHeader*) (pefptr + eu32(loaderHeader->containerOffset));
|
= (PEFLoaderInfoHeader*) (pefptr + eu32(loaderHeader->containerOffset));
|
||||||
|
|
||||||
|
|
||||||
@ -57,23 +83,23 @@ void MakeImportLibrary(char *pefptr, size_t pefsize, string libname, string name
|
|||||||
|
|
||||||
UInt32 nSymbols = eu32(loaderInfoHeader->exportedSymbolCount);
|
UInt32 nSymbols = eu32(loaderInfoHeader->exportedSymbolCount);
|
||||||
|
|
||||||
char *symbols /* use char pointer to avoid packing issues */
|
const char *symbols /* use char pointer to avoid packing issues */
|
||||||
= (pefptr + eu32(loaderHeader->containerOffset)
|
= (pefptr + eu32(loaderHeader->containerOffset)
|
||||||
+ eu32(loaderInfoHeader->exportHashOffset)
|
+ eu32(loaderInfoHeader->exportHashOffset)
|
||||||
+ hashTableSize * sizeof(PEFExportedSymbolHashSlot)
|
+ hashTableSize * sizeof(PEFExportedSymbolHashSlot)
|
||||||
+ nSymbols * sizeof(PEFExportedSymbolKey));
|
+ nSymbols * sizeof(PEFExportedSymbolKey));
|
||||||
|
|
||||||
char *stringTable = pefptr
|
const char *stringTable = pefptr
|
||||||
+ eu32(loaderHeader->containerOffset)
|
+ eu32(loaderHeader->containerOffset)
|
||||||
+ eu32(loaderInfoHeader->loaderStringsOffset);
|
+ eu32(loaderInfoHeader->loaderStringsOffset);
|
||||||
char *stringTableEnd = pefptr
|
const char *stringTableEnd = pefptr
|
||||||
+ eu32(loaderHeader->containerOffset)
|
+ eu32(loaderHeader->containerOffset)
|
||||||
+ eu32(loaderInfoHeader->exportHashOffset);
|
+ eu32(loaderInfoHeader->exportHashOffset);
|
||||||
vector< pair< const char *, UInt8 > > classesAndNamePtrs;
|
vector< pair< const char *, UInt8 > > classesAndNamePtrs;
|
||||||
|
|
||||||
for(UInt32 i=0; i < nSymbols; i++)
|
for(UInt32 i=0; i < nSymbols; i++)
|
||||||
{
|
{
|
||||||
PEFExportedSymbol sym = * (PEFExportedSymbol*) (symbols + 10*i);
|
const PEFExportedSymbol sym = * (PEFExportedSymbol*) (symbols + 10*i);
|
||||||
|
|
||||||
UInt8 symclass = PEFExportedSymbolClass(eu32(sym.classAndName));
|
UInt8 symclass = PEFExportedSymbolClass(eu32(sym.classAndName));
|
||||||
UInt32 nameoffset = PEFExportedSymbolNameOffset(eu32(sym.classAndName));
|
UInt32 nameoffset = PEFExportedSymbolNameOffset(eu32(sym.classAndName));
|
||||||
@ -110,7 +136,6 @@ void MakeImportLibrary(char *pefptr, size_t pefsize, string libname, string name
|
|||||||
|
|
||||||
{
|
{
|
||||||
ofstream expFile("stub.exp");
|
ofstream expFile("stub.exp");
|
||||||
//ofstream cFile("stub.c");
|
|
||||||
ofstream sFile("stub.s");
|
ofstream sFile("stub.s");
|
||||||
sFile << "\t.toc\n";
|
sFile << "\t.toc\n";
|
||||||
for(UInt32 i=0; i< nSymbols; i++)
|
for(UInt32 i=0; i< nSymbols; i++)
|
||||||
@ -147,46 +172,44 @@ void MakeImportLibrary(char *pefptr, size_t pefsize, string libname, string name
|
|||||||
system("powerpc-apple-macos-as stub.s -o stub.o");
|
system("powerpc-apple-macos-as stub.s -o stub.o");
|
||||||
system(("powerpc-apple-macos-ld -shared --no-check-sections "
|
system(("powerpc-apple-macos-ld -shared --no-check-sections "
|
||||||
"-bexport:stub.exp -o'"
|
"-bexport:stub.exp -o'"
|
||||||
+ name + ".o' stub.o").c_str());
|
+ libname + "' stub.o").c_str());
|
||||||
system(("powerpc-apple-macos-ar cq '" + libname + "' '" + name + ".o'").c_str());
|
//system(("powerpc-apple-macos-ar cq '" + libname + "' '" + name + ".o'").c_str());
|
||||||
system(("powerpc-apple-macos-ar t '" + libname + "'").c_str());
|
//system(("powerpc-apple-macos-ar t '" + libname + "'").c_str());
|
||||||
|
|
||||||
unlink("stub.exp");
|
unlink("stub.exp");
|
||||||
unlink("stub.o");
|
unlink("stub.o");
|
||||||
unlink("stub.c");
|
unlink("stub.s");
|
||||||
unlink((name + ".o").c_str());
|
//unlink((name + ".o").c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MakeImportLibraryMulti(char *file, const char *path, string libname)
|
void MakeImportLibraryMulti(const char *path, string libname)
|
||||||
{
|
{
|
||||||
FSRef ref;
|
ResourceFile resFile(path);
|
||||||
FSPathMakeRef((const UInt8*) path, &ref, NULL);
|
assert(resFile.read());
|
||||||
|
|
||||||
short refnum = FSOpenResFile(&ref, fsRdPerm);
|
const char *file = resFile.data.data();
|
||||||
|
Resource& cfrgRes = resFile.resources.resources[ResRef("cfrg",0)];
|
||||||
Handle h = Get1Resource('cfrg', 0);
|
|
||||||
HLock(h);
|
|
||||||
|
|
||||||
unlink(("lib" + libname + ".a").c_str());
|
unlink(("lib" + libname + ".a").c_str());
|
||||||
|
|
||||||
CFragResource *cfrg = (CFragResource*) *h;
|
CFragResource *cfrg = (CFragResource *)cfrgRes.getData().data();
|
||||||
CFragResourceMember *member = &(cfrg -> firstMember);
|
CFragResourceMember *member = &(cfrg -> firstMember);
|
||||||
|
|
||||||
for(UInt16 i = 0; i < cfrg->memberCount; i++)
|
for(UInt16 i = 0; i < eu16(cfrg->memberCount); i++)
|
||||||
{
|
{
|
||||||
string membername =
|
string membername =
|
||||||
string(member->name+1, member->name+1+member->name[0]);
|
string(member->name+1, member->name+1+member->name[0]);
|
||||||
cout << i << ": " << membername << endl;
|
cout << i << ": " << membername << endl;
|
||||||
if(member->architecture == kPowerPCCFragArch
|
if(eu32(member->architecture) == kPowerPCCFragArch
|
||||||
|| member->architecture == kAnyCFragArch)
|
|| eu32(member->architecture) == kAnyCFragArch)
|
||||||
{
|
{
|
||||||
if(member->usage == kStubLibraryCFrag
|
if(member->usage == kStubLibraryCFrag
|
||||||
|| member->usage == kImportLibraryCFrag)
|
|| member->usage == kImportLibraryCFrag)
|
||||||
MakeImportLibrary(file + member->offset, member->length,
|
MakeImportLibrary(file + eu32(member->offset), eu32(member->length),
|
||||||
libname, membername);
|
libname, membername);
|
||||||
else if(member->usage == kWeakStubLibraryCFrag)
|
else if(member->usage == kWeakStubLibraryCFrag)
|
||||||
MakeImportLibrary(file + member->offset, member->length,
|
MakeImportLibrary(file + eu32(member->offset), eu32(member->length),
|
||||||
libname, membername + "__weak");
|
libname, membername + "__weak");
|
||||||
else
|
else
|
||||||
std::cerr << "Inappropriate usage flag: "
|
std::cerr << "Inappropriate usage flag: "
|
||||||
@ -201,10 +224,8 @@ void MakeImportLibraryMulti(char *file, const char *path, string libname)
|
|||||||
<< string((char*) &member->architecture,
|
<< string((char*) &member->architecture,
|
||||||
((char*) &member->architecture) + 4) << endl;
|
((char*) &member->architecture) + 4) << endl;
|
||||||
|
|
||||||
member = (CFragResourceMember*) (((char*)member) + member->memberSize);
|
member = (CFragResourceMember*) (((char*)member) + eu16(member->memberSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseResFile(refnum);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main (int argc, char * const argv[])
|
int main (int argc, char * const argv[])
|
||||||
@ -212,7 +233,7 @@ int main (int argc, char * const argv[])
|
|||||||
//printf("%d\n",argc);
|
//printf("%d\n",argc);
|
||||||
if(argc != 3)
|
if(argc != 3)
|
||||||
{
|
{
|
||||||
cerr << "Usage: makeimport <peflib> [<libname>]" << endl;
|
cerr << "Usage: makeimport <peflib> <libname>" << endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,12 +243,12 @@ int main (int argc, char * const argv[])
|
|||||||
perror(argv[1]);
|
perror(argv[1]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
struct stat sb;
|
/*struct stat sb;
|
||||||
fstat(fd, &sb);
|
fstat(fd, &sb);
|
||||||
off_t filesize = sb.st_size;
|
off_t filesize = sb.st_size;
|
||||||
char *p = (char*) mmap(NULL, filesize, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0);
|
char *p = (char*) mmap(NULL, filesize, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0);*/
|
||||||
|
|
||||||
MakeImportLibraryMulti(p,argv[1], argv[2]);
|
MakeImportLibraryMulti(argv[1], argv[2]);
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -219,20 +219,26 @@ void mkpef(std::istream& in, std::ostream& out, std::string mainSymbol = "__star
|
|||||||
for(unsigned i=0; i<xcoffLoaderHeader.l_nsyms; i++)
|
for(unsigned i=0; i<xcoffLoaderHeader.l_nsyms; i++)
|
||||||
{
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
if(syms[i]._l._l_l._l_zeroes == 0)
|
internal_ldsym sym = syms[i];
|
||||||
|
|
||||||
|
eswap(&sym, "........Ls..LL");
|
||||||
|
if(sym._l._l_l._l_zeroes == 0)
|
||||||
|
{
|
||||||
|
eswap(&sym._l._l_l._l_offset,"L");
|
||||||
name = loaderSectionPtr + xcoffLoaderHeader.l_stoff
|
name = loaderSectionPtr + xcoffLoaderHeader.l_stoff
|
||||||
+ syms[i]._l._l_l._l_offset;
|
+ sym._l._l_l._l_offset;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
name = syms[i]._l._l_name;
|
name = sym._l._l_name;
|
||||||
if(verboseFlag)
|
if(verboseFlag)
|
||||||
std::cerr << "Loader Symbol: " << name << std::endl;
|
std::cerr << "Loader Symbol: " << name << std::endl;
|
||||||
|
|
||||||
if((syms[i].l_smtype & 0xF8) == L_IMPORT)
|
if((sym.l_smtype & 0xF8) == L_IMPORT)
|
||||||
{
|
{
|
||||||
assert((syms[i].l_smtype & 3) == XTY_ER);
|
assert((sym.l_smtype & 3) == XTY_ER);
|
||||||
if(verboseFlag)
|
if(verboseFlag)
|
||||||
std::cerr << "from file: " << syms[i].l_ifile << std::endl;
|
std::cerr << "from file: " << sym.l_ifile << std::endl;
|
||||||
importLibs[syms[i].l_ifile].imports.push_back(name);
|
importLibs[sym.l_ifile].imports.push_back(name);
|
||||||
importSources[name] = totalImportedSyms;
|
importSources[name] = totalImportedSyms;
|
||||||
importedSymbolSet.insert(name);
|
importedSymbolSet.insert(name);
|
||||||
totalImportedSyms++;
|
totalImportedSyms++;
|
||||||
@ -437,10 +443,20 @@ void mkpef(std::istream& in, std::ostream& out, std::string mainSymbol = "__star
|
|||||||
name = imp.mem;
|
name = imp.mem;
|
||||||
else
|
else
|
||||||
name = imp.base;
|
name = imp.base;
|
||||||
|
|
||||||
|
|
||||||
|
if(verboseFlag)
|
||||||
|
{
|
||||||
|
std::cerr << "XCOFF name \"" << name << '"';
|
||||||
|
}
|
||||||
int dotIndex = name.rfind('.');
|
int dotIndex = name.rfind('.');
|
||||||
if(dotIndex)
|
if(dotIndex)
|
||||||
|
{
|
||||||
name = name.substr(0,dotIndex);
|
name = name.substr(0,dotIndex);
|
||||||
|
if(name.substr(0,3) == "lib")
|
||||||
|
name = name.substr(3);
|
||||||
|
}
|
||||||
|
|
||||||
if(name.length() > 6)
|
if(name.length() > 6)
|
||||||
{
|
{
|
||||||
if(name.substr(name.length()-6,6) == "__weak")
|
if(name.substr(name.length()-6,6) == "__weak")
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
#define CALLBACK_API(ret,name) ret (*name)
|
#define CALLBACK_API(ret,name) ret (*name)
|
||||||
#define CALLBACK_API_C(ret,name) ret (*name)
|
#define CALLBACK_API_C(ret,name) ret (*name)
|
||||||
#define ONEWORDINLINE(x)
|
#define ONEWORDINLINE(x)
|
||||||
|
#define TWOWORDINLINE(x,y)
|
||||||
|
#define THREEWORDINLINE(x,y,z)
|
||||||
#define FOUR_CHAR_CODE(x) (x)
|
#define FOUR_CHAR_CODE(x) (x)
|
||||||
#define PRAGMA_STRUCT_PACKPUSH 1
|
#define PRAGMA_STRUCT_PACKPUSH 1
|
||||||
|
|
||||||
@ -25,7 +27,15 @@ typedef int16_t SInt16;
|
|||||||
typedef uint32_t UInt32;
|
typedef uint32_t UInt32;
|
||||||
typedef int32_t SInt32;
|
typedef int32_t SInt32;
|
||||||
typedef uint32_t OSType;
|
typedef uint32_t OSType;
|
||||||
|
typedef int16_t OSErr;
|
||||||
|
typedef const unsigned char ConstStr63Param[64];
|
||||||
|
typedef const unsigned char ConstStr255Param[256];
|
||||||
|
typedef unsigned char Str255[256];
|
||||||
|
typedef unsigned char *StringPtr;
|
||||||
|
typedef struct {} FSSpec, *FSSpecPtr;
|
||||||
|
typedef char* Ptr;
|
||||||
|
typedef int16_t Boolean;
|
||||||
|
typedef void *LogicalAddress;
|
||||||
|
|
||||||
/* Definitions for PEF, from Apple's Universal Interfaces */
|
/* Definitions for PEF, from Apple's Universal Interfaces */
|
||||||
#include <PEFBinaryFormat.h>
|
#include <PEFBinaryFormat.h>
|
||||||
@ -43,4 +53,8 @@ typedef uint32_t OSType;
|
|||||||
( (UInt16) ((UInt32)(fullIndex) & 0xFFFF) )
|
( (UInt16) ((UInt32)(fullIndex) & 0xFFFF) )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define __FILES__
|
||||||
|
|
||||||
|
#include <CodeFragments.h>
|
||||||
|
|
||||||
#endif // PEF_H
|
#endif // PEF_H
|
||||||
|
@ -34,8 +34,9 @@ public:
|
|||||||
|
|
||||||
class Resources : public Fork
|
class Resources : public Fork
|
||||||
{
|
{
|
||||||
std::map<ResRef, Resource> resources;
|
|
||||||
public:
|
public:
|
||||||
|
std::map<ResRef, Resource> resources;
|
||||||
|
|
||||||
Resources() {}
|
Resources() {}
|
||||||
Resources(std::istream& in);
|
Resources(std::istream& in);
|
||||||
void writeFork(std::ostream& out) const;
|
void writeFork(std::ostream& out) const;
|
||||||
|
Loading…
Reference in New Issue
Block a user