diff --git a/GNUmakefile b/GNUmakefile index 2b5bcc23..3f48cc50 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -25,9 +25,9 @@ ifeq ($(PREFIX),) PREFIX = /usr endif -# Sadly, we can't actually use GCC_PRAGMA_AWARE because of GCC bug 53431. -# Its a shame because GCC has so much to offer by the way of analysis. -# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53431 +# Sadly, we can't actually use GCC_PRAGMA_AWARE with GCC because of GCC bug 53431. +# Its a shame because GCC has so much to offer by the way of analysis. Clang works +# as expected, though. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53431 ifneq ($(CLANG_COMPILER),0) CXXFLAGS += -Wall endif @@ -36,26 +36,41 @@ ifeq ($(IS_X86),1) GCC42_OR_LATER = $(shell $(CXX) -v 2>&1 | $(EGREP) -i -c "^gcc version (4.[2-9]|[5-9])") ICC111_OR_LATER = $(shell $(CXX) --version 2>&1 | $(EGREP) -c "\(ICC\) ([2-9][0-9]|1[2-9]|11\.[1-9])") -GAS210_OR_LATER = $(shell $(CXX) -xc -c /dev/null -Wa,-v -o/dev/null 2>&1 | $(EGREP) -c "GNU assembler version (2\.[1-9][0-9]|[3-9])") -GAS217_OR_LATER = $(shell $(CXX) -xc -c /dev/null -Wa,-v -o/dev/null 2>&1 | $(EGREP) -c "GNU assembler version (2\.1[7-9]|2\.[2-9]|[3-9])") -GAS219_OR_LATER = $(shell $(CXX) -xc -c /dev/null -Wa,-v -o/dev/null 2>&1 | $(EGREP) -c "GNU assembler version (2\.19|2\.[2-9]|[3-9])") +GAS210_OR_LATER ?= $(shell $(CXX) -xc -c /dev/null -Wa,-v -o/dev/null 2>&1 | $(EGREP) -c "GNU assembler version (2\.[1-9][0-9]|[3-9])") +GAS217_OR_LATER ?= $(shell $(CXX) -xc -c /dev/null -Wa,-v -o/dev/null 2>&1 | $(EGREP) -c "GNU assembler version (2\.1[7-9]|2\.[2-9]|[3-9])") +GAS219_OR_LATER ?= $(shell $(CXX) -xc -c /dev/null -Wa,-v -o/dev/null 2>&1 | $(EGREP) -c "GNU assembler version (2\.19|2\.[2-9]|[3-9])") # Enable PIC for x86_64 targets ifneq ($(IS_X86_64),0) CXXFLAGS += -fPIC endif # PIC for x86_64 targets -# Undefined Behavior Sanitzier (Clang and G++) +# Undefined Behavior Sanitizer (Clang 3.2 and GCC 4.8 and above) ifeq ($(findstring ubsan,$(MAKECMDGOALS)),ubsan) CXXFLAGS += -fsanitize=undefined -# CXXFLAGS += -fsanitize-undefined-trap-on-error +# CXXFLAGS += -fsanitize-undefined-trap-on-error endif # UBsan -# Address Sanitzier (Clang and G++) +# Address Sanitizer (Clang 3.2 and GCC 4.8 and above) ifeq ($(findstring asan,$(MAKECMDGOALS)),asan) CXXFLAGS += -fsanitize=address endif # Asan +# Test CXXFLAGS in case the user passed the flags directly through it +ASAN = 0 +UBSAN = 0 +ifeq ($(findstring -fsanitize=address,$(CXXFLAGS)),-fsanitize=address) +ASAN = 1 +endif +ifeq ($(findstring -fsanitize=undefined,$(CXXFLAGS)),-fsanitize=undefined) +UBSAN = 1 +endif + +# Enforce Sanitizer business logic... +ifeq ($(ASAN)$(UBSAN),11) +$(error Asan and UBsan are mutually exclusive) +endif + # Cygwin work arounds ifneq ($(IS_CYGWIN),0) @@ -70,7 +85,7 @@ CXXFLAGS := $(subst -fPIC,,$(CXXFLAGS)) endif # -fPIC # -O3 fails to link with GCC 4.5.3 -IS_GCC45 = $(shell $(CXX) -v 2>&1 | $(EGREP) -i -c "^gcc version 4\.5\.") +IS_GCC45 = $(shell $(CXX) -v 2>&1 | $(EGREP) -i -c "^gcc version 4\.5\.[0-9]") ifneq ($(IS_GCC45),0) ifeq ($(findstring -O3,$(CXXFLAGS)),-O3) CXXFLAGS := $(subst -O3,-O2,$(CXXFLAGS)) diff --git a/config.h b/config.h index 41632693..0a6495df 100644 --- a/config.h +++ b/config.h @@ -71,7 +71,15 @@ // Define this if you are working around Clang's integrated assembler bug by // disabling the assembler (https://llvm.org/bugs/show_bug.cgi?id=18916). -// #define CRYPTOPP_CLANG_NO_INTEGRATED_AS +// When the LLVM project fixes it, then we turn it on/off automatically. +#define WORKAROUND_LLVM_BUG_18916 + +// Define this if you are working with Clang's integrated assembler. As far as we know, +// the only way to tell is `$(CXX) -xc -c /dev/null -Wa,-v -o/dev/null 2>&1`. The +// integrated assembler will return `clang: error: unsupported argument '-v' option`. +#if defined(__clang__) +#define CRYPTOPP_USING_CLANG_INTEGRATED_ASSEMBLER +#endif #ifdef CRYPTOPP_DOXYGEN_PROCESSING // Avoid putting "CryptoPP::" in front of everything in Doxygen output diff --git a/cpu.h b/cpu.h index 115ed31c..4c4a9d57 100644 --- a/cpu.h +++ b/cpu.h @@ -209,6 +209,23 @@ inline int GetCacheLineSize() #define ASC(x, y) __asm {x label##y} #define CRYPTOPP_NAKED __declspec(naked) #define AS_HEX(y) 0x##y +#elif defined(__clang__) && defined(CRYPTOPP_USING_CLANG_INTEGRATED_ASSEMBLER) + #define CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY + // define these in two steps to allow arguments to be expanded + #define GNU_AS1(x) "\n\t" #x ";" + #define GNU_AS2(x, y) "\n\t" #x ", " #y ";" + #define GNU_AS3(x, y, z) "\n\t" #x ", " #y ", " #z ";" + #define GNU_ASL(x) "\n\t#x:" + #define GNU_ASJ(x, y, z) "\n\t#x " #y #z ";" + #define AS1(x) GNU_AS1(x) + #define AS2(x, y) GNU_AS2(x, y) + #define AS3(x, y, z) GNU_AS3(x, y, z) + #define ASS(x, y, a, b, c, d) "\n\t" #x ", " #y ", " #a "*64+" #b "*16+" #c "*4+" #d ";" + #define ASL(x) GNU_ASL(x) + #define ASJ(x, y, z) GNU_ASJ(x, y, z) + #define ASC(x, y) "\n\t" #x " " #y ";" + #define CRYPTOPP_NAKED + #define AS_HEX(y) 0x##y #else #define CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY // define these in two steps to allow arguments to be expanded @@ -229,15 +246,15 @@ inline int GetCacheLineSize() #endif // https://llvm.org/bugs/show_bug.cgi?id=18916 -#if defined(__clang__) -# define GNU_ATT_SYNTAX ".att_syntax;" -# define GNU_INTEL_SYNTAX ".intel_syntax;" +#if defined(__clang__) && defined(WORKAROUND_LLVM_BUG_18916) +# define GNU_AS_ATT_SYNTAX ".att_syntax;" +# define GNU_AS_INTEL_SYNTAX ".intel_syntax;" "\n" #elif defined(__GNUC__) -# define GNU_ATT_SYNTAX ".att_syntax prefix;" -# define GNU_INTEL_SYNTAX ".intel_syntax noprefix;" +# define GNU_AS_ATT_SYNTAX ".att_syntax prefix;" +# define GNU_AS_INTEL_SYNTAX ".intel_syntax noprefix;" #else -# define GNU_ATT_SYNTAX ".att_syntax prefix;" -# define GNU_INTEL_SYNTAX ".intel_syntax noprefix;" +# define GNU_AS_ATT_SYNTAX ".att_syntax prefix;" +# define GNU_AS_INTEL_SYNTAX ".intel_syntax noprefix;" #endif #define IF0(y) diff --git a/integer.cpp b/integer.cpp index 1ebf788b..6da90e7e 100644 --- a/integer.cpp +++ b/integer.cpp @@ -538,7 +538,7 @@ int Baseline_Add(size_t N, word *C, const word *A, const word *B) word result; __asm__ __volatile__ ( - ".intel_syntax;" + ".intel_syntax;" "\n" AS1( neg %1) ASJ( jz, 1, f) AS2( mov %0,[%3+8*%1]) @@ -557,7 +557,7 @@ int Baseline_Add(size_t N, word *C, const word *A, const word *B) ASL(1) AS2( mov %0, 0) AS2( adc %0, %0) - ".att_syntax;" + ".att_syntax;" "\n" : "=&r" (result), "+c" (N) : "r" (C+N), "r" (A+N), "r" (B+N) : "memory", "cc" @@ -589,12 +589,12 @@ int Baseline_Sub(size_t N, word *C, const word *A, const word *B) ASL(1) AS2( mov %0, 0) AS2( adc %0, %0) - ".att_syntax;" + ".att_syntax;" "\n" : "=&r" (result), "+c" (N) : "r" (C+N), "r" (A+N), "r" (B+N) : "memory", "cc" ); - return (int)result; + return static_cast(result); } #elif defined(CRYPTOPP_X86_ASM_AVAILABLE) && CRYPTOPP_BOOL_X86 CRYPTOPP_NAKED int CRYPTOPP_FASTCALL Baseline_Add(size_t N, word *C, const word *A, const word *B) @@ -2978,10 +2978,8 @@ static Integer StringToInteger(const T *str) unsigned int length; for (length = 0; str[length] != 0; length++) {} - Integer v; - if (length == 0) - return v; + return Integer::Zero(); switch (str[length-1]) { @@ -3002,8 +3000,12 @@ static Integer StringToInteger(const T *str) } if (length > 2 && str[0] == '0' && str[1] == 'x') + { radix = 16; + str += 2, length -= 2; + } + Integer v; for (unsigned i=0; i