-
Notifications
You must be signed in to change notification settings - Fork 710
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cpu feature detection #392
Changes from 12 commits
b1fb0a5
52eca58
f7e046d
e8e1253
aaaa73b
7b6ac18
cae8c11
9ad928a
e914243
042b8cb
ce050f9
0843d84
97f0261
dfb508a
4db4eb8
1695809
71667e6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
#include <openssl/cpu.h> | ||
|
||
#ifdef __linux__ | ||
unsigned long getauxval_wrapper(unsigned long type, char *success) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's use this signature: int getauxval_wrapper(unsigned long type, unsigned long *out_value) { The idea is that success/failure is indicated by the return value and the output value is made an out parameter. This is consistent with other stuff in ring and BoringSSL. I suggest we document this function's return value: It returns 1 if I think it's also good to document that this is a workaround for the fact that weak symbols aren't supported well in (stable) Rust. |
||
if (getauxval == NULL) { | ||
*success = 0; | ||
return 0; | ||
} | ||
|
||
unsigned long result = getauxval(type); | ||
if (errno != 0) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. AFAIU, it isn't legal to check There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree, this is weird, and felt wrong even with my pretty rusty C. Unfortunately, 0 is a valid value, so the original
This is the implementation in glibc's
They also have
I took this to mean we should check errno. https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=6619179 seems to agree that while regrettable, this is how it has to be done when every possible return value is potentially valid. Thoughts? |
||
*success = 0; | ||
return 0; | ||
} | ||
|
||
*success = 1; | ||
return result; | ||
} | ||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -70,6 +70,16 @@ extern "C" { | |
|
||
/* Runtime CPU feature support */ | ||
|
||
#ifdef __linux__ | ||
|
||
/* |getauxval| is not available on Android until API level 20. Link it as a weak | ||
* symbol and use other methods as fallback. */ | ||
unsigned long getauxval(unsigned long type) __attribute__((weak)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I couldn't figure out how to make weak linkage work on macOS's compiler toolchain, so this and all tests that hit the C bits are linux-only unfortunately. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's OK. These are really Linux-specific and ARM-specific anyway, AFAICT. However, let's just put this declaration in cpu-arm-linux.c. There's no reason for it to be in a header file, especially these "public" header files. |
||
|
||
#include <errno.h> | ||
unsigned long getauxval_wrapper(unsigned long type, char *success); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
/* Prevent -Wmissing-prototypes warnings. */
unsigned long getauxval_wrapper(unsigned long type, char *success); So, basically, move these to cpu-arm-linux.c. |
||
|
||
#endif | ||
|
||
#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) | ||
/* GFp_ia32cap_P contains the Intel CPUID bits when running on an x86 or | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,7 +45,7 @@ macro_rules! define_metrics_tests { | |
// We can't use `size_t` because we need to test that our | ||
// definition of `size_t` is correct using this code! We use `u16` | ||
// because even 8-bit and 16-bit microcontrollers have no trouble | ||
// with it, and because `u16` is always as smaller or smaller than | ||
// with it, and because `u16` is always as small as or smaller than | ||
// `usize`. | ||
static $c_align: u16; | ||
static $c_size: u16; | ||
|
@@ -91,7 +91,6 @@ define_type!(long, i32, test_long_metrics, GFp_long_align, GFp_long_size, | |
define_type!(long, i64, test_long_metrics, GFp_long_align, GFp_long_size, | ||
"The C `long` type. Equivalent to `libc::c_long`."); | ||
|
||
|
||
define_type!( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems like a spurious change that should be undone or done in a separate commit specific to fixing formatting. |
||
size_t, usize, test_size_t_metrics, GFp_size_t_align, GFp_size_t_size, | ||
"The C `size_t` type from `<stdint.h>`. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The internet claims this is the most widely portable flavor of
#define
for linux. Unfortunately there doesn't seem to be a "only glibc" define, but even if we had that we'd still have to deal with the weak linkage anyway...There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that seems right to me. However, I'd prefer to keep this in the cpu-arm-linux.c file, since it really is specific to ARM Linux.