diff --git a/src/Makefile b/src/Makefile index 783e8915..a5543b12 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,30 +1,29 @@ # -# UPX Makefile - needs GNU make 3.81 or better +# UPX Makefile - needs GNU make # # Copyright (C) 1996-2020 Markus Franz Xaver Johannes Oberhumer # +MAKEFLAGS += -rR +.SUFFIXES: +export SHELL = /bin/sh + # build configuration options for this Makefile BUILD_TYPE_DEBUG ?= 0 BUILD_TYPE_SANITIZE ?= 0 BUILD_USE_DEPEND ?= 1 -MAKEFLAGS += -r -.SUFFIXES: -export SHELL = /bin/sh -override ee = $($1) $(EXTRA_$1) $(upx_$1) $(upx_EXTRA_$1) $($(basename $(notdir $@)).$1) - ifndef srcdir -srcdir := $(dir $(lastword $(MAKEFILE_LIST))) -srcdir := $(shell echo '$(srcdir)' | sed 's,/*$$,,' || echo 'ERROR') + srcdir := $(dir $(lastword $(MAKEFILE_LIST))) + srcdir := $(shell echo '$(srcdir)' | sed 's,/*$$,,' || echo 'ERROR') endif ifndef top_srcdir -top_srcdir := $(srcdir)/.. + top_srcdir := $(srcdir)/.. endif include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local) ifneq ($(srcdir),.) -vpath %.cpp .:$(srcdir) -vpath %.h .:$(srcdir) + vpath %.cpp .:$(srcdir) + vpath %.h .:$(srcdir) endif # toolchain @@ -34,50 +33,60 @@ exeext ?= .out libext ?= .a objext ?= .o +# flags composition +override all_flags = $(mf.$1) $($1) $(EXTRA_$1) $(upx_$1) $(upx_EXTRA_$1) $($(basename $(notdir $@)).$1) +ALL_CPPFLAGS = $(strip $(call all_flags,CPPFLAGS)) +ALL_CXXFLAGS = $(strip $(call all_flags,CXXFLAGS)) +ALL_LDFLAGS = $(strip $(call all_flags,LDFLAGS)) +ALL_LDADD = $(strip $(call all_flags,LDADD)) +ALL_LIBS = $(strip $(call all_flags,LIBS)) + upx_SOURCES := $(sort $(wildcard $(srcdir)/*.cpp)) upx_OBJECTS := $(notdir $(upx_SOURCES:.cpp=$(objext))) ifneq ($(wildcard $(top_srcdir)/.git/.),) UPX_VERSION_GITREV := $(strip $(shell cd '$(top_srcdir)' && git rev-parse --short=12 HEAD || echo 'ERROR')) ifneq ($(UPX_VERSION_GITREV),) -GITREV_PLUS := $(strip $(shell cd '$(top_srcdir)' && git diff --exit-code HEAD >/dev/null && echo '' || echo '+')) -DEFS += '-DUPX_VERSION_GITREV="$(UPX_VERSION_GITREV)$(GITREV_PLUS)"' + GITREV_PLUS := $(strip $(shell cd '$(top_srcdir)' && git diff --exit-code HEAD >/dev/null && echo '' || echo '+')) + DEFS += '-DUPX_VERSION_GITREV="$(UPX_VERSION_GITREV)$(GITREV_PLUS)"' endif endif # we need UCL and zlib - you can set envvar UPX_UCLDIR ifneq ($(wildcard $(UPX_UCLDIR)/include/ucl/ucl.h),) -INCLUDES += -I$(UPX_UCLDIR)/include -LIBS += $(addprefix -L,$(dir $(wildcard $(UPX_UCLDIR)/libucl$(libext) $(UPX_UCLDIR)/src/.libs/libucl$(libext)))) + INCLUDES += -I$(UPX_UCLDIR)/include + LIBS += $(addprefix -L,$(dir $(wildcard $(UPX_UCLDIR)/libucl$(libext) $(UPX_UCLDIR)/src/.libs/libucl$(libext)))) endif LIBS += -lucl -lz # LZMA from https://github.com/upx/upx-lzma-sdk include $(top_srcdir)/src/stub/src/c/Makevars.lzma -CPPFLAGS += $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) -CXXFLAGS += -std=c++14 +# optional flags ifeq ($(BUILD_TYPE_DEBUG),1) -CXXFLAGS_OPTIMIZE ?= -O0 -g + CXXFLAGS_OPTIMIZE ?= -O0 -g else -CXXFLAGS_OPTIMIZE ?= -O2 + CXXFLAGS_OPTIMIZE ?= -O2 endif -CXXFLAGS += $(CXXFLAGS_OPTIMIZE) -# protect against security threats caused by misguided C++ compiler "optimizations" -ifeq ($(findstring clang,$(CXX)),) -CXXFLAGS += -fno-delete-null-pointer-checks -endif -CXXFLAGS += -fno-strict-aliasing -fwrapv -CXXFLAGS += -funsigned-char -CXXFLAGS += -Wall -W -Wcast-align -Wcast-qual -Wmissing-declarations -Wpointer-arith -Wshadow -Wsign-compare -Wvla -Wwrite-strings -CXXFLAGS_WERROR ?= -Werror -CXXFLAGS += $(CXXFLAGS_WERROR) - ifeq ($(BUILD_TYPE_SANITIZE),1) -CXXFLAGS_SANITIZE ?= -fsanitize=address,undefined -fno-omit-frame-pointer -DACC_CFG_NO_UNALIGNED -CXXFLAGS += $(CXXFLAGS_SANITIZE) -# these are the only 2 objects that are actually speed-sensitive -compress_lzma$(objext) filteri$(objext) : override CXXFLAGS_SANITIZE = + CXXFLAGS_SANITIZE ?= -fsanitize=address,undefined -fno-omit-frame-pointer -DACC_CFG_NO_UNALIGNED +else + CXXFLAGS_SANITIZE ?= -fstack-protector-all endif +ifeq ($(findstring clang,$(CXX)),) + CXXFLAGS_NO_DELETE_NULL_POINTER_CHECKS ?= -fno-delete-null-pointer-checks +endif +CXXFLAGS_WERROR ?= -Werror + +# Mandatory Flags - DO NOT CHANGE! +mf.CPPFLAGS += $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) +mf.CXXFLAGS += $(CXXFLAGS_OPTIMIZE) +# protect against security threats caused by misguided C++ compiler "optimizations" +mf.CXXFLAGS += $(CXXFLAGS_NO_DELETE_NULL_POINTER_CHECKS) +mf.CXXFLAGS += -fno-strict-aliasing -fno-strict-overflow +mf.CXXFLAGS += -funsigned-char +mf.CXXFLAGS += $(CXXFLAGS_SANITIZE) +mf.CXXFLAGS += -Wall -W -Wcast-align -Wcast-qual -Wmissing-declarations -Wpointer-arith -Wshadow -Wvla -Wwrite-strings +mf.CXXFLAGS += $(CXXFLAGS_WERROR) # rules all: upx$(exeext) | ./.depend @@ -85,20 +94,30 @@ all: upx$(exeext) | ./.depend upx$(exeext): $(upx_OBJECTS) $(upx_DEPENDENCIES) $($(notdir $@).PRE_LINK_STEP) - $(strip $(CXXLD) $(call ee,CXXFLAGS) $(call ee,LDFLAGS) -o $@ $(upx_OBJECTS) $(call ee,LDADD) $(call ee,LIBS)) + $(strip $(CXXLD) $(ALL_CXXFLAGS) $(ALL_LDFLAGS) -o $@ $(upx_OBJECTS) $(ALL_LDADD) $(ALL_LIBS)) $($(notdir $@).POST_LINK_STEP) $(CHECK_WHITESPACE) %.o : %.cpp | ./.depend - $(strip $(CXX) $(call ee,CPPFLAGS) $(call ee,CXXFLAGS) -o $@ -c $<) + $(strip $(CXX) $(ALL_CPPFLAGS) $(ALL_CXXFLAGS) -o $@ -c $<) %.cpp.ii : %.cpp - $(strip $(CXX) $(call ee,CPPFLAGS) $(call ee,CXXFLAGS) -o $@ -E $<) + $(strip $(CXX) $(ALL_CPPFLAGS) $(ALL_CXXFLAGS) -o $@ -E $<) + +# object overrides +compress_lzma$(objext) : INCLUDES += -I$(UPX_LZMADIR) +# these are the only 2 objects that are actually speed-sensitive +compress_lzma$(objext) : override CXXFLAGS_SANITIZE = +filteri$(objext) : override CXXFLAGS_SANITIZE = +# disable some warnings +compress_lzma$(objext) : upx_CXXFLAGS += -Wno-shadow +p_mach$(objext) : upx_CXXFLAGS += -Wno-cast-align ifeq ($(BUILD_USE_DEPEND),1) ./.depend: $(sort $(wildcard $(srcdir)/*.cpp $(srcdir)/*.h)) $(MAKEFILE_LIST) @rm -f $@ @echo "Updating $@" - @$(strip $(CXX) $(call ee,CPPFLAGS) $(call ee,CXXFLAGS) -MM) $(filter %.cpp,$^) > $@ + @$(strip $(CXX) $(ALL_CPPFLAGS) $(ALL_CXXFLAGS) -MM) $(filter %.cpp,$^) > $@ +./.depend : INCLUDES += -I$(UPX_LZMADIR) else ./.depend: .PHONY: ./.depend @@ -117,11 +136,6 @@ endif mostlyclean clean distclean maintainer-clean: rm -f *.d *.ii *.map *.o *.obj *.res ./.depend upx.exe upx.out upx.ttp upx$(exeext) -./.depend compress_lzma$(objext) : INCLUDES += -I$(UPX_LZMADIR) - -compress_lzma$(objext) : CXXFLAGS += -Wno-shadow -p_mach$(objext) : CXXFLAGS += -Wno-cast-align - .PHONY: all mostlyclean clean distclean maintainer-clean ifeq ($(MAKECMDGOALS),mostlyclean) diff --git a/src/conf.h b/src/conf.h index 927224be..9f02aac0 100644 --- a/src/conf.h +++ b/src/conf.h @@ -65,6 +65,8 @@ # error "UINT_MAX" #endif ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(int) == 4) +ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(long long) == 8) +// check sane compiler mandatory flags ACC_COMPILE_TIME_ASSERT_HEADER(-1 == ~0) // two's complement - see http://wg21.link/P0907R4 ACC_COMPILE_TIME_ASSERT_HEADER(0u-1 == ~0u) // two's complement - see http://wg21.link/P0907R4 ACC_COMPILE_TIME_ASSERT_HEADER((1u << 31) << 1 == 0) @@ -179,7 +181,7 @@ typedef unsigned char upx_byte; // see C 11 standard, Annex K typedef size_t upx_rsize_t; #define UPX_RSIZE_MAX UPX_RSIZE_MAX_MEM -#define UPX_RSIZE_MAX_MEM (768 * 1024 * 1024) // DO NOT CHANGE +#define UPX_RSIZE_MAX_MEM (768 * 1024 * 1024) // DO NOT CHANGE !!! #define UPX_RSIZE_MAX_STR (1024 * 1024) @@ -671,6 +673,7 @@ void e_exit(int ec) __attribute__((__noreturn__)); #else void e_exit(int ec); #endif +void upx_compiler_sanity_check(void); // msg.cpp diff --git a/src/main.cpp b/src/main.cpp index 6234ce48..65a69c53 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1289,12 +1289,22 @@ static bool test(void) return true; }}; +template struct TestNoStrictAliasingStruct { + __acc_static_noinline bool test(A *a, B *b) { *a = 0; *b = (B)((B)0-1); return *a != 0; } +}; +template static inline bool testNoStrictAliasing(A *a, B *b) { + return TestNoStrictAliasingStruct::test(a, b); +} +template struct TestIntegerWrap { + static inline bool inc(T x) { return x + 1 > x; } + static inline bool dec(T x) { return x - 1 < x; } +}; #define ACC_WANT_ACC_CHK_CH 1 #undef ACCCHK_ASSERT #include "miniacc.h" -__acc_static_noinline void upx_sanity_check(void) +void upx_compiler_sanity_check(void) { #define ACC_WANT_ACC_CHK_CH 1 #undef ACCCHK_ASSERT @@ -1340,6 +1350,7 @@ __acc_static_noinline void upx_sanity_check(void) else { assert(revlen == 12 || revlen == 13); } if (revlen == 6 || revlen == 13) { assert(gitrev[revlen-1] == '+'); } } + assert(UPX_RSIZE_MAX_MEM == 805306368); #if 1 assert(TestBELE::test()); @@ -1396,6 +1407,18 @@ __acc_static_noinline void upx_sanity_check(void) assert(get_be64_signed(d) == UPX_INT64_C(9186918263483431288)); } #endif + + union { short v_short; int v_int; long v_long; } u; + assert(testNoStrictAliasing(&u.v_short, &u.v_long)); + + assert( TestIntegerWrap::inc(0)); + assert(!TestIntegerWrap::inc(INT_MAX)); + assert( TestIntegerWrap::dec(0)); + assert(!TestIntegerWrap::dec(INT_MIN)); + assert( TestIntegerWrap::inc(0)); + assert(!TestIntegerWrap::inc(UINT_MAX)); + assert( TestIntegerWrap::dec(1)); + assert(!TestIntegerWrap::dec(0)); } @@ -1427,7 +1450,7 @@ int __acc_cdecl_main main(int argc, char *argv[]) #endif acc_wildargv(&argc, &argv); - upx_sanity_check(); + upx_compiler_sanity_check(); opt->reset(); if (!argv[0] || !argv[0][0]) diff --git a/src/work.cpp b/src/work.cpp index b17ca148..88c914fb 100644 --- a/src/work.cpp +++ b/src/work.cpp @@ -255,6 +255,7 @@ static void unlink_ofile(char *oname) { } void do_files(int i, int argc, char *argv[]) { + upx_compiler_sanity_check(); if (opt->verbose >= 1) { show_head(); UiPacker::uiHeader();