Xi Wang

$ alias cd='rm -rf'

Libo 0.1 Released

Permalink

Just tagged libo 0.1, a library for fast integer overflow detection.

The major interface change in this version is that instead of writing smulo32(...) for detecting signed 32-bit multiplication overflow, you just call overflow_mul(...), and it will figure out the type for you (using black magic).

I have also added a unit test using Google Test. It would be great if you can help generate and test ARM/PowerPC implementations.

To give you a sense of how efficient libo is, below is libo’s implementation of overflow_mul() for long on x86_64:

overflow_mul_l:
imulq %rdx, %rsi
movq %rsi, (%rdi)
seto %al
ret

on ppc:

overflow_mul_l:
mullw 6, 4, 5
stw 6, 0(3)
mulhw 3, 4, 5
srawi 4, 6, 31
xor 3, 3, 4
addic 4, 3, -1
subfe 3, 4, 3
blr

For a comparison, this is the implementation from CERT’s IntegerLib.

#if (LLONG_MAX >= 2*LONG_MAX)
signed long multsl(signed long lhs, signed long rhs){
signed long long tmp = (signed long long)lhs * (signed long long)rhs;
errno = 0;
if ( (tmp > LONG_MAX) || (tmp < LONG_MIN)){
error_handler("OVERFLOW ERROR", NULL, EOVERFLOW);
errno = EINVAL;
}
return (signed long)tmp;
}
#else
signed long multsl(signed long lhs, signed long rhs){
errno = 0;
if ( (lhs == 0) || (rhs == 0)) return 0;
if( lhs > 0){
if( rhs > 0){
if(lhs > (LONG_MAX / rhs)){
error_handler("OVERFLOW ERROR", NULL, EOVERFLOW);
errno = EINVAL;
}
} else {
if ( rhs < (LONG_MIN / lhs)){
error_handler("OVERFLOW ERROR", NULL, EOVERFLOW);
errno = EINVAL;
}
}
} else {
if(rhs > 0){
if( lhs < (LONG_MIN / rhs)){
error_handler("OVERFLOW ERROR", NULL, EOVERFLOW);
errno = EINVAL;
}
} else {
if( (lhs != 0) && (rhs < (LONG_MAX / lhs))){
error_handler("OVERFLOW ERROR", NULL, EOVERFLOW);
errno = EINVAL;
}
}
}
return lhs * rhs;
}
#endif /* LLONG_MAX >= 2*LONG_MAX */

Comments