PackDylibAMD64 (Mac OS X shared library on x86_64)
This commit is contained in:
+62
-12
@@ -70,6 +70,8 @@ static const
|
||||
|
||||
static const
|
||||
#include "stub/powerpc-darwin.dylib-entry.h"
|
||||
static const
|
||||
#include "stub/amd64-darwin.dylib-entry.h"
|
||||
|
||||
static const unsigned lc_segment[2] = {
|
||||
0x1, 0x19
|
||||
@@ -77,6 +79,12 @@ static const unsigned lc_segment[2] = {
|
||||
//Mach_segment_command::LC_SEGMENT_64
|
||||
};
|
||||
|
||||
static const unsigned lc_routines[2] = {
|
||||
0x11, 0x1a
|
||||
//Mach_segment_command::LC_ROUTINES,
|
||||
//Mach_segment_command::LC_ROUTINES_64
|
||||
};
|
||||
|
||||
template <class T>
|
||||
PackMachBase<T>::PackMachBase(InputFile *f, unsigned cputype, unsigned filetype,
|
||||
unsigned flavor, unsigned count, unsigned size) :
|
||||
@@ -101,6 +109,11 @@ PackDylibI386::PackDylibI386(InputFile *f) : super(f)
|
||||
my_filetype = Mach_header::MH_DYLIB;
|
||||
}
|
||||
|
||||
PackDylibAMD64::PackDylibAMD64(InputFile *f) : super(f)
|
||||
{
|
||||
my_filetype = Mach_header::MH_DYLIB;
|
||||
}
|
||||
|
||||
PackDylibPPC32::PackDylibPPC32(InputFile *f) : super(f)
|
||||
{
|
||||
my_filetype = Mach_header::MH_DYLIB;
|
||||
@@ -386,6 +399,14 @@ PackDylibI386::buildLoader(const Filter *ft)
|
||||
0, 0, ft );
|
||||
}
|
||||
|
||||
void
|
||||
PackDylibAMD64::buildLoader(const Filter *ft)
|
||||
{
|
||||
buildMachLoader(
|
||||
stub_amd64_darwin_dylib_entry, sizeof(stub_amd64_darwin_dylib_entry),
|
||||
0, 0, ft );
|
||||
}
|
||||
|
||||
void
|
||||
PackDylibPPC32::buildLoader(const Filter *ft)
|
||||
{
|
||||
@@ -635,6 +656,11 @@ void PackDylibI386::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
||||
pack4dylib(fo, ft, threado.state.eip);
|
||||
}
|
||||
|
||||
void PackDylibAMD64::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
||||
{
|
||||
pack4dylib(fo, ft, threado.state.rip);
|
||||
}
|
||||
|
||||
void PackDylibPPC32::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
||||
{
|
||||
pack4dylib(fo, ft, threado.state.srr0);
|
||||
@@ -719,6 +745,29 @@ void PackDylibI386::pack3(OutputFile *fo, Filter &ft) // append loader
|
||||
sz_mach_headers = save_sz_mach_headers;
|
||||
}
|
||||
|
||||
void PackDylibAMD64::pack3(OutputFile *fo, Filter &ft) // append loader
|
||||
{
|
||||
TE32 disp; // FIXME: 64-bit ???
|
||||
unsigned const zero = 0;
|
||||
unsigned len = fo->getBytesWritten();
|
||||
fo->write(&zero, 3& (0u-len));
|
||||
len += (3& (0u-len)) + 4*sizeof(disp);
|
||||
|
||||
disp = prev_init_address;
|
||||
fo->write(&disp, sizeof(disp)); // user .init_address
|
||||
|
||||
disp = sizeof(mhdro) + mhdro.sizeofcmds + sizeof(l_info) + sizeof(p_info);
|
||||
fo->write(&disp, sizeof(disp)); // src offset(compressed __TEXT)
|
||||
|
||||
disp = len - disp - 3*sizeof(disp);
|
||||
fo->write(&disp, sizeof(disp)); // length(compressed __TEXT)
|
||||
|
||||
unsigned const save_sz_mach_headers(sz_mach_headers);
|
||||
sz_mach_headers = 0;
|
||||
super::pack3(fo, ft);
|
||||
sz_mach_headers = save_sz_mach_headers;
|
||||
}
|
||||
|
||||
void PackDylibPPC32::pack3(OutputFile *fo, Filter &ft) // append loader
|
||||
{
|
||||
TE32 disp;
|
||||
@@ -1069,6 +1118,7 @@ template <class T>
|
||||
bool PackMachBase<T>::canPack()
|
||||
{
|
||||
unsigned const lc_seg = lc_segment[sizeof(Addr)>>3];
|
||||
unsigned const lc_rout = lc_routines[sizeof(Addr)>>3];
|
||||
fi->seek(0, SEEK_SET);
|
||||
fi->readx(&mhdri, sizeof(mhdri));
|
||||
|
||||
@@ -1086,10 +1136,10 @@ bool PackMachBase<T>::canPack()
|
||||
unsigned char const *ptr = (unsigned char const *)rawmseg;
|
||||
for (unsigned j= 0; j < ncmds; ++j) {
|
||||
msegcmd[j] = *(Mach_segment_command const *)ptr;
|
||||
if (((Mach_segment_command const *)ptr)->cmd ==
|
||||
Mach_segment_command::LC_ROUTINES) {
|
||||
if (((Mach_segment_command const *)ptr)->cmd == lc_rout) {
|
||||
o_routines_cmd = (const char *)ptr - (const char *)rawmseg;
|
||||
prev_init_address = ((Mach_routines_command const *)ptr)->init_address;
|
||||
prev_init_address =
|
||||
((Mach_routines_command const *)ptr)->init_address;
|
||||
}
|
||||
ptr += (unsigned) ((const Mach_segment_command *)ptr)->cmdsize;
|
||||
}
|
||||
@@ -1202,13 +1252,13 @@ void PackMachFat::pack(OutputFile *fo)
|
||||
packer.updatePackHeader();
|
||||
packer.pack(fo);
|
||||
}
|
||||
//else if (hdr.filetype==Mach_header::MH_DYLIB) {
|
||||
// PackDylibAMD64 packer(fi);
|
||||
// packer.initPackHeader();
|
||||
// packer.canPack();
|
||||
// packer.updatePackHeader();
|
||||
// packer.pack(fo);
|
||||
//}
|
||||
else if (hdr.filetype==Mach_header::MH_DYLIB) {
|
||||
PackDylibAMD64 packer(fi);
|
||||
packer.initPackHeader();
|
||||
packer.canPack();
|
||||
packer.updatePackHeader();
|
||||
packer.pack(fo);
|
||||
}
|
||||
} break;
|
||||
case PackMachFat::CPU_TYPE_POWERPC: {
|
||||
typedef N_Mach::Mach_header<MachClass_BE32::MachITypes> Mach_header;
|
||||
@@ -1333,8 +1383,8 @@ bool PackMachFat::canPack()
|
||||
case PackMachFat::CPU_TYPE_X86_64: {
|
||||
PackMachAMD64 packer(fi);
|
||||
if (!packer.canPack()) {
|
||||
//PackDylibI386 pack2r(fi);
|
||||
//if (!pack2r.canPack())
|
||||
PackDylibI386 pack2r(fi);
|
||||
if (!pack2r.canPack())
|
||||
return false;
|
||||
}
|
||||
} break;
|
||||
|
||||
Reference in New Issue
Block a user