1
0
mirror of https://github.com/upx/upx synced 2025-09-28 19:06:07 +08:00

powerpc-darwin.dylib

This commit is contained in:
John Reiser 2009-05-27 10:19:50 -07:00
parent bde43fbdfb
commit 7ffcc0a5e7
8 changed files with 349 additions and 4 deletions

View File

@ -475,6 +475,7 @@ private:
#define UPX_F_MACH_ARMEL 32 #define UPX_F_MACH_ARMEL 32
#define UPX_F_DYLIB_i386 33 #define UPX_F_DYLIB_i386 33
#define UPX_F_DYLIB_PPC32 34
#define UPX_F_PLAIN_TEXT 127 #define UPX_F_PLAIN_TEXT 127

View File

@ -63,6 +63,9 @@ static const
// The runtime stub for the dyld -init routine does not use "fold"ed code. // The runtime stub for the dyld -init routine does not use "fold"ed code.
//#include "stub/i386-darwin.dylib-fold.h" //#include "stub/i386-darwin.dylib-fold.h"
static const
#include "stub/powerpc-darwin.dylib-entry.h"
template <class T> template <class T>
PackMachBase<T>::PackMachBase(InputFile *f, unsigned cputype, unsigned filetype, PackMachBase<T>::PackMachBase(InputFile *f, unsigned cputype, unsigned filetype,
unsigned flavor, unsigned count, unsigned size) : unsigned flavor, unsigned count, unsigned size) :
@ -87,6 +90,11 @@ PackDylibI386::PackDylibI386(InputFile *f) : super(f)
my_filetype = Mach_header::MH_DYLIB; my_filetype = Mach_header::MH_DYLIB;
} }
PackDylibPPC32::PackDylibPPC32(InputFile *f) : super(f)
{
my_filetype = Mach_header::MH_DYLIB;
}
template <class T> template <class T>
const int *PackMachBase<T>::getCompressionMethods(int method, int level) const const int *PackMachBase<T>::getCompressionMethods(int method, int level) const
{ {
@ -313,6 +321,14 @@ PackDylibI386::buildLoader(const Filter *ft)
0, 0, ft ); 0, 0, ft );
} }
void
PackDylibPPC32::buildLoader(const Filter *ft)
{
buildMachLoader(
stub_powerpc_darwin_dylib_entry, sizeof(stub_powerpc_darwin_dylib_entry),
0, 0, ft );
}
template <class T> template <class T>
void PackMachBase<T>::patchLoader() { } void PackMachBase<T>::patchLoader() { }
@ -430,6 +446,13 @@ void PackMachBase<T>::pack4dylib( // append PackHeader
case Mach_segment_command::LC_REEXPORT_DYLIB: case Mach_segment_command::LC_REEXPORT_DYLIB:
hdrpos += seg->cmdsize; hdrpos += seg->cmdsize;
break; // contain no file offset fields break; // contain no file offset fields
case Mach_segment_command::LC_TWOLEVEL_HINTS: {
Mach_twolevel_hints_command cmd = *(Mach_twolevel_hints_command const *)seg;
if (o_end_txt <= cmd.offset) { cmd.offset += slide; }
fo->seek(hdrpos, SEEK_SET);
fo->rewrite(&cmd, sizeof(cmd));
hdrpos += sizeof(cmd);
} break;
case Mach_segment_command::LC_ROUTINES_64: case Mach_segment_command::LC_ROUTINES_64:
case Mach_segment_command::LC_ROUTINES: { case Mach_segment_command::LC_ROUTINES: {
Mach_routines_command cmd = *(Mach_routines_command const *)seg; Mach_routines_command cmd = *(Mach_routines_command const *)seg;
@ -527,9 +550,14 @@ void PackDylibI386::pack4(OutputFile *fo, Filter &ft) // append PackHeader
pack4dylib(fo, ft, threado.state.eip); pack4dylib(fo, ft, threado.state.eip);
} }
void PackDylibPPC32::pack4(OutputFile *fo, Filter &ft) // append PackHeader
{
pack4dylib(fo, ft, threado.state.srr0);
}
void PackMachPPC32::pack3(OutputFile *fo, Filter &ft) // append loader void PackMachPPC32::pack3(OutputFile *fo, Filter &ft) // append loader
{ {
BE32 disp; TE32 disp;
unsigned const zero = 0; unsigned const zero = 0;
unsigned len = fo->getBytesWritten(); unsigned len = fo->getBytesWritten();
fo->write(&zero, 3& (0u-len)); fo->write(&zero, 3& (0u-len));
@ -543,7 +571,7 @@ void PackMachPPC32::pack3(OutputFile *fo, Filter &ft) // append loader
void PackMachI386::pack3(OutputFile *fo, Filter &ft) // append loader void PackMachI386::pack3(OutputFile *fo, Filter &ft) // append loader
{ {
LE32 disp; TE32 disp;
unsigned const zero = 0; unsigned const zero = 0;
unsigned len = fo->getBytesWritten(); unsigned len = fo->getBytesWritten();
fo->write(&zero, 3& (0u-len)); fo->write(&zero, 3& (0u-len));
@ -557,7 +585,7 @@ void PackMachI386::pack3(OutputFile *fo, Filter &ft) // append loader
void PackMachARMEL::pack3(OutputFile *fo, Filter &ft) // append loader void PackMachARMEL::pack3(OutputFile *fo, Filter &ft) // append loader
{ {
LE32 disp; TE32 disp;
unsigned const zero = 0; unsigned const zero = 0;
unsigned len = fo->getBytesWritten(); unsigned len = fo->getBytesWritten();
fo->write(&zero, 3& (0u-len)); fo->write(&zero, 3& (0u-len));
@ -571,7 +599,30 @@ void PackMachARMEL::pack3(OutputFile *fo, Filter &ft) // append loader
void PackDylibI386::pack3(OutputFile *fo, Filter &ft) // append loader void PackDylibI386::pack3(OutputFile *fo, Filter &ft) // append loader
{ {
LE32 disp; TE32 disp;
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;
unsigned const zero = 0; unsigned const zero = 0;
unsigned len = fo->getBytesWritten(); unsigned len = fo->getBytesWritten();
fo->write(&zero, 3& (0u-len)); fo->write(&zero, 3& (0u-len));

View File

@ -210,6 +210,20 @@ __packed_struct(Mach_routines_command)
#include "p_mach_enum.h" #include "p_mach_enum.h"
__packed_struct_end() __packed_struct_end()
template <class TMachITypes>
__packed_struct(Mach_twolevel_hints_command)
typedef typename TMachITypes::Word Word;
typedef typename TMachITypes::Addr Addr;
typedef typename TMachITypes::Off Off;
Word cmd;
Word cmdsize;
Off offset; /* offset to the hint table */
Word nhints; /* number of hints */
#define WANT_MACH_SEGMENT_ENUM 1
#include "p_mach_enum.h"
__packed_struct_end()
template <class TMachITypes> template <class TMachITypes>
__packed_struct(Mach_ppc_thread_state) __packed_struct(Mach_ppc_thread_state)
typedef typename TMachITypes::Addr Addr; typedef typename TMachITypes::Addr Addr;
@ -340,6 +354,7 @@ struct MachClass_32
typedef N_Mach::Mach_dysymtab_command<MachITypes> Mach_dysymtab_command; typedef N_Mach::Mach_dysymtab_command<MachITypes> Mach_dysymtab_command;
typedef N_Mach::Mach_segsplit_info_command<MachITypes> Mach_segsplit_info_command; typedef N_Mach::Mach_segsplit_info_command<MachITypes> Mach_segsplit_info_command;
typedef N_Mach::Mach_routines_command<MachITypes> Mach_routines_command; typedef N_Mach::Mach_routines_command<MachITypes> Mach_routines_command;
typedef N_Mach::Mach_twolevel_hints_command<MachITypes> Mach_twolevel_hints_command;
typedef N_Mach::Mach_ppc_thread_state<MachITypes> Mach_ppc_thread_state; typedef N_Mach::Mach_ppc_thread_state<MachITypes> Mach_ppc_thread_state;
typedef N_Mach::Mach_i386_thread_state<MachITypes> Mach_i386_thread_state; typedef N_Mach::Mach_i386_thread_state<MachITypes> Mach_i386_thread_state;
typedef N_Mach::Mach_ARM_thread_state<MachITypes> Mach_ARM_thread_state; typedef N_Mach::Mach_ARM_thread_state<MachITypes> Mach_ARM_thread_state;
@ -369,6 +384,7 @@ struct MachClass_64
typedef N_Mach::Mach_dysymtab_command<MachITypes> Mach_dysymtab_command; typedef N_Mach::Mach_dysymtab_command<MachITypes> Mach_dysymtab_command;
typedef N_Mach::Mach_segsplit_info_command<MachITypes> Mach_segsplit_info_command; typedef N_Mach::Mach_segsplit_info_command<MachITypes> Mach_segsplit_info_command;
typedef N_Mach::Mach_routines_command<MachITypes> Mach_routines_command; typedef N_Mach::Mach_routines_command<MachITypes> Mach_routines_command;
typedef N_Mach::Mach_twolevel_hints_command<MachITypes> Mach_twolevel_hints_command;
static void compileTimeAssertions() { static void compileTimeAssertions() {
BeLePolicy::compileTimeAssertions(); BeLePolicy::compileTimeAssertions();
@ -391,6 +407,7 @@ typedef MachClass_Host32::Mach_symtab_command Mach32_symtab_command;
typedef MachClass_Host32::Mach_dysymtab_command Mach32_dysymtab_command; typedef MachClass_Host32::Mach_dysymtab_command Mach32_dysymtab_command;
typedef MachClass_Host32::Mach_segsplit_info_command Mach32_segsplit_info_command; typedef MachClass_Host32::Mach_segsplit_info_command Mach32_segsplit_info_command;
typedef MachClass_Host32::Mach_routines_command Mach32_routines_command; typedef MachClass_Host32::Mach_routines_command Mach32_routines_command;
typedef MachClass_Host32::Mach_twolevel_hints_command Mach32_twolevel_hints_command;
typedef MachClass_Host64::Mach_segment_command Mach64_segment_command; typedef MachClass_Host64::Mach_segment_command Mach64_segment_command;
typedef MachClass_Host64::Mach_section_command Mach64_section_command; typedef MachClass_Host64::Mach_section_command Mach64_section_command;
@ -398,6 +415,7 @@ typedef MachClass_Host64::Mach_symtab_command Mach64_symtab_command;
typedef MachClass_Host64::Mach_dysymtab_command Mach64_dysymtab_command; typedef MachClass_Host64::Mach_dysymtab_command Mach64_dysymtab_command;
typedef MachClass_Host64::Mach_segsplit_info_command Mach64_segsplit_info_command; typedef MachClass_Host64::Mach_segsplit_info_command Mach64_segsplit_info_command;
typedef MachClass_Host64::Mach_routines_command Mach64_routines_command; typedef MachClass_Host64::Mach_routines_command Mach64_routines_command;
typedef MachClass_Host64::Mach_twolevel_hints_command Mach64_twolevel_hints_command;
typedef MachClass_BE32::Mach_segment_command MachBE32_segment_command; typedef MachClass_BE32::Mach_segment_command MachBE32_segment_command;
typedef MachClass_BE32::Mach_section_command MachBE32_section_command; typedef MachClass_BE32::Mach_section_command MachBE32_section_command;
@ -405,6 +423,7 @@ typedef MachClass_BE32::Mach_symtab_command MachBE32_symtab_command;
typedef MachClass_BE32::Mach_dysymtab_command MachBE32_dysymtab_command; typedef MachClass_BE32::Mach_dysymtab_command MachBE32_dysymtab_command;
typedef MachClass_BE32::Mach_segsplit_info_command MachBE32_segsplit_info_command; typedef MachClass_BE32::Mach_segsplit_info_command MachBE32_segsplit_info_command;
typedef MachClass_BE32::Mach_routines_command MachBE32_routines_command; typedef MachClass_BE32::Mach_routines_command MachBE32_routines_command;
typedef MachClass_BE32::Mach_twolevel_hints_command MachBE32_twolevel_hints_command;
typedef MachClass_BE64::Mach_segment_command MachBE64_segment_command; typedef MachClass_BE64::Mach_segment_command MachBE64_segment_command;
typedef MachClass_BE64::Mach_section_command MachBE64_section_command; typedef MachClass_BE64::Mach_section_command MachBE64_section_command;
@ -412,6 +431,7 @@ typedef MachClass_BE64::Mach_symtab_command MachBE64_symtab_command;
typedef MachClass_BE64::Mach_dysymtab_command MachBE64_dysymtab_command; typedef MachClass_BE64::Mach_dysymtab_command MachBE64_dysymtab_command;
typedef MachClass_BE64::Mach_segsplit_info_command MachBE64_segsplit_info_command; typedef MachClass_BE64::Mach_segsplit_info_command MachBE64_segsplit_info_command;
typedef MachClass_BE64::Mach_routines_command MachBE64_routines_command; typedef MachClass_BE64::Mach_routines_command MachBE64_routines_command;
typedef MachClass_BE64::Mach_twolevel_hints_command MachBE64_twolevel_hints_command;
typedef MachClass_LE32::Mach_segment_command MachLE32_segment_command; typedef MachClass_LE32::Mach_segment_command MachLE32_segment_command;
typedef MachClass_LE32::Mach_section_command MachLE32_section_command; typedef MachClass_LE32::Mach_section_command MachLE32_section_command;
@ -419,6 +439,7 @@ typedef MachClass_LE32::Mach_symtab_command MachLE32_symtab_command;
typedef MachClass_LE32::Mach_dysymtab_command MachLE32_dysymtab_command; typedef MachClass_LE32::Mach_dysymtab_command MachLE32_dysymtab_command;
typedef MachClass_LE32::Mach_segsplit_info_command MachLE32_segsplit_info_command; typedef MachClass_LE32::Mach_segsplit_info_command MachLE32_segsplit_info_command;
typedef MachClass_LE32::Mach_routines_command MachLE32_routines_command; typedef MachClass_LE32::Mach_routines_command MachLE32_routines_command;
typedef MachClass_LE32::Mach_twolevel_hints_command MachLE32_twolevel_hints_command;
typedef MachClass_LE64::Mach_segment_command MachLE64_segment_command; typedef MachClass_LE64::Mach_segment_command MachLE64_segment_command;
typedef MachClass_LE64::Mach_section_command MachLE64_section_command; typedef MachClass_LE64::Mach_section_command MachLE64_section_command;
@ -426,6 +447,7 @@ typedef MachClass_LE64::Mach_symtab_command MachLE64_symtab_command;
typedef MachClass_LE64::Mach_dysymtab_command MachLE64_dysymtab_command; typedef MachClass_LE64::Mach_dysymtab_command MachLE64_dysymtab_command;
typedef MachClass_LE64::Mach_segsplit_info_command MachLE64_segsplit_info_command; typedef MachClass_LE64::Mach_segsplit_info_command MachLE64_segsplit_info_command;
typedef MachClass_LE64::Mach_routines_command MachLE64_routines_command; typedef MachClass_LE64::Mach_routines_command MachLE64_routines_command;
typedef MachClass_LE64::Mach_twolevel_hints_command MachLE64_twolevel_hints_command;
typedef MachClass_BE32::Mach_ppc_thread_state Mach_ppc_thread_state; typedef MachClass_BE32::Mach_ppc_thread_state Mach_ppc_thread_state;
typedef MachClass_LE32::Mach_i386_thread_state Mach_i386_thread_state; typedef MachClass_LE32::Mach_i386_thread_state Mach_i386_thread_state;
@ -454,6 +476,7 @@ protected:
typedef typename MachClass::Mach_dysymtab_command Mach_dysymtab_command; typedef typename MachClass::Mach_dysymtab_command Mach_dysymtab_command;
typedef typename MachClass::Mach_segsplit_info_command Mach_segsplit_info_command; typedef typename MachClass::Mach_segsplit_info_command Mach_segsplit_info_command;
typedef typename MachClass::Mach_routines_command Mach_routines_command; typedef typename MachClass::Mach_routines_command Mach_routines_command;
typedef typename MachClass::Mach_twolevel_hints_command Mach_twolevel_hints_command;
public: public:
PackMachBase(InputFile *, unsigned cpuid, unsigned filetype, PackMachBase(InputFile *, unsigned cpuid, unsigned filetype,
@ -581,6 +604,22 @@ protected:
Mach_thread_command threado; Mach_thread_command threado;
}; };
class PackDylibPPC32 : public PackMachPPC32
{
typedef PackMachPPC32 super;
public:
PackDylibPPC32(InputFile *f);
virtual int getFormat() const { return UPX_F_DYLIB_PPC32; }
virtual const char *getName() const { return "Dylib/ppc32"; }
virtual const char *getFullName(const options_t *) const { return "powerpc-darwin.dylib"; }
protected:
virtual void pack3(OutputFile *, Filter &); // append loader
virtual void pack4(OutputFile *, Filter &); // append PackHeader
virtual void buildLoader(const Filter *ft);
};
class PackMachI386 : public PackMachBase<MachClass_LE32> class PackMachI386 : public PackMachBase<MachClass_LE32>
{ {
typedef PackMachBase<MachClass_LE32> super; typedef PackMachBase<MachClass_LE32> super;

View File

@ -70,6 +70,7 @@
LC_ID_DYLIB = 0xd, LC_ID_DYLIB = 0xd,
LC_LOAD_DYLINKER = 0xe, LC_LOAD_DYLINKER = 0xe,
LC_ROUTINES = 0x11, LC_ROUTINES = 0x11,
LC_TWOLEVEL_HINTS= 0x16,
LC_SEGMENT_64 = 0x19, LC_SEGMENT_64 = 0x19,
LC_ROUTINES_64 = 0x1a, LC_ROUTINES_64 = 0x1a,
LC_UUID = 0x1b, LC_UUID = 0x1b,

View File

@ -281,6 +281,8 @@ Packer* PackMaster::visitAllPackers(visit_func_t func, InputFile *f, const optio
return p; return p;
if ((p = func(new PackDylibI386(f), user)) != NULL) if ((p = func(new PackDylibI386(f), user)) != NULL)
return p; return p;
if ((p = func(new PackDylibPPC32(f), user)) != NULL)
return p;
return NULL; return NULL;
} }

View File

@ -102,6 +102,7 @@ STUBS += mips.r3000-linux.elf-fold.h
STUBS += mipsel.r3000-linux.elf-entry.h STUBS += mipsel.r3000-linux.elf-entry.h
STUBS += mipsel.r3000-linux.elf-fold.h STUBS += mipsel.r3000-linux.elf-fold.h
STUBS += mipsel.r3000-ps1.h STUBS += mipsel.r3000-ps1.h
STUBS += powerpc-darwin.dylib-entry.h
STUBS += powerpc-darwin.macho-entry.h STUBS += powerpc-darwin.macho-entry.h
STUBS += powerpc-darwin.macho-fold.h STUBS += powerpc-darwin.macho-fold.h
STUBS += powerpc-linux.elf-entry.h STUBS += powerpc-linux.elf-entry.h
@ -1050,6 +1051,19 @@ tmp/powerpc-darwin.macho-main.o : $(srcdir)/src/$$T.c
$(call tc,objdump) -dr $(tc_objdump_disasm_options) $@ | $(RTRIM) > $@.disasm $(call tc,objdump) -dr $(tc_objdump_disasm_options) $@ | $(RTRIM) > $@.disasm
# /***********************************************************************
# // powerpc-darwin.dylib
# ************************************************************************/
# info: we use the tc settings from powerpc-linux.elf
powerpc-darwin.dylib%.h : tc_list = powerpc-linux.elf default
powerpc-darwin.dylib%.h : tc_bfdname = elf32-powerpc
powerpc-darwin.dylib-entry.h : $(srcdir)/src/$$T.S
$(call tc,gcc) -c $< -o tmp/$T.bin
$(call tc,f-embed_objinfo,tmp/$T.bin)
$(call tc,bin2h) tmp/$T.bin $@
# /*********************************************************************** # /***********************************************************************
# // powerpc-linux.elf # // powerpc-linux.elf
# ************************************************************************/ # ************************************************************************/

View File

@ -0,0 +1,185 @@
/*
* powerpc-darwin.dylib-entry.S -- program entry point & decompressor (PowerPC32 dylib)
*
* This file is part of the UPX executable compressor.
*
* Copyright (C) 2005-2009 John F. Reiser
* All Rights Reserved.
*
* UPX and the UCL library are free software; you can redistribute them
* and/or modify them under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING.
* If not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* John F. Reiser
* <jreiser@users.sourceforge.net>
*
*/
#include "arch/powerpc/32/macros.S"
#include "arch/powerpc/32/ppc_regs.h"
/*************************************************************************
// We have been CALLed as a subroutine from dyld; C-language rules apply.
// -4*4+_start: .long offset(user_init_function)
// -3*4+_start: .long offset(b_info of compressed Mach_headers)
// -2*4+_start: .long length(compressed __TEXT)
// -1*4+_start: .long 8+ total_length # 8+ number of preceding bytes in file
**************************************************************************/
section MACOS000
_start: .globl _start
mflr r2
call main # must be exactly 1 instruction; link_register= &decompress
decompressor:
section NRV_HEAD
SZ_DLINE=128 # size of data cache line in Apple G5
/* PowerPC has no 'cmplis': compare logical [unsigned] immediate shifted [by 16] */
#define hibit r0 /* holds 0x80000000 during decompress */
#define src a0
#define lsrc a1
#define dst a2
#define ldst a3 /* Out: actually a reference: &len_dst */
#define meth a4
#define off a4
#define len a5
#define bits a6
#define disp a7
section NRV2E
#include "arch/powerpc/32/nrv2e_d.S"
section NRV2D
#include "arch/powerpc/32/nrv2d_d.S"
section NRV2B
#include "arch/powerpc/32/nrv2b_d.S"
#include "arch/powerpc/32/lzma_d.S"
section NRV_TAIL
eof_nrv:
#define dst0 a4
#define tmp a1
lwz dst0,0(ldst) // original dst
mtlr t3 // return address
subf a0,lsrc,src
subf tmp,dst0,dst // -1+ dst length
addi a0,a0,1 // return 0: good; else: bad [+1: correct for lbzu]
addi tmp,tmp,1 // dst length
stw tmp,0(ldst)
#undef tmp
// CACHELINE=32 is the observed minimum line size of any cache.
// Some caches may have larger lines, but it is cumbersome to lookup
// {AT_DCACHEBSIZE, AT_ICACHEBSIZE, AT_UCACHEBSIZE: /usr/include/elf.h},
// then save the correct size in a variable {where to put it?}, or to modify
// the two instructions here. If a cache has larger lines, then we expect
// that the second dcbst (or icbi) on a the same line will be fast.
// If not, then too bad.
section CFLUSH // In: a2=dst= &highest stored byte; a4=dst0= &lowest stored byte
CACHELINE=32
ori dst0,dst0,-1+ CACHELINE // highest addr on cache line
cfl_nrv:
dcbst 0,dst0 // initiate store (modified) cacheline to memory
cmpl cr0,dst0,dst // did we cover the highest-addressed byte?
icbi 0,dst0 // discard instructions from cacheline
addi dst0,dst0,CACHELINE // highest addr on next line
blt cr0,cfl_nrv // not done yet
#undef dst0
sync // wait for all memory operations to finish
isync // discard prefetched instructions (if any)
cfl_ret:
ret
section ELFMAINY
// IDENTSTR goes here
section ELFMAINZ
sz_b_info= 12
sz_unc= 0
sz_cpr= 4
b_method= 8
PROT_NONE =0x00
PROT_READ =0x01
PROT_WRITE =0x02
PROT_EXEC =0x04
MAP_SHARED =0x1
MAP_PRIVATE =0x2
MAP_ANON =0x1000
SYS_mmap =197
SYS_mprotect= 74
main2:
teq r0,r0 // debugging
stwu r2,-4*(1+ 32-a0)(sp) # retaddr
stmw a0,4*1(sp)
mflr r31 # r31= &decompressor
lwz r29, -4*1(r31) # "call main" at _start
lwz r30,-4*1+ _start - decompressor(r31) # 4+ offset(_start)
rlwinm r29,r29,0,6,29 # 4+ main - decompressor
add r30,r30,r29 # offset(main); ASSUMES (8+_start)==decompressor
addi r29,r29,-4 # main - decompressor
li a0,0 # addr
mr a1,r30 # length
li a2,PROT_READ|PROT_WRITE
li a3,MAP_ANON|MAP_PRIVATE
li a4,-1
li a5,0 # hi32(offset)
li a6,0 # lo32(offset)
li 0,SYS_mmap
sc
li a0,-1 # failure
teq r0,r0 // debugging
li a2,main - movup2
mtctr a2
add a1,a0 ,r30 # lwa(dst); new_page + offset(main)
add a0,r29,r31 # lwa(src); &main
movup1: # descending copy [moveup2, main)
lbzu r0,-1(a0)
stbu r0,-1(a1)
bdnz+ movup1
subf a2,a2,r30 # offset(movup2)
mtlr a1 # &copied movup2
mtctr a2 # offset(movup2)
blr # goto the copied code
movup2: # descending copy [base, movup2)
lbzu r0,-1(a0)
stbu r0,-1(a1)
bdnz+ movup2
subf r31,a0,r31
add r31,a1,r31 # relocated decompressor
teq r0,r0
main:
b main2
dy_top:
len_top = dy_top - main
/*
vi:ts=8:et:nowrap
*/

View File

@ -0,0 +1,52 @@
file format elf32-powerpc
Sections:
Idx Name Size VMA LMA File off Algn Flags
0 MACOS000 00000008 00000000 00000000 00000034 2**0 CONTENTS, RELOC, READONLY
1 NRV_HEAD 00000000 00000000 00000000 0000003c 2**0 CONTENTS, READONLY
2 NRV2E 00000148 00000000 00000000 0000003c 2**0 CONTENTS, RELOC, READONLY
3 NRV2D 0000012c 00000000 00000000 00000184 2**0 CONTENTS, RELOC, READONLY
4 NRV2B 000000f0 00000000 00000000 000002b0 2**0 CONTENTS, RELOC, READONLY
5 LZMA_ELF00 0000008c 00000000 00000000 000003a0 2**0 CONTENTS, RELOC, READONLY
6 LZMA_DEC10 0000099c 00000000 00000000 0000042c 2**0 CONTENTS, READONLY
7 LZMA_DEC20 0000099c 00000000 00000000 00000dc8 2**0 CONTENTS, READONLY
8 LZMA_DEC30 00000020 00000000 00000000 00001764 2**0 CONTENTS, READONLY
9 NRV_TAIL 0000001c 00000000 00000000 00001784 2**0 CONTENTS, READONLY
10 CFLUSH 00000024 00000000 00000000 000017a0 2**0 CONTENTS, READONLY
11 ELFMAINY 00000000 00000000 00000000 000017c4 2**0 CONTENTS, READONLY
12 ELFMAINZ 00000098 00000000 00000000 000017c4 2**0 CONTENTS, READONLY
SYMBOL TABLE:
00000000 l d LZMA_DEC30 00000000 LZMA_DEC30
00000000 l d NRV_TAIL 00000000 NRV_TAIL
00000000 l d ELFMAINZ 00000000 ELFMAINZ
00000000 l d MACOS000 00000000 MACOS000
00000000 l d NRV_HEAD 00000000 NRV_HEAD
00000000 l d NRV2E 00000000 NRV2E
00000000 l d NRV2D 00000000 NRV2D
00000000 l d NRV2B 00000000 NRV2B
00000000 l d LZMA_ELF00 00000000 LZMA_ELF00
00000000 l d LZMA_DEC10 00000000 LZMA_DEC10
00000000 l d LZMA_DEC20 00000000 LZMA_DEC20
00000000 l d CFLUSH 00000000 CFLUSH
00000000 l d ELFMAINY 00000000 ELFMAINY
00000000 g MACOS000 00000000 _start
RELOCATION RECORDS FOR [MACOS000]:
OFFSET TYPE VALUE
00000004 R_PPC_REL24 ELFMAINZ+0x00000094
RELOCATION RECORDS FOR [NRV2E]:
OFFSET TYPE VALUE
000000b4 R_PPC_REL14 NRV_TAIL
RELOCATION RECORDS FOR [NRV2D]:
OFFSET TYPE VALUE
000000b4 R_PPC_REL14 NRV_TAIL
RELOCATION RECORDS FOR [NRV2B]:
OFFSET TYPE VALUE
00000090 R_PPC_REL14 NRV_TAIL
RELOCATION RECORDS FOR [LZMA_ELF00]:
OFFSET TYPE VALUE
00000004 R_PPC_REL14 LZMA_DEC30+0x00000020