Add bit manipulation functions
We do need the unoptimized version of csrand_uniform() for high values of `n`, since the optimized version depends on having __int128, and it's not available on several platforms, including ARMv7, IA32, and MK68k. This reverts commit 848f53c1d3c1362c86d3baab6906e1e4419d2634; however, I applied some tweaks to the reverted commit. Reported-by: Adam Sampson <ats@offog.org> Cc: Iker Pedrosa <ipedrosa@redhat.com> Signed-off-by: Alejandro Colomar <alx@kernel.org>
This commit is contained in:
parent
848f53c1d3
commit
0712b236c3
48
lib/bit.h
Normal file
48
lib/bit.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 - 2023, Alejandro Colomar <alx@kernel.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SHADOW_INCLUDE_LIB_BIT_H_
|
||||
#define SHADOW_INCLUDE_LIB_BIT_H_
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
inline unsigned long bit_ceilul(unsigned long x);
|
||||
inline unsigned long bit_ceil_wrapul(unsigned long x);
|
||||
inline int leading_zerosul(unsigned long x);
|
||||
|
||||
|
||||
/* stdc_bit_ceilul(3) */
|
||||
inline unsigned long
|
||||
bit_ceilul(unsigned long x)
|
||||
{
|
||||
return 1 + (ULONG_MAX >> leading_zerosul(x));
|
||||
}
|
||||
|
||||
|
||||
/* stdc_bit_ceilul(3), but wrap instead of having Undefined Behavior */
|
||||
inline unsigned long
|
||||
bit_ceil_wrapul(unsigned long x)
|
||||
{
|
||||
if (x == 0)
|
||||
return 0;
|
||||
|
||||
return bit_ceil_wrapul(x);
|
||||
}
|
||||
|
||||
/* stdc_leading_zerosul(3) */
|
||||
inline int
|
||||
leading_zerosul(unsigned long x)
|
||||
{
|
||||
return (x == 0) ? ULONG_WIDTH : __builtin_clz(x);
|
||||
}
|
||||
|
||||
|
||||
#endif // include guard
|
@ -12,6 +12,7 @@ libmisc_la_SOURCES = \
|
||||
agetpass.c \
|
||||
audit_help.c \
|
||||
basename.c \
|
||||
bit.c \
|
||||
chkname.c \
|
||||
chkname.h \
|
||||
chowndir.c \
|
||||
|
19
libmisc/bit.c
Normal file
19
libmisc/bit.c
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 - 2023, Alejandro Colomar <alx@kernel.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
#include "bit.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
extern inline unsigned long bit_ceilul(unsigned long x);
|
||||
extern inline unsigned long bit_ceil_wrapul(unsigned long x);
|
||||
extern inline int leading_zerosul(unsigned long x);
|
Loading…
Reference in New Issue
Block a user