ppc: PEFTools: closer to working

This commit is contained in:
Wolfgang Thaller 2015-08-31 01:16:54 +02:00
parent 4577098201
commit 59827d52b4
5 changed files with 106 additions and 53 deletions

View File

@ -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)

View File

@ -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 = &sectionHeaders[i]; loaderHeader = &sectionHeaders[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;

View File

@ -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,9 +443,19 @@ 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)
{ {

View File

@ -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

View File

@ -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;