sysmacros: Make P2ROUNDUP not trigger int overflow

The original P2ROUNDUP and P2ROUNDUP_TYPED macros contain -x which
triggers PaX's integer overflow detection for unsigned integers.
Replace the macros with an equivalent version that does not trigger
the overflow.

Axioms:
A. (-(x)) === (~((x) - 1)) === (~(x) + 1) under two's complement.
B. ~(x & y) === ((~(x)) | (~(y))) under De Morgan's law.
C. ~(~x) === x under the law of excluded middle.

Proof:
0. (-(-(x) & -(align))) original
1. (~(-(x) & -(align)) + 1) by A
2. (((~(-(x))) | (~(-(align)))) + 1) by B
3. (((~(~((x) - 1))) | (~(~((align) - 1)))) + 1) by A
4. (((((x) - 1)) | (((align) - 1))) + 1) by C
Q.E.D.

Signed-off-by: Jason Zaman <jason@perfinion.com>
Reviewed-by: Chris Dunlop <chris@onthe.net.au>
Reviewed-by: Richard Yao <ryao@gentoo.org>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #3949
This commit is contained in:
Jason Zaman 2015-10-24 14:01:08 +08:00 committed by Brian Behlendorf
parent 27a19a0d5a
commit 5c790678f1

View File

@ -49,9 +49,7 @@
*/ */
#define P2ALIGN(x, align) ((x) & -(align)) #define P2ALIGN(x, align) ((x) & -(align))
#define P2CROSS(x, y, align) (((x) ^ (y)) > (align) - 1) #define P2CROSS(x, y, align) (((x) ^ (y)) > (align) - 1)
#define P2ROUNDUP(x, align) (-(-(x) & -(align))) #define P2ROUNDUP(x, align) ((((x) - 1) | ((align) - 1)) + 1)
#define P2ROUNDUP_TYPED(x, align, type) \
(-(-(type)(x) & -(type)(align)))
#define P2BOUNDARY(off, len, align) \ #define P2BOUNDARY(off, len, align) \
(((off) ^ ((off) + (len) - 1)) > (align) - 1) (((off) ^ ((off) + (len) - 1)) > (align) - 1)
#define P2PHASE(x, align) ((x) & ((align) - 1)) #define P2PHASE(x, align) ((x) & ((align) - 1))
@ -79,7 +77,7 @@
#define P2NPHASE_TYPED(x, align, type) \ #define P2NPHASE_TYPED(x, align, type) \
(-(type)(x) & ((type)(align) - 1)) (-(type)(x) & ((type)(align) - 1))
#define P2ROUNDUP_TYPED(x, align, type) \ #define P2ROUNDUP_TYPED(x, align, type) \
(-(-(type)(x) & -(type)(align))) ((((type)(x) - 1) | ((type)(align) - 1)) + 1)
#define P2END_TYPED(x, align, type) \ #define P2END_TYPED(x, align, type) \
(-(~(type)(x) & -(type)(align))) (-(~(type)(x) & -(type)(align)))
#define P2PHASEUP_TYPED(x, align, phase, type) \ #define P2PHASEUP_TYPED(x, align, phase, type) \