⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 p_tos.cpp

📁 UPX 源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* p_tos.cpp --   This file is part of the UPX executable compressor.   Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer   Copyright (C) 1996-2007 Laszlo Molnar   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.   Markus F.X.J. Oberhumer              Laszlo Molnar   <mfx@users.sourceforge.net>          <ml1050@users.sourceforge.net> */#include "conf.h"#include "file.h"#include "filter.h"#include "packer.h"#include "p_tos.h"#include "linker.h"static const#include "stub/m68k-atari.tos.h"//#define TESTING 1/*************************************************************************//**************************************************************************/#define FH_SIZE         sizeof(tos_header_t)PackTos::PackTos(InputFile *f) :    super(f){    bele = &N_BELE_RTP::be_policy;    COMPILE_TIME_ASSERT(FH_SIZE == 28);}const int *PackTos::getCompressionMethods(int method, int level) const{    bool small = ih.fh_text + ih.fh_data <= 256*1024;    return Packer::getDefaultCompressionMethods_8(method, level, small);}const int *PackTos::getFilters() const{    return NULL;}Linker* PackTos::newLinker() const{    return new ElfLinkerM68k;}void PackTos::LinkerSymbols::LoopInfo::init(unsigned count_, bool allow_dbra){    count = value = count_;    if (count == 0)        mode = LOOP_NONE;    else if (count <= 65536 && allow_dbra)    {        mode = LOOP_DBRA;        value -= 1;        value &= 0xffff;    }    else if (count <= 65536)    {        mode = LOOP_SUBQ_W;        value &= 0xffff;    }    else        mode = LOOP_SUBQ_L;}unsigned PackTos::getDecomprOffset(int method, int small) const{    UNUSED(small);    if (M_IS_NRV2B(method))        return 2;   // FIXME: do not hardcode this value    else if (M_IS_NRV2D(method))        return 2;   // FIXME: do not hardcode this value    else if (M_IS_NRV2E(method))        return 2;   // FIXME: do not hardcode this value    else if (M_IS_LZMA(method))        return linker->getSectionSize("__mulsi3");    else        throwBadLoader();    return 0;}void PackTos::buildLoader(const Filter *ft){    assert(ft->id == 0);    initLoader(stub_m68k_atari_tos, sizeof(stub_m68k_atari_tos));    //linker->dumpSymbols();    //    // part 1a    //    addLoader("entry");    if (symbols.up21_a6 <= 32767)        addLoader("set_up21_a6.w");    else if (symbols.up21_d4 <= 32767)        addLoader("set_up21_d4.w");    else        addLoader("set_up21_d4.l");    assert(symbols.loop1.count || symbols.loop2.count);    if (symbols.loop1.count)    {        if (symbols.loop1.value <= 127)            addLoader("loop1_set_count.b");        else if (symbols.loop1.value <= 65535)            addLoader("loop1_set_count.w");        else            addLoader("loop1_set_count.l");        addLoader("loop1_label");        addLoader(opt->small ? "loop1.small" : "loop1.fast");        if (symbols.loop1.mode == symbols.LOOP_SUBQ_L)            addLoader("loop1_subql");        else if (symbols.loop1.mode == symbols.LOOP_SUBQ_W)            addLoader("loop1_subqw");        else if (symbols.loop1.mode == symbols.LOOP_DBRA)            addLoader("loop1_dbra");        else            throwBadLoader();    }    if (symbols.loop2.count)    {        assert(symbols.loop2.mode == symbols.LOOP_DBRA);        addLoader(opt->small ? "loop2.small" : "loop2.fast");    }    addLoader("copy_to_stack");    if (M_IS_NRV2B(ph.method))        addLoader("nrv2b.init");    else if (M_IS_NRV2D(ph.method))        addLoader("nrv2d.init");    else if (M_IS_NRV2E(ph.method))        addLoader("nrv2e.init");    else if (M_IS_LZMA(ph.method))        addLoader("lzma.init");    else        throwBadLoader();    symbols.up31_d4 = symbols.up31_base_d4 + getDecomprOffset(ph.method, opt->small);    symbols.up31_a6 = symbols.up31_base_a6 + getDecomprOffset(ph.method, opt->small);    if (symbols.up31_a6 <= 32767)        addLoader("jmp_decompressor_a6.w");    else if (symbols.up31_d4 <= 32767)        addLoader("jmp_decompressor_d4.w");    else if (symbols.up31_a6 <= 65534)        addLoader("jmp_decompressor_a6.w2");    else        addLoader("jmp_decompressor_d4.l");    //    // part 1b    //    addLoader("code_on_stack");    addLoader("clear_dirty_bss");    addLoader("loop3_label");    addLoader(opt->small ? "loop3.small" : "loop3.fast");    if (symbols.loop3.mode == symbols.LOOP_SUBQ_L)        addLoader("loop3_subql");    else if (symbols.loop3.mode == symbols.LOOP_SUBQ_W)        addLoader("loop3_subqw");    else if (symbols.loop3.mode == symbols.LOOP_DBRA)        addLoader("loop3_dbra");    else        throwBadLoader();    addLoader("flush_cache");    addLoader("restore_stack");#if 0    addLoader("clear_dirty_stack");#endif    addLoader("start_program");    addLoader("IDENTSTR,+40D,UPX1HEAD,CUTPOINT");    //    // part 2    //    if (M_IS_NRV2B(ph.method)) {        addLoader(opt->small ? "nrv2b_8.small" : "nrv2b_8.fast");    } else if (M_IS_NRV2D(ph.method)) {        addLoader(opt->small ? "nrv2d_8.small" : "nrv2d_8.fast");    } else if (M_IS_NRV2E(ph.method)) {        addLoader(opt->small ? "nrv2e_8.small" : "nrv2e_8.fast");    } else if (M_IS_LZMA(ph.method)) {        addLoader("__mulsi3");        addLoader(opt->small ? "lzma.small" : "lzma.fast");        addLoader("lzma.finish");    }    else        throwBadLoader();    if (symbols.need_reloc)        addLoader("reloc");    assert(symbols.loop3.count);    if (symbols.loop3.value <= 127)        addLoader("loop3_set_count.b");    else if (symbols.loop3.value <= 65535)        addLoader("loop3_set_count.w");    else        addLoader("loop3_set_count.l");    addLoader("jmp_stack");}/*************************************************************************//**************************************************************************//* flags for curproc->memflags *//* also used for program headers fh_flag */#define F_FASTLOAD      0x01        // don't zero heap#define F_ALTLOAD       0x02        // OK to load in alternate ram#define F_ALTALLOC      0x04        // OK to malloc from alt. ram#define F_SMALLTPA      0x08        // used in MagiC: TPA can be allocated                                    // as specified in the program header                                    // rather than the biggest free memory                                    // block#define F_MEMFLAGS      0xf0        // reserved for future use#define F_SHTEXT        0x800       // program's text may be shared#define F_MINALT        0xf0000000  // used to decide which type of RAM to load in#define F_ALLOCZERO     0x2000      // zero mem, for bugged (GEM...) programs/* Bit in Mxalloc's arg for "don't auto-free this memory" */#define F_KEEP          0x4000#define F_OS_SPECIAL    0x8000      // mark as a special process/* flags for curproc->memflags (that is, fh_flag) and also Mxalloc mode.  *//* (Actually, when users call Mxalloc, they add 0x10 to what you see here) */#define F_PROTMODE      0xf0        // protection mode bits#define F_PROT_P        0x00        // no read or write#define F_PROT_G        0x10        // any access OK#define F_PROT_S        0x20        // any super access OK#define F_PROT_PR       0x30        // any read OK, no write#define F_PROT_I        0x40        // invalid page/*************************************************************************// util//   readFileHeader() reads ih and checks for illegal values//   checkFileHeader() checks ih for legal but unsupported values**************************************************************************/int PackTos::readFileHeader(){    fi->seek(0,SEEK_SET);    fi->readx(&ih, FH_SIZE);    if (ih.fh_magic != 0x601a)        return 0;    if (FH_SIZE + ih.fh_text + ih.fh_data + ih.fh_sym > (unsigned) file_size)        return 0;    return UPX_F_ATARI_TOS;}bool PackTos::checkFileHeader(){    const unsigned f = ih.fh_flag;    //printf("flags: 0x%x, text: %d, data: %d, bss: %d, sym: %d\n", f, (int)ih.fh_text, (int)ih.fh_data, (int)ih.fh_bss, (int)ih.fh_sym);    if ((ih.fh_text & 1) || (ih.fh_data & 1))        throwCantPack("odd size values in text/data");    if (f & F_OS_SPECIAL)        throwCantPack("I won't pack F_OS_SPECIAL programs");    if ((f & F_PROTMODE) > F_PROT_I)        throwCantPack("invalid protection mode");    if ((f & F_PROTMODE) != F_PROT_P)    {        if (opt->force < 1)            throwCantPack("no private memory protection; use option '-f' to force packing");    }    if (f & F_SHTEXT)    {        if (opt->force < 1)            throwCantPack("shared text segment; use option '-f' to force packing");    }#if 0    // fh_reserved seems to be unused    if (ih.fh_reserved != 0)    {        if (opt->force < 1)            throwCantPack("reserved header field set; use option '-f' to force packing");    }#endif    return true;}/*************************************************************************// relocs**************************************************************************/// Check relocation for errors to make sure our loader can handle it.static int check_relocs(const upx_byte *relocs, unsigned rsize, unsigned isize,                        unsigned *nrelocs, unsigned *relocsize, unsigned *overlay){    unsigned fixup = get_be32(relocs);    unsigned last_fixup = fixup;    unsigned i = 4;    assert(isize >= 4);    assert(fixup > 0);    *nrelocs = 1;    for (;;)    {        if (fixup & 1)              // must be word-aligned            return -1;        if (fixup + 4 > isize)      // too far            return -1;        if (i >= rsize)             // premature EOF in relocs            return -1;        unsigned c = relocs[i++];        if (c == 0)                 // end marker            break;        else if (c == 1)            // increase fixup, no reloc            fixup += 254;        else if (c & 1)             // must be word-aligned            return -1;        else                        // next reloc is here        {            fixup += c;            if (fixup - last_fixup < 4)     // overlapping relocation                return -1;            last_fixup = fixup;            *nrelocs += 1;        }    }    *relocsize = i;    *overlay = rsize - i;    return 0;}/*************************************************************************//**************************************************************************/bool PackTos::canPack(){    if (!readFileHeader())        return false;    unsigned char buf[768];    fi->readx(buf, sizeof(buf));    checkAlreadyPacked(buf, sizeof(buf));    if (!checkFileHeader())        throwCantPack("unsupported header flags");    if (file_size < 1024)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -