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 zfsonlinux/zfs#2505
Closes #488
This commit is contained in:
Jason Zaman 2015-10-24 14:15:58 +08:00 committed by Brian Behlendorf
parent f5f2b87df0
commit 8fc851b7b5
1 changed files with 2 additions and 2 deletions

View File

@ -186,7 +186,7 @@ extern void spl_cleanup(void);
*/ */
#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 P2PHASE(x, align) ((x) & ((align) - 1)) #define P2PHASE(x, align) ((x) & ((align) - 1))
#define P2NPHASE(x, align) (-(x) & ((align) - 1)) #define P2NPHASE(x, align) (-(x) & ((align) - 1))
#define ISP2(x) (((x) & ((x) - 1)) == 0) #define ISP2(x) (((x) & ((x) - 1)) == 0)
@ -213,7 +213,7 @@ extern void spl_cleanup(void);
#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) \