src: introduce type tribool

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