support gcc 5 builtins for multiplication overflow in safemult.h
fix copypasted comment in fmt_asn1dertag add man pages for add_of, sub_of and assign
This commit is contained in:
parent
6cfc16fc40
commit
fb1f19042f
@ -3,7 +3,7 @@
|
||||
/* write int in least amount of bytes, return number of bytes */
|
||||
/* as used in ASN.1 DER tag */
|
||||
size_t fmt_asn1dertag(char* dest,unsigned long long l) {
|
||||
/* encoding is either l%128 or (0x80+number of bytes,bytes) */
|
||||
/* high bit says if more bytes are coming, lower 7 bits are payload; big endian */
|
||||
size_t n=0,i;
|
||||
unsigned long long t;
|
||||
for (t=l, n=1; t>0x7f; t>>=7) ++n;
|
||||
|
21
mult/add_of.3
Normal file
21
mult/add_of.3
Normal file
@ -0,0 +1,21 @@
|
||||
.TH add_of 3
|
||||
.SH NAME
|
||||
add_of \- add two integers, check for arithmetic overflow
|
||||
.SH SYNTAX
|
||||
.B #include <rangecheck.h>
|
||||
|
||||
int \fBadd_of\fP(dest,a,b);
|
||||
.SH DESCRIPTION
|
||||
If calculating a+b is possible without causing undefined behavior or an
|
||||
arithmetic overflow in C, and the sum fits into the destination integer
|
||||
type, do dest=a+b and return 0.
|
||||
|
||||
Otherwise, return 1.
|
||||
|
||||
Note: This is a macro, so dest does not have to be a pointer.
|
||||
.SH BUGS
|
||||
In the multiplication functions, a return value of 1 signals success and
|
||||
0 failure. In add_of, sub_of and assign it's the other way around.
|
||||
.SH "SEE ALSO"
|
||||
sub_of(3), assign(3), imult16(3), umult16(3), imult32(3), umult32(3),
|
||||
imult64(3), umult64(3)
|
20
mult/assign.3
Normal file
20
mult/assign.3
Normal file
@ -0,0 +1,20 @@
|
||||
.TH assign 3
|
||||
.SH NAME
|
||||
assign \- assign an integer value, check for truncation
|
||||
.SH SYNTAX
|
||||
.B #include <rangecheck.h>
|
||||
|
||||
int \fBassign\fP(dest,a);
|
||||
.SH DESCRIPTION
|
||||
If a and dest have the same type, or the value of a is representable in
|
||||
the type of dest, do dest=a and return 0.
|
||||
|
||||
Otherwise, return 1.
|
||||
|
||||
Note: This is a macro, so dest does not have to be a pointer.
|
||||
.SH BUGS
|
||||
In the multiplication functions, a return value of 1 signals success and
|
||||
0 failure. In add_of, sub_of and assign it's the other way around.
|
||||
.SH "SEE ALSO"
|
||||
add_of(3), sub_of(3), imult16(3), umult16(3), imult32(3), umult32(3),
|
||||
imult64(3), umult64(3)
|
@ -1,3 +1,11 @@
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 5)
|
||||
|
||||
#include "uint16.h"
|
||||
|
||||
int imult16( int16 a, int16 b, int16* c) { return !__builtin_mul_overflow(a,b,c); }
|
||||
|
||||
#else
|
||||
|
||||
#include "safemult.h"
|
||||
|
||||
int imult16(int16 a,int16 b,int16* c) {
|
||||
@ -6,3 +14,5 @@ int imult16(int16 a,int16 b,int16* c) {
|
||||
*c=x;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,3 +1,11 @@
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 5)
|
||||
|
||||
#include "uint32.h"
|
||||
|
||||
int imult32( int32 a, int32 b, int32* c) { return !__builtin_mul_overflow(a,b,c); }
|
||||
|
||||
#else
|
||||
|
||||
#include "safemult.h"
|
||||
|
||||
int imult32(int32 a,int32 b,int32* c) {
|
||||
@ -6,3 +14,5 @@ int imult32(int32 a,int32 b,int32* c) {
|
||||
*c=x;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,3 +1,11 @@
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 5)
|
||||
|
||||
#include "uint64.h"
|
||||
|
||||
int imult64( int64 a, int64 b, int64* c) { return !__builtin_mul_overflow(a,b,c); }
|
||||
|
||||
#else
|
||||
|
||||
#if defined(__x86_64__) && defined(__OPTIMIZE__)
|
||||
|
||||
/* WARNING: this only works if compiled with -fomit-frame-pointer */
|
||||
@ -46,3 +54,5 @@ int imult64(int64 a,int64 b,int64* c) {
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
21
mult/sub_of.3
Normal file
21
mult/sub_of.3
Normal file
@ -0,0 +1,21 @@
|
||||
.TH sub_of 3
|
||||
.SH NAME
|
||||
sub_of \- subtract two integers, check for arithmetic overflow
|
||||
.SH SYNTAX
|
||||
.B #include <rangecheck.h>
|
||||
|
||||
int \fBsub_of\fP(dest,a,b);
|
||||
.SH DESCRIPTION
|
||||
If calculating a-b is possible without causing undefined behavior or an
|
||||
arithmetic overflow in C, and the result fits into the destination
|
||||
integer type, do dest=a-b and return 0.
|
||||
|
||||
Otherwise, return 1.
|
||||
|
||||
Note: This is a macro, so dest does not have to be a pointer.
|
||||
.SH BUGS
|
||||
In the multiplication functions, a return value of 1 signals success and
|
||||
0 failure. In add_of, sub_of and assign it's the other way around.
|
||||
.SH "SEE ALSO"
|
||||
add_of(3), assign(3), imult16(3), umult16(3), imult32(3), umult32(3),
|
||||
imult64(3), umult64(3)
|
@ -1,3 +1,11 @@
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 5)
|
||||
|
||||
#include "uint16.h"
|
||||
|
||||
int umult16(uint16 a,uint16 b,uint16* c) { return !__builtin_mul_overflow(a,b,c); }
|
||||
|
||||
#else
|
||||
|
||||
#include "safemult.h"
|
||||
|
||||
int umult16(uint16 a,uint16 b,uint16* c) {
|
||||
@ -6,3 +14,5 @@ int umult16(uint16 a,uint16 b,uint16* c) {
|
||||
*c=x&0xffff;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,3 +1,11 @@
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 5)
|
||||
|
||||
#include "uint32.h"
|
||||
|
||||
int umult32(uint32 a,uint32 b,uint32* c) { return !__builtin_mul_overflow(a,b,c); }
|
||||
|
||||
#else
|
||||
|
||||
#include "safemult.h"
|
||||
|
||||
int umult32(uint32 a,uint32 b,uint32* c) {
|
||||
@ -6,3 +14,5 @@ int umult32(uint32 a,uint32 b,uint32* c) {
|
||||
*c=x&0xffffffff;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,3 +1,11 @@
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 5)
|
||||
|
||||
#include "uint64.h"
|
||||
|
||||
int umult64(uint64 a,uint64 b,uint64* c) { return !__builtin_mul_overflow(a,b,c); }
|
||||
|
||||
#else
|
||||
|
||||
#include "haveuint128.h"
|
||||
|
||||
#if defined(__x86_64__) && defined(__OPTIMIZE__)
|
||||
@ -60,3 +68,5 @@ int umult64(uint64 a,uint64 b,uint64* c) {
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
18
safemult.h
18
safemult.h
@ -10,6 +10,22 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 5)
|
||||
|
||||
/* for historical reasons, the mult interface uses 0 for failure and 1
|
||||
* for success, while the builtins (and my own addition and
|
||||
* subtraction routines in rangecheck.h) do it the other way around. */
|
||||
extern inline int umult16(uint16 a,uint16 b,uint16* c) { return !__builtin_mul_overflow(a,b,c); }
|
||||
extern inline int imult16( int16 a, int16 b, int16* c) { return !__builtin_mul_overflow(a,b,c); }
|
||||
|
||||
extern inline int umult32(uint32 a,uint32 b,uint32* c) { return !__builtin_mul_overflow(a,b,c); }
|
||||
extern inline int imult32( int32 a, int32 b, int32* c) { return !__builtin_mul_overflow(a,b,c); }
|
||||
|
||||
extern inline int umult64(uint64 a,uint64 b,uint64* c) { return !__builtin_mul_overflow(a,b,c); }
|
||||
extern inline int imult64( int64 a, int64 b, int64* c) { return !__builtin_mul_overflow(a,b,c); }
|
||||
|
||||
#else
|
||||
|
||||
/* return 0 for overflow, 1 for ok */
|
||||
int umult16(uint16 a,uint16 b,uint16* c);
|
||||
int imult16( int16 a, int16 b, int16* c);
|
||||
@ -20,6 +36,8 @@ int imult32( int32 a, int32 b, int32* c);
|
||||
int umult64(uint64 a,uint64 b,uint64* c);
|
||||
int imult64( int64 a, int64 b, int64* c);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user