src: introduce type tribool
This commit is contained in:
parent
10e759f1f1
commit
a9ac4b5e23
@ -863,11 +863,11 @@ int upx_test_overlap ( const upx_bytep buf,
|
||||
|
||||
|
||||
#include "util/snprintf.h" // must get included first!
|
||||
#include "util/util.h"
|
||||
#include "options.h"
|
||||
#include "except.h"
|
||||
#include "bele.h"
|
||||
#include "console/console.h"
|
||||
#include "util/util.h"
|
||||
// xspan
|
||||
#include "util/raw_bytes.h"
|
||||
#include "util/xspan.h"
|
||||
|
||||
@ -109,7 +109,7 @@ struct PackerNames {
|
||||
names[names_count].sname = pb->getName();
|
||||
names_count++;
|
||||
}
|
||||
static bool visit(PackerBase *pb, void *user) {
|
||||
static tribool visit(PackerBase *pb, void *user) {
|
||||
PackerNames *self = (PackerNames *) user;
|
||||
self->add(pb);
|
||||
return false;
|
||||
|
||||
@ -679,8 +679,11 @@ static int do_option(int optc, const char *arg) {
|
||||
break;
|
||||
case 632:
|
||||
opt->win32_pe.compress_resources = 1;
|
||||
if (mfx_optarg && mfx_optarg[0])
|
||||
getoptvar(&opt->win32_pe.compress_resources, 0, 1, arg);
|
||||
if (mfx_optarg && mfx_optarg[0]) {
|
||||
int value;
|
||||
getoptvar(&value, 0, 1, arg);
|
||||
opt->win32_pe.compress_resources = bool(value);
|
||||
}
|
||||
// printf("compress_resources: %d\n", opt->win32_pe.compress_resources);
|
||||
break;
|
||||
case 633:
|
||||
|
||||
@ -163,8 +163,8 @@ struct Options final {
|
||||
struct {
|
||||
int compress_exports;
|
||||
int compress_icons;
|
||||
int compress_resources;
|
||||
signed char compress_rt[25]; // 25 == RT_LAST
|
||||
TriBool<upx_int8_t> compress_resources;
|
||||
TriBool<upx_int8_t> compress_rt[25]; // 25 == RT_LAST
|
||||
int strip_relocs;
|
||||
const char *keep_resource;
|
||||
} win32_pe;
|
||||
|
||||
@ -58,7 +58,7 @@ const int *PackCom::getFilters() const {
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
bool PackCom::canPack() {
|
||||
tribool PackCom::canPack() {
|
||||
byte buf[128];
|
||||
|
||||
fi->readx(buf, sizeof(buf));
|
||||
@ -197,7 +197,7 @@ void PackCom::pack(OutputFile *fo) {
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int PackCom::canUnpack() {
|
||||
tribool PackCom::canUnpack() {
|
||||
if (!readPackHeader(128)) // read "ph"
|
||||
return false;
|
||||
if (file_size_u <= ph.c_len)
|
||||
|
||||
@ -46,8 +46,8 @@ public:
|
||||
virtual void pack(OutputFile *fo) override;
|
||||
virtual void unpack(OutputFile *fo) override;
|
||||
|
||||
virtual bool canPack() override;
|
||||
virtual int canUnpack() override;
|
||||
virtual tribool canPack() override;
|
||||
virtual tribool canUnpack() override;
|
||||
|
||||
protected:
|
||||
virtual Linker *newLinker() const override;
|
||||
|
||||
@ -197,7 +197,7 @@ void PackDjgpp2::stripDebug() {
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
bool PackDjgpp2::canPack() {
|
||||
tribool PackDjgpp2::canPack() {
|
||||
if (!readFileHeader())
|
||||
return false;
|
||||
if (is_dlm(fi, coff_offset))
|
||||
@ -346,7 +346,7 @@ void PackDjgpp2::pack(OutputFile *fo) {
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int PackDjgpp2::canUnpack() {
|
||||
tribool PackDjgpp2::canUnpack() {
|
||||
if (!readFileHeader())
|
||||
return false;
|
||||
if (is_dlm(fi, coff_offset))
|
||||
|
||||
@ -50,8 +50,8 @@ public:
|
||||
virtual void pack(OutputFile *fo) override;
|
||||
virtual void unpack(OutputFile *fo) override;
|
||||
|
||||
virtual bool canPack() override;
|
||||
virtual int canUnpack() override;
|
||||
virtual tribool canPack() override;
|
||||
virtual tribool canUnpack() override;
|
||||
|
||||
protected:
|
||||
void handleStub(OutputFile *fo);
|
||||
|
||||
@ -229,7 +229,7 @@ int PackExe::readFileHeader() {
|
||||
return UPX_F_DOS_EXE;
|
||||
}
|
||||
|
||||
bool PackExe::canPack() {
|
||||
tribool PackExe::canPack() {
|
||||
if (fn_has_ext(fi->getName(), "sys")) // dos/sys
|
||||
return false;
|
||||
if (!readFileHeader())
|
||||
@ -572,7 +572,7 @@ void PackExe::pack(OutputFile *fo) {
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int PackExe::canUnpack() {
|
||||
tribool PackExe::canUnpack() {
|
||||
if (!readFileHeader())
|
||||
return false;
|
||||
const unsigned off = ih.headsize16 * 16;
|
||||
|
||||
@ -46,8 +46,8 @@ public:
|
||||
virtual void pack(OutputFile *fo) override;
|
||||
virtual void unpack(OutputFile *fo) override;
|
||||
|
||||
virtual bool canPack() override;
|
||||
virtual int canUnpack() override;
|
||||
virtual tribool canPack() override;
|
||||
virtual tribool canUnpack() override;
|
||||
|
||||
// unpacker capabilities
|
||||
virtual bool canUnpackVersion(int version) const override {
|
||||
|
||||
@ -2411,7 +2411,7 @@ bool PackLinuxElf32::calls_crt1(Elf32_Rel const *rel, int sz)
|
||||
return false;
|
||||
}
|
||||
|
||||
int PackLinuxElf32::canUnpack() // bool, except -1: format known, but not packed
|
||||
tribool PackLinuxElf32::canUnpack() // bool, except -1: format known, but not packed
|
||||
{
|
||||
if (checkEhdr(&ehdri)) {
|
||||
return false;
|
||||
@ -2506,7 +2506,7 @@ PackLinuxElf32::canPackOSABI(Elf32_Ehdr const *ehdr)
|
||||
return true; // good so far
|
||||
}
|
||||
|
||||
bool PackLinuxElf32::canPack()
|
||||
tribool PackLinuxElf32::canPack()
|
||||
{
|
||||
union {
|
||||
unsigned char buf[MAX_ELF_HDR_32];
|
||||
@ -2589,7 +2589,7 @@ bool PackLinuxElf32::canPack()
|
||||
max_offset = UPX_MAX(max_offset, get_te32(&phdr->p_filesz) + get_te32(&phdr->p_offset));
|
||||
}
|
||||
}
|
||||
if (canUnpack() > 0) {
|
||||
if (canUnpack()) {
|
||||
throwAlreadyPacked();
|
||||
}
|
||||
// We want to compress position-independent executable (gcc -pie)
|
||||
@ -2952,7 +2952,7 @@ proceed: ;
|
||||
return true;
|
||||
}
|
||||
|
||||
int PackLinuxElf64::canUnpack() // bool, except -1: format known, but not packed
|
||||
tribool PackLinuxElf64::canUnpack() // bool, except -1: format known, but not packed
|
||||
{
|
||||
if (checkEhdr(&ehdri)) {
|
||||
return false;
|
||||
@ -2966,7 +2966,7 @@ int PackLinuxElf64::canUnpack() // bool, except -1: format known, but not packed
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
tribool
|
||||
PackLinuxElf64::canPack()
|
||||
{
|
||||
union {
|
||||
@ -3024,7 +3024,7 @@ PackLinuxElf64::canPack()
|
||||
max_offset = UPX_MAX(max_offset, get_te64(&phdr->p_filesz) + get_te64(&phdr->p_offset));
|
||||
}
|
||||
}
|
||||
if (canUnpack() > 0) {
|
||||
if (canUnpack()) {
|
||||
throwAlreadyPacked();
|
||||
}
|
||||
// We want to compress position-independent executable (gcc -pie)
|
||||
@ -7407,7 +7407,7 @@ PackLinuxElf32x86::~PackLinuxElf32x86()
|
||||
{
|
||||
}
|
||||
|
||||
int PackLinuxElf32x86::canUnpack() // bool, except -1: format known, but not packed
|
||||
tribool PackLinuxElf32x86::canUnpack() // bool, except -1: format known, but not packed
|
||||
{
|
||||
if (super::canUnpack()) {
|
||||
return true;
|
||||
|
||||
@ -46,7 +46,7 @@ public:
|
||||
/*virtual void buildLoader(const Filter *);*/
|
||||
virtual int getVersion() const override { return 14; } // upx-3.96 cannot upack, for instance
|
||||
virtual bool canUnpackVersion(int version) const override { return (version >= 11); }
|
||||
virtual int canUnpack() override { return super::canUnpack(); } // bool, except -1: format known, but not packed
|
||||
virtual tribool canUnpack() override { return super::canUnpack(); } // bool, except -1: format known, but not packed
|
||||
|
||||
protected:
|
||||
virtual const int *getCompressionMethods(int method, int level) const override;
|
||||
@ -140,8 +140,8 @@ protected:
|
||||
virtual void PackLinuxElf32help1(InputFile *f);
|
||||
virtual int checkEhdr(Elf32_Ehdr const *ehdr) const;
|
||||
virtual bool canPackOSABI(Elf32_Ehdr const *);
|
||||
virtual bool canPack() override;
|
||||
virtual int canUnpack() override; // bool, except -1: format known, but not packed
|
||||
virtual tribool canPack() override;
|
||||
virtual tribool canUnpack() override; // bool, except -1: format known, but not packed
|
||||
|
||||
// These ARM routines are essentially common to big/little endian,
|
||||
// but the class hierarchy splits after this class.
|
||||
@ -311,8 +311,8 @@ public:
|
||||
protected:
|
||||
virtual void PackLinuxElf64help1(InputFile *f);
|
||||
virtual int checkEhdr(Elf64_Ehdr const *ehdr) const;
|
||||
virtual bool canPack() override;
|
||||
virtual int canUnpack() override; // bool, except -1: format known, but not packed
|
||||
virtual tribool canPack() override;
|
||||
virtual tribool canUnpack() override; // bool, except -1: format known, but not packed
|
||||
|
||||
virtual void pack1(OutputFile *, Filter &) override; // generate executable header
|
||||
virtual void asl_pack2_Shdrs(OutputFile *, unsigned pre_xct_top); // AndroidSharedLibrary processes Shdrs
|
||||
@ -606,7 +606,7 @@ public:
|
||||
virtual const char *getName() const override { return "linux/i386"; }
|
||||
virtual const char *getFullName(const options_t *) const override { return "i386-linux.elf"; }
|
||||
virtual const int *getFilters() const override;
|
||||
virtual int canUnpack() override; // bool, except -1: format known, but not packed
|
||||
virtual tribool canUnpack() override; // bool, except -1: format known, but not packed
|
||||
|
||||
protected:
|
||||
virtual void pack1(OutputFile *, Filter &) override; // generate executable header
|
||||
|
||||
@ -495,7 +495,7 @@ int PackLinuxI386::checkEhdr(const Elf_LE32_Ehdr *ehdr) const
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
bool PackLinuxI386::canPack()
|
||||
tribool PackLinuxI386::canPack()
|
||||
{
|
||||
if (exetype != 0)
|
||||
return super::canPack();
|
||||
|
||||
@ -54,7 +54,7 @@ public:
|
||||
virtual const int *getFilters() const override;
|
||||
virtual void buildLoader(const Filter *) override;
|
||||
|
||||
virtual bool canPack() override;
|
||||
virtual tribool canPack() override;
|
||||
|
||||
protected:
|
||||
virtual void pack1(OutputFile *, Filter &) override; // generate executable header
|
||||
|
||||
@ -64,7 +64,7 @@ PackLinuxElf32x86interp::~PackLinuxElf32x86interp()
|
||||
{
|
||||
}
|
||||
|
||||
bool PackLinuxElf32x86interp::canPack()
|
||||
tribool PackLinuxElf32x86interp::canPack()
|
||||
{
|
||||
if (opt->o_unix.make_ptinterp) {
|
||||
return true;
|
||||
|
||||
@ -49,7 +49,7 @@ public:
|
||||
virtual const char *getName() const override { return "linux/elfi386"; }
|
||||
virtual const char *getFullName(const options_t *) const override { return "i386-linux.elf.interp"; }
|
||||
|
||||
virtual bool canPack() override;
|
||||
virtual tribool canPack() override;
|
||||
virtual void unpack(OutputFile *fo) override;
|
||||
|
||||
protected:
|
||||
|
||||
@ -122,7 +122,7 @@ bool PackLinuxI386sh::getShellName(char *buf)
|
||||
return false;
|
||||
for (int j = 0; nullptr != shname[j]; ++j) {
|
||||
if (0 == strcmp(shname[j], bname + 1)) {
|
||||
bool const s = super::canPack();
|
||||
bool const s = bool(super::canPack());
|
||||
if (s) {
|
||||
opt->o_unix.blocksize = blocksize = file_size;
|
||||
}
|
||||
@ -138,7 +138,7 @@ bool PackLinuxI386sh::getShellName(char *buf)
|
||||
}
|
||||
|
||||
|
||||
bool PackLinuxI386sh::canPack()
|
||||
tribool PackLinuxI386sh::canPack()
|
||||
{
|
||||
#if defined(__linux__) //{
|
||||
// only compress i386sh scripts when running under Linux
|
||||
|
||||
@ -54,7 +54,7 @@ public:
|
||||
virtual void pack1(OutputFile *fo, Filter &ft) override;
|
||||
virtual off_t pack3(OutputFile *fo, Filter &ft) override;
|
||||
|
||||
virtual bool canPack() override;
|
||||
virtual tribool canPack() override;
|
||||
// virtual void unpack(OutputFile *fo) { super::unpack(fo); }
|
||||
virtual bool canUnpackVersion(int version) const override
|
||||
{ return (version >= 11); }
|
||||
|
||||
@ -1615,7 +1615,7 @@ void PackMachBase<T>::unpack(OutputFile *fo)
|
||||
|
||||
// The prize is the value of overlay_offset: the offset of compressed data
|
||||
template <class T>
|
||||
int PackMachBase<T>::canUnpack()
|
||||
tribool PackMachBase<T>::canUnpack()
|
||||
{
|
||||
unsigned const lc_seg = lc_seg_info[sizeof(Addr)>>3].segment_cmd;
|
||||
fi->seek(0, SEEK_SET);
|
||||
@ -1924,7 +1924,7 @@ upx_uint64_t PackMachBase<T>::get_mod_init_func(Mach_segment_command const *segp
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool PackMachBase<T>::canPack()
|
||||
tribool PackMachBase<T>::canPack()
|
||||
{
|
||||
unsigned const lc_seg = lc_seg_info[sizeof(Addr)>>3].segment_cmd;
|
||||
fi->seek(0, SEEK_SET);
|
||||
@ -2484,7 +2484,7 @@ void PackMachFat::unpack(OutputFile *fo)
|
||||
}
|
||||
}
|
||||
|
||||
bool PackMachFat::canPack()
|
||||
tribool PackMachFat::canPack()
|
||||
{
|
||||
struct Mach_fat_arch const *const arch = &fat_head.arch[0];
|
||||
|
||||
@ -2552,7 +2552,7 @@ bool PackMachFat::canPack()
|
||||
return true;
|
||||
}
|
||||
|
||||
int PackMachFat::canUnpack()
|
||||
tribool PackMachFat::canUnpack()
|
||||
{
|
||||
struct Mach_fat_arch const *const arch = &fat_head.arch[0];
|
||||
|
||||
|
||||
@ -756,8 +756,8 @@ public:
|
||||
virtual void pack1_setup_threado(OutputFile *const fo) = 0;
|
||||
virtual void unpack(OutputFile *fo) override;
|
||||
|
||||
virtual bool canPack() override;
|
||||
virtual int canUnpack() override;
|
||||
virtual tribool canPack() override;
|
||||
virtual tribool canUnpack() override;
|
||||
virtual upx_uint64_t get_mod_init_func(Mach_segment_command const *segptr);
|
||||
virtual unsigned find_SEGMENT_gap(unsigned const k, unsigned pos_eof);
|
||||
|
||||
@ -1257,8 +1257,8 @@ protected:
|
||||
virtual void list() override;
|
||||
|
||||
public:
|
||||
virtual bool canPack() override;
|
||||
virtual int canUnpack() override;
|
||||
virtual tribool canPack() override;
|
||||
virtual tribool canUnpack() override;
|
||||
|
||||
protected:
|
||||
// loader core
|
||||
|
||||
@ -220,7 +220,7 @@ bool PackPs1::checkFileHeader() {
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
bool PackPs1::canPack() {
|
||||
tribool PackPs1::canPack() {
|
||||
byte buf[PS_HDR_SIZE - sizeof(ps1_exe_t)];
|
||||
|
||||
if (!readFileHeader())
|
||||
@ -614,7 +614,7 @@ void PackPs1::pack(OutputFile *fo) {
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int PackPs1::canUnpack() {
|
||||
tribool PackPs1::canUnpack() {
|
||||
if (!readFileHeader())
|
||||
return false;
|
||||
if (!readPackHeader(CD_SEC))
|
||||
|
||||
@ -50,8 +50,8 @@ public:
|
||||
virtual void pack(OutputFile *fo) override;
|
||||
virtual void unpack(OutputFile *fo) override;
|
||||
|
||||
virtual bool canPack() override;
|
||||
virtual int canUnpack() override;
|
||||
virtual tribool canPack() override;
|
||||
virtual tribool canUnpack() override;
|
||||
|
||||
protected:
|
||||
void putBkupHeader(const byte *src, byte *dst, unsigned *len);
|
||||
|
||||
@ -40,7 +40,7 @@ static const CLANG_FORMAT_DUMMY_STATEMENT
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
bool PackSys::canPack() {
|
||||
tribool PackSys::canPack() {
|
||||
byte buf[128];
|
||||
|
||||
fi->readx(buf, sizeof(buf));
|
||||
|
||||
@ -41,7 +41,7 @@ public:
|
||||
virtual const char *getName() const override { return "dos/sys"; }
|
||||
virtual const char *getFullName(const Options *) const override { return "i086-dos16.sys"; }
|
||||
|
||||
virtual bool canPack() override;
|
||||
virtual tribool canPack() override;
|
||||
|
||||
protected: // dos/com overrides
|
||||
virtual unsigned getCallTrickOffset() const override { return 0; }
|
||||
|
||||
@ -150,7 +150,7 @@ int PackTmt::readFileHeader() {
|
||||
#undef H
|
||||
}
|
||||
|
||||
bool PackTmt::canPack() {
|
||||
tribool PackTmt::canPack() {
|
||||
if (!readFileHeader())
|
||||
return false;
|
||||
return true;
|
||||
@ -265,7 +265,7 @@ void PackTmt::pack(OutputFile *fo) {
|
||||
throwNotCompressible();
|
||||
}
|
||||
|
||||
int PackTmt::canUnpack() {
|
||||
tribool PackTmt::canUnpack() {
|
||||
if (!readFileHeader())
|
||||
return false;
|
||||
fi->seek(adam_offset, SEEK_SET);
|
||||
|
||||
@ -48,8 +48,8 @@ public:
|
||||
virtual void pack(OutputFile *fo) override;
|
||||
virtual void unpack(OutputFile *fo) override;
|
||||
|
||||
virtual bool canPack() override;
|
||||
virtual int canUnpack() override;
|
||||
virtual tribool canPack() override;
|
||||
virtual tribool canUnpack() override;
|
||||
|
||||
protected:
|
||||
int readFileHeader();
|
||||
|
||||
@ -342,7 +342,7 @@ static bool check_relocs(const byte *relocs, unsigned rsize, unsigned image_size
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
bool PackTos::canPack() {
|
||||
tribool PackTos::canPack() {
|
||||
if (!readFileHeader())
|
||||
return false;
|
||||
|
||||
@ -673,7 +673,7 @@ void PackTos::pack(OutputFile *fo) {
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int PackTos::canUnpack() {
|
||||
tribool PackTos::canUnpack() {
|
||||
if (!readFileHeader())
|
||||
return false;
|
||||
if (!readPackHeader(768))
|
||||
|
||||
@ -46,8 +46,8 @@ public:
|
||||
virtual void pack(OutputFile *fo) override;
|
||||
virtual void unpack(OutputFile *fo) override;
|
||||
|
||||
virtual bool canPack() override;
|
||||
virtual int canUnpack() override;
|
||||
virtual tribool canPack() override;
|
||||
virtual tribool canUnpack() override;
|
||||
|
||||
virtual void fileInfo() override;
|
||||
|
||||
|
||||
@ -67,7 +67,7 @@ PackUnix::~PackUnix()
|
||||
}
|
||||
|
||||
// common part of canPack(), enhanced by subclasses
|
||||
bool PackUnix::canPack()
|
||||
tribool PackUnix::canPack()
|
||||
{
|
||||
if (exetype == 0)
|
||||
return false;
|
||||
@ -555,7 +555,7 @@ unsigned PackUnix::unpackExtent(unsigned wanted, OutputFile *fo,
|
||||
**************************************************************************/
|
||||
|
||||
// The prize is the value of overlay_offset: the offset of compressed data
|
||||
int PackUnix::canUnpack()
|
||||
tribool PackUnix::canUnpack()
|
||||
{
|
||||
int const small = 32 + sizeof(overlay_offset);
|
||||
// Allow zero-filled last page, for Mac OS X code signing.
|
||||
|
||||
@ -55,8 +55,8 @@ public:
|
||||
virtual void pack(OutputFile *fo) override;
|
||||
virtual void unpack(OutputFile *fo) override;
|
||||
|
||||
virtual bool canPack() override;
|
||||
virtual int canUnpack() override; // bool, except -1: format known, but not packed
|
||||
virtual tribool canPack() override;
|
||||
virtual tribool canUnpack() override; // bool, except -1: format known, but not packed
|
||||
int find_overlay_offset(MemBuffer const &buf);
|
||||
|
||||
protected:
|
||||
|
||||
@ -143,7 +143,7 @@ typename T::Shdr const *PackVmlinuxBase<T>::getElfSections()
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool PackVmlinuxBase<T>::canPack()
|
||||
tribool PackVmlinuxBase<T>::canPack()
|
||||
{
|
||||
fi->seek(0, SEEK_SET);
|
||||
fi->readx(&ehdri, sizeof(ehdri));
|
||||
@ -553,7 +553,7 @@ void PackVmlinuxBase<T>::pack(OutputFile *fo)
|
||||
}
|
||||
|
||||
template <class T>
|
||||
int PackVmlinuxBase<T>::canUnpack()
|
||||
tribool PackVmlinuxBase<T>::canUnpack()
|
||||
{
|
||||
fi->seek(0, SEEK_SET);
|
||||
fi->readx(&ehdri, sizeof(ehdri));
|
||||
|
||||
@ -83,9 +83,9 @@ protected:
|
||||
virtual int getStrategy(Filter &/*ft*/);
|
||||
virtual bool is_valid_e_entry(Addr) = 0;
|
||||
virtual bool has_valid_vmlinux_head() = 0;
|
||||
virtual bool canPack() override;
|
||||
virtual tribool canPack() override;
|
||||
virtual void pack(OutputFile *fo) override;
|
||||
virtual int canUnpack() override; // bool, except -1: format known, but not packed
|
||||
virtual tribool canUnpack() override; // bool, except -1: format known, but not packed
|
||||
virtual void unpack(OutputFile *fo) override;
|
||||
virtual unsigned write_vmlinux_head(
|
||||
OutputFile *fo,
|
||||
|
||||
@ -93,7 +93,7 @@ int PackVmlinuzI386::getStrategy(Filter &/*ft*/)
|
||||
}
|
||||
|
||||
|
||||
bool PackVmlinuzI386::canPack()
|
||||
tribool PackVmlinuzI386::canPack()
|
||||
{
|
||||
return readFileHeader() == getFormat();
|
||||
}
|
||||
@ -671,7 +671,7 @@ void PackBvmlinuzI386::pack(OutputFile *fo)
|
||||
// unpack
|
||||
**************************************************************************/
|
||||
|
||||
int PackVmlinuzI386::canUnpack()
|
||||
tribool PackVmlinuzI386::canUnpack()
|
||||
{
|
||||
if (readFileHeader() != getFormat())
|
||||
return false;
|
||||
@ -735,7 +735,7 @@ int PackVmlinuzARMEL::getStrategy(Filter &/*ft*/)
|
||||
return (opt->no_filter ? -3 : ((opt->filter > 0) ? -2 : 2));
|
||||
}
|
||||
|
||||
bool PackVmlinuzARMEL::canPack()
|
||||
tribool PackVmlinuzARMEL::canPack()
|
||||
{
|
||||
return readFileHeader() == getFormat();
|
||||
}
|
||||
@ -1029,7 +1029,7 @@ void PackVmlinuzARMEL::pack(OutputFile *fo)
|
||||
throwNotCompressible();
|
||||
}
|
||||
|
||||
int PackVmlinuzARMEL::canUnpack()
|
||||
tribool PackVmlinuzARMEL::canUnpack()
|
||||
{
|
||||
if (readFileHeader() != getFormat())
|
||||
return false;
|
||||
|
||||
@ -51,8 +51,8 @@ public:
|
||||
virtual void pack(OutputFile *fo) override;
|
||||
virtual void unpack(OutputFile *fo) override;
|
||||
|
||||
virtual bool canPack() override;
|
||||
virtual int canUnpack() override;
|
||||
virtual tribool canPack() override;
|
||||
virtual tribool canUnpack() override;
|
||||
|
||||
protected:
|
||||
virtual int readFileHeader();
|
||||
@ -142,8 +142,8 @@ public:
|
||||
virtual void pack(OutputFile *fo) override;
|
||||
virtual void unpack(OutputFile *fo) override;
|
||||
|
||||
virtual bool canPack() override;
|
||||
virtual int canUnpack() override;
|
||||
virtual tribool canPack() override;
|
||||
virtual tribool canUnpack() override;
|
||||
|
||||
protected:
|
||||
virtual int readFileHeader();
|
||||
|
||||
@ -75,7 +75,7 @@ int PackW32PeI386::readFileHeader() {
|
||||
// pack
|
||||
**************************************************************************/
|
||||
|
||||
bool PackW32PeI386::canPack() {
|
||||
tribool PackW32PeI386::canPack() {
|
||||
if (!readFileHeader())
|
||||
return false;
|
||||
checkMachine(ih.cpu);
|
||||
|
||||
@ -51,7 +51,7 @@ public:
|
||||
virtual void setOhHeaderSize(const pe_section_t *osection) override;
|
||||
virtual void pack(OutputFile *fo) override;
|
||||
|
||||
virtual bool canPack() override;
|
||||
virtual tribool canPack() override;
|
||||
|
||||
protected:
|
||||
virtual int readFileHeader() override;
|
||||
|
||||
@ -65,7 +65,7 @@ Linker *PackW64PeAmd64::newLinker() const { return new ElfLinkerAMD64; }
|
||||
// pack
|
||||
**************************************************************************/
|
||||
|
||||
bool PackW64PeAmd64::canPack() {
|
||||
tribool PackW64PeAmd64::canPack() {
|
||||
if (!readFileHeader())
|
||||
return false;
|
||||
checkMachine(ih.cpu);
|
||||
|
||||
@ -50,7 +50,7 @@ public:
|
||||
virtual void setOhHeaderSize(const pe_section_t *osection) override;
|
||||
virtual void pack(OutputFile *fo) override;
|
||||
|
||||
virtual bool canPack() override;
|
||||
virtual tribool canPack() override;
|
||||
|
||||
protected:
|
||||
virtual void buildLoader(const Filter *ft) override;
|
||||
|
||||
@ -59,7 +59,7 @@ const int *PackW64PeArm64::getFilters() const { return nullptr; }
|
||||
// pack
|
||||
**************************************************************************/
|
||||
|
||||
bool PackW64PeArm64::canPack() {
|
||||
tribool PackW64PeArm64::canPack() {
|
||||
if (!readFileHeader())
|
||||
return false;
|
||||
checkMachine(ih.cpu);
|
||||
@ -106,7 +106,7 @@ void PackW64PeArm64::pack(OutputFile *fo) {
|
||||
// pack
|
||||
**************************************************************************/
|
||||
|
||||
bool PackW64PeArm64EC::canPack() {
|
||||
tribool PackW64PeArm64EC::canPack() {
|
||||
if (!readFileHeader())
|
||||
return false;
|
||||
checkMachine(ih.cpu);
|
||||
|
||||
@ -50,7 +50,7 @@ public:
|
||||
virtual void setOhHeaderSize(const pe_section_t *osection) override;
|
||||
virtual void pack(OutputFile *fo) override;
|
||||
|
||||
virtual bool canPack() override;
|
||||
virtual tribool canPack() override;
|
||||
|
||||
protected:
|
||||
virtual void buildLoader(const Filter *ft) override;
|
||||
@ -74,7 +74,7 @@ public:
|
||||
virtual const char *getName() const override { return "win64/arm64ec"; }
|
||||
virtual const char *getFullName(const Options *) const override { return "arm64ec-win64.pe"; }
|
||||
|
||||
virtual bool canPack() override;
|
||||
virtual tribool canPack() override;
|
||||
};
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
||||
@ -112,7 +112,7 @@ void PackWcle::handleStub(OutputFile *fo) {
|
||||
Packer::handleStub(fi, fo, le_offset);
|
||||
}
|
||||
|
||||
bool PackWcle::canPack() {
|
||||
tribool PackWcle::canPack() {
|
||||
if (!LeFile::readFileHeader())
|
||||
return false;
|
||||
return true;
|
||||
@ -731,7 +731,7 @@ void PackWcle::decodeEntryTable() {
|
||||
ientries = nullptr;
|
||||
}
|
||||
|
||||
int PackWcle::canUnpack() {
|
||||
tribool PackWcle::canUnpack() {
|
||||
if (!LeFile::readFileHeader())
|
||||
return false;
|
||||
fi->seek(exe_offset + ih.data_pages_offset, SEEK_SET);
|
||||
|
||||
@ -48,8 +48,8 @@ public:
|
||||
virtual void pack(OutputFile *fo) override;
|
||||
virtual void unpack(OutputFile *fo) override;
|
||||
|
||||
virtual bool canPack() override;
|
||||
virtual int canUnpack() override;
|
||||
virtual tribool canPack() override;
|
||||
virtual tribool canUnpack() override;
|
||||
|
||||
protected:
|
||||
virtual void handleStub(OutputFile *fo);
|
||||
|
||||
@ -111,7 +111,7 @@ void PackWinCeArm::processTls(Interval *) // pass 1
|
||||
// pack
|
||||
**************************************************************************/
|
||||
|
||||
bool PackWinCeArm::canPack() {
|
||||
tribool PackWinCeArm::canPack() {
|
||||
if (!readFileHeader())
|
||||
return false;
|
||||
checkMachine(ih.cpu);
|
||||
|
||||
@ -55,7 +55,7 @@ public:
|
||||
virtual void setOhHeaderSize(const pe_section_t *osection) override;
|
||||
virtual void pack(OutputFile *fo) override;
|
||||
|
||||
virtual bool canPack() override;
|
||||
virtual tribool canPack() override;
|
||||
|
||||
protected:
|
||||
virtual void buildLoader(const Filter *ft) override;
|
||||
|
||||
22
src/packer.h
22
src/packer.h
@ -57,12 +57,14 @@ public:
|
||||
virtual const int *getCompressionMethods(int method, int level) const = 0;
|
||||
virtual const int *getFilters() const = 0;
|
||||
|
||||
// canPack() should throw a cantPackException eplaining why it
|
||||
// cannot pack a recognized format.
|
||||
virtual bool canPack() = 0;
|
||||
// canUnpack() can return -1 meaning "format recognized, but file
|
||||
// is definitely not packed". See packmast.cpp try_unpack().
|
||||
virtual int canUnpack() = 0;
|
||||
// canPack() should throw a cantPackException eplaining why it cannot pack
|
||||
// a recognized format.
|
||||
// canPack() can return -1 to stop early; see class PackMaster
|
||||
virtual tribool canPack() = 0;
|
||||
// canUnpack() should throw a cantUnpackException eplaining why it cannot pack
|
||||
// a recognized format.
|
||||
// canUnpack() can return -1 to stop early; see class PackMaster
|
||||
virtual tribool canUnpack() = 0;
|
||||
|
||||
// PackMaster entries
|
||||
virtual void assertPacker() const = 0;
|
||||
@ -164,10 +166,10 @@ protected:
|
||||
void verifyOverlappingDecompression(byte *o_ptr, unsigned o_size, Filter *ft = nullptr);
|
||||
|
||||
// packheader handling
|
||||
virtual int patchPackHeader(void *b, int blen);
|
||||
virtual bool getPackHeader(const void *b, int blen, bool allow_incompressible = false);
|
||||
virtual bool readPackHeader(int len, bool allow_incompressible = false);
|
||||
virtual void checkAlreadyPacked(const void *b, int blen);
|
||||
virtual int patchPackHeader(void *b, int blen) final;
|
||||
virtual bool getPackHeader(const void *b, int blen, bool allow_incompressible = false) final;
|
||||
virtual bool readPackHeader(int len, bool allow_incompressible = false) final;
|
||||
virtual void checkAlreadyPacked(const void *b, int blen) final;
|
||||
|
||||
// loader core
|
||||
virtual void buildLoader(const Filter *ft) = 0;
|
||||
|
||||
@ -89,37 +89,38 @@ PackMaster::~PackMaster() noexcept {
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
static bool try_can_pack(PackerBase *pb, void *user) may_throw {
|
||||
static tribool try_can_pack(PackerBase *pb, void *user) may_throw {
|
||||
InputFile *f = (InputFile *) user;
|
||||
try {
|
||||
pb->initPackHeader();
|
||||
f->seek(0, SEEK_SET);
|
||||
if (pb->canPack()) {
|
||||
tribool r = pb->canPack();
|
||||
if (r) {
|
||||
if (opt->cmd == CMD_COMPRESS)
|
||||
pb->updatePackHeader();
|
||||
f->seek(0, SEEK_SET);
|
||||
return true;
|
||||
return true; // success
|
||||
}
|
||||
if (r.isOther()) // aka "-1"
|
||||
return r; // canPack() says the format is recognized and we should stop early
|
||||
} catch (const IOException &) {
|
||||
// ignored
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool try_can_unpack(PackerBase *pb, void *user) may_throw {
|
||||
static tribool try_can_unpack(PackerBase *pb, void *user) may_throw {
|
||||
InputFile *f = (InputFile *) user;
|
||||
try {
|
||||
pb->initPackHeader();
|
||||
f->seek(0, SEEK_SET);
|
||||
int r = pb->canUnpack();
|
||||
if (r > 0) {
|
||||
tribool r = pb->canUnpack();
|
||||
if (r) {
|
||||
f->seek(0, SEEK_SET);
|
||||
return true;
|
||||
}
|
||||
if (r < 0) {
|
||||
// FIXME - could stop testing all other unpackers at this time
|
||||
// see canUnpack() in packer.h
|
||||
return true; // success
|
||||
}
|
||||
if (r.isOther()) // aka "-1"
|
||||
return r; // canUnpack() says the format is recognized and we should stop early
|
||||
} catch (const IOException &) {
|
||||
// ignored
|
||||
}
|
||||
@ -141,8 +142,11 @@ PackerBase *PackMaster::visitAllPackers(visit_func_t func, InputFile *f, const O
|
||||
if (o->debug.debug_level) \
|
||||
fprintf(stderr, "visitAllPackers: (ver=%d, fmt=%3d) %s\n", pb->getVersion(), \
|
||||
pb->getFormat(), #Klass); \
|
||||
if (func(pb.get(), user)) \
|
||||
return pb.release(); \
|
||||
tribool r = func(pb.get(), user); \
|
||||
if (r) \
|
||||
return pb.release(); /* success */ \
|
||||
if (r.isOther()) \
|
||||
return nullptr; /* stop early */ \
|
||||
ACC_BLOCK_END
|
||||
|
||||
// NOTE: order of tries is important !!!
|
||||
|
||||
@ -46,7 +46,7 @@ public:
|
||||
void list();
|
||||
void fileInfo();
|
||||
|
||||
typedef bool (*visit_func_t)(PackerBase *pb, void *user);
|
||||
typedef tribool (*visit_func_t)(PackerBase *pb, void *user);
|
||||
static PackerBase *visitAllPackers(visit_func_t, InputFile *f, const Options *, void *user)
|
||||
may_throw;
|
||||
|
||||
|
||||
@ -1795,14 +1795,14 @@ void PeFile::processResources(Resource *res) {
|
||||
return;
|
||||
|
||||
// setup default options for resource compression
|
||||
if (opt->win32_pe.compress_resources < 0)
|
||||
if (opt->win32_pe.compress_resources.isOther())
|
||||
opt->win32_pe.compress_resources = !isefi;
|
||||
if (!opt->win32_pe.compress_resources) {
|
||||
opt->win32_pe.compress_icons = false;
|
||||
for (int i = 0; i < RT_LAST; i++)
|
||||
opt->win32_pe.compress_rt[i] = false;
|
||||
}
|
||||
if (opt->win32_pe.compress_rt[RT_STRING] < 0) {
|
||||
if (opt->win32_pe.compress_rt[RT_STRING].isOther()) {
|
||||
// by default, don't compress RT_STRINGs of screensavers (".scr")
|
||||
opt->win32_pe.compress_rt[RT_STRING] = true;
|
||||
if (fn_has_ext(fi->getName(), "scr"))
|
||||
@ -3017,7 +3017,7 @@ void PeFile32::unpack(OutputFile *fo) {
|
||||
unpack0<pe_header_t, LE32>(fo, ih, oh, 1U << 31, set_oft);
|
||||
}
|
||||
|
||||
int PeFile32::canUnpack() {
|
||||
tribool PeFile32::canUnpack() {
|
||||
if (!canPack()) // this calls readFileHeader() and readPeHeader()
|
||||
return false;
|
||||
return canUnpack0(getFormat() == UPX_F_WINCE_ARM ? 4 : 3, ih.objects, ih.entry, sizeof(ih));
|
||||
@ -3065,7 +3065,7 @@ void PeFile64::pack0(OutputFile *fo, unsigned subsystem_mask, upx_uint64_t defau
|
||||
|
||||
void PeFile64::unpack(OutputFile *fo) { unpack0<pe_header_t, LE64>(fo, ih, oh, 1ULL << 63, false); }
|
||||
|
||||
int PeFile64::canUnpack() {
|
||||
tribool PeFile64::canUnpack() {
|
||||
if (!canPack()) // this calls readFileHeader() and readPeHeader()
|
||||
return false;
|
||||
return canUnpack0(3, ih.objects, ih.entry, sizeof(ih));
|
||||
|
||||
@ -503,7 +503,7 @@ protected:
|
||||
void pack0(OutputFile *fo, unsigned subsystem_mask, upx_uint64_t default_imagebase,
|
||||
bool last_section_rsrc_only);
|
||||
virtual void unpack(OutputFile *fo) override;
|
||||
virtual int canUnpack() override;
|
||||
virtual tribool canUnpack() override;
|
||||
|
||||
virtual void readPeHeader() override;
|
||||
|
||||
@ -564,7 +564,7 @@ protected:
|
||||
void pack0(OutputFile *fo, unsigned subsystem_mask, upx_uint64_t default_imagebase);
|
||||
|
||||
virtual void unpack(OutputFile *fo) override;
|
||||
virtual int canUnpack() override;
|
||||
virtual tribool canUnpack() override;
|
||||
|
||||
virtual void readPeHeader() override;
|
||||
|
||||
|
||||
@ -787,4 +787,60 @@ TEST_CASE("get_ratio") {
|
||||
CHECK(get_ratio(2 * UPX_RSIZE_MAX, 1024ull * UPX_RSIZE_MAX) == 9999999);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct TestTriBool {
|
||||
static void test(bool expect_true, int x) noexcept {
|
||||
CHECK(T(false) == T::False);
|
||||
CHECK(T(true) == T::True);
|
||||
CHECK(T(T::Other) == T::Other);
|
||||
T a;
|
||||
CHECK(!a);
|
||||
CHECK(a.isStrictFalse());
|
||||
CHECK(!a.isStrictTrue());
|
||||
CHECK(a.isStrictBool());
|
||||
CHECK(!a.isOther());
|
||||
a = false;
|
||||
CHECK(!a);
|
||||
CHECK(a.isStrictFalse());
|
||||
CHECK(!a.isStrictTrue());
|
||||
CHECK(a.isStrictBool());
|
||||
CHECK(!a.isOther());
|
||||
a = true;
|
||||
CHECK(a);
|
||||
CHECK(!a.isStrictFalse());
|
||||
CHECK(a.isStrictTrue());
|
||||
CHECK(a.isStrictBool());
|
||||
CHECK(!a.isOther());
|
||||
a = T::Other;
|
||||
if (expect_true)
|
||||
CHECK(a);
|
||||
else
|
||||
CHECK(!a);
|
||||
CHECK(!a.isStrictFalse());
|
||||
CHECK(!a.isStrictTrue());
|
||||
CHECK(!a.isStrictBool());
|
||||
CHECK(a.isOther());
|
||||
a = x;
|
||||
if (expect_true)
|
||||
CHECK(a);
|
||||
else
|
||||
CHECK(!a);
|
||||
CHECK(!a.isStrictFalse());
|
||||
CHECK(!a.isStrictTrue());
|
||||
CHECK(!a.isStrictBool());
|
||||
CHECK(a.isOther());
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CASE("TriBool") {
|
||||
TestTriBool<tribool>::test(false, -1);
|
||||
TestTriBool<TriBool<upx_int8_t> >::test(false, -1);
|
||||
TestTriBool<TriBool<upx_int64_t> >::test(false, -1);
|
||||
//
|
||||
TestTriBool<TriBool<upx_int8_t, 2> >::test(true, 2);
|
||||
TestTriBool<TriBool<upx_uint8_t, 2> >::test(true, 2);
|
||||
TestTriBool<TriBool<upx_int64_t, 2> >::test(true, 2);
|
||||
TestTriBool<TriBool<upx_uint64_t, 2> >::test(true, 2);
|
||||
}
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
||||
@ -194,6 +194,49 @@ inline void owner_delete(T (&array)[]) noexcept DELETED_FUNCTION;
|
||||
template <class T, size_t N>
|
||||
inline void owner_delete(T (&array)[N]) noexcept DELETED_FUNCTION;
|
||||
|
||||
/*************************************************************************
|
||||
// TriBool - tri-state bool
|
||||
**************************************************************************/
|
||||
|
||||
template <class T = int, T TOther = -1> // an enum with an underlying type and 3 values
|
||||
class TriBool {
|
||||
public:
|
||||
// types
|
||||
typedef T underlying_type;
|
||||
static_assert(std::is_integral_v<underlying_type>);
|
||||
typedef decltype(T(0) + T(0)) promoted_type;
|
||||
static_assert(std::is_integral_v<promoted_type>);
|
||||
static_assert(TOther != 0 && TOther != 1);
|
||||
enum value_type : underlying_type { False = 0, True = 1, Other = TOther };
|
||||
// constructors
|
||||
forceinline TriBool() noexcept = default;
|
||||
forceinline ~TriBool() noexcept = default;
|
||||
constexpr TriBool(value_type x) noexcept : value(x) {}
|
||||
constexpr TriBool(promoted_type x) noexcept : value(x == 0 ? False : (x == 1 ? True : Other)) {}
|
||||
// access
|
||||
value_type getValue() const noexcept { return value; }
|
||||
// checks for > 0, so TOther determines if Other is false (the default) or true
|
||||
explicit operator bool() const noexcept { return value > False; }
|
||||
// query; this is NOT the same as operator bool()
|
||||
bool isStrictFalse() const noexcept { return value == False; }
|
||||
bool isStrictTrue() const noexcept { return value == True; }
|
||||
bool isStrictBool() const noexcept { return value == False || value == True; }
|
||||
bool isOther() const noexcept { return value != False && value != True; }
|
||||
// "other" can mean many things, depending on usage context, so provide some alternative names:
|
||||
// forceinline bool isDefault() const noexcept { return isOther(); } // might be misleading
|
||||
forceinline bool isIndeterminate() const noexcept { return isOther(); }
|
||||
forceinline bool isUndecided() const noexcept { return isOther(); }
|
||||
// forceinline bool isUnset() const noexcept { return isOther(); } // might be misleading
|
||||
constexpr bool operator==(TriBool other) const noexcept { return value == other.value; }
|
||||
constexpr bool operator==(value_type other) const noexcept { return value == other; }
|
||||
constexpr bool operator==(promoted_type other) const noexcept { return value == other; }
|
||||
protected:
|
||||
// value
|
||||
value_type value = False;
|
||||
};
|
||||
|
||||
typedef TriBool<> tribool;
|
||||
|
||||
/*************************************************************************
|
||||
// misc. support functions
|
||||
**************************************************************************/
|
||||
|
||||
Loading…
Reference in New Issue
Block a user