Add an OPENSSL_ia32cap_get() function for C code.
OPENSSL_ia32cap_addr avoids any relocations within the module, at the cost of a runtime TEXTREL, which causes problems in some cases. (Notably, if someone links us into a binary which uses the GCC "ifunc" attribute, the loader crashes.) Fix C references of OPENSSL_ia32cap_addr with a function. This is analogous to the BSS getters. A follow-up commit will fix perlasm with a different scheme which avoids calling into a function (clobbering registers and complicating unwind directives.) Change-Id: I09d6cda4cec35b693e16b5387611167da8c7a6de Reviewed-on: https://boringssl-review.googlesource.com/15525 Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
parent
a5237972fa
commit
91871018a4
@ -169,6 +169,10 @@ func transform(lines []string, symbols map[string]bool) (ret []string) {
|
||||
// referenced and thus needs to be emitted outside the module.
|
||||
ia32capAddrNeeded := false
|
||||
|
||||
// ia32capGetNeeded is true iff OPENSSL_ia32cap_get has been referenced
|
||||
// and thus needs to be emitted outside the module.
|
||||
ia32capGetNeeded := false
|
||||
|
||||
// bssAccessorsNeeded maps the names of BSS variables for which
|
||||
// accessor functions need to be emitted outside of the module, to the
|
||||
// BSS symbols they point to. For example, “EVP_sha256_once” could map
|
||||
@ -188,11 +192,6 @@ func transform(lines []string, symbols map[string]bool) (ret []string) {
|
||||
break
|
||||
}
|
||||
|
||||
// References to OPENSSL_ia32cap_P via the GOT result from C
|
||||
// code. The OPENSSL_ia32cap_addr symbol, generated by this
|
||||
// script, is just like a GOT entry, but at a known offset.
|
||||
line = strings.Replace(line, "OPENSSL_ia32cap_P@GOTPCREL(%rip)", "OPENSSL_ia32cap_addr(%rip)", -1)
|
||||
|
||||
if referencesIA32CapDirectly(line) {
|
||||
panic("reference to OPENSSL_ia32cap_P needs to be changed to indirect via OPENSSL_ia32cap_addr")
|
||||
}
|
||||
@ -201,6 +200,10 @@ func transform(lines []string, symbols map[string]bool) (ret []string) {
|
||||
ia32capAddrNeeded = true
|
||||
}
|
||||
|
||||
if strings.Contains(line, "OPENSSL_ia32cap_get@PLT") {
|
||||
ia32capGetNeeded = true
|
||||
}
|
||||
|
||||
line = strings.Replace(line, "@PLT", "", -1)
|
||||
parts := strings.Fields(strings.TrimSpace(line))
|
||||
|
||||
@ -393,6 +396,14 @@ func transform(lines []string, symbols map[string]bool) (ret []string) {
|
||||
ret = append(ret, "\tret")
|
||||
}
|
||||
|
||||
// Emit an OPENSSL_ia32cap_get accessor.
|
||||
if ia32capGetNeeded {
|
||||
ret = append(ret, ".type OPENSSL_ia32cap_get, @function")
|
||||
ret = append(ret, "OPENSSL_ia32cap_get:")
|
||||
ret = append(ret, "\tleaq OPENSSL_ia32cap_P(%rip), %rax")
|
||||
ret = append(ret, "\tret")
|
||||
}
|
||||
|
||||
// Emit an indirect reference to OPENSSL_ia32cap_P.
|
||||
if ia32capAddrNeeded {
|
||||
ret = append(ret, ".extern OPENSSL_ia32cap_P")
|
||||
|
@ -365,7 +365,7 @@ void CRYPTO_ghash_init(gmult_func *out_mult, ghash_func *out_hash,
|
||||
|
||||
#if defined(GHASH_ASM_X86_64)
|
||||
if (crypto_gcm_clmul_enabled()) {
|
||||
if (((OPENSSL_ia32cap_P[1] >> 22) & 0x41) == 0x41) { /* AVX+MOVBE */
|
||||
if (((OPENSSL_ia32cap_get()[1] >> 22) & 0x41) == 0x41) { /* AVX+MOVBE */
|
||||
gcm_init_avx(out_table, H.u);
|
||||
*out_mult = gcm_gmult_avx;
|
||||
*out_hash = gcm_ghash_avx;
|
||||
@ -1064,8 +1064,9 @@ void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len) {
|
||||
#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
|
||||
int crypto_gcm_clmul_enabled(void) {
|
||||
#ifdef GHASH_ASM
|
||||
return (OPENSSL_ia32cap_P[0] & (1 << 24)) && /* check FXSR bit */
|
||||
(OPENSSL_ia32cap_P[1] & (1 << 1)); /* check PCLMULQDQ bit */
|
||||
const uint32_t *ia32cap = OPENSSL_ia32cap_get();
|
||||
return (ia32cap[0] & (1 << 24)) && /* check FXSR bit */
|
||||
(ia32cap[1] & (1 << 1)); /* check PCLMULQDQ bit */
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
@ -82,7 +82,7 @@ extern int CRYPTO_rdrand(uint8_t out[8]);
|
||||
extern int CRYPTO_rdrand_multiple8_buf(uint8_t *buf, size_t len);
|
||||
|
||||
static int have_rdrand(void) {
|
||||
return (OPENSSL_ia32cap_P[1] & (1u << 30)) != 0;
|
||||
return (OPENSSL_ia32cap_get()[1] & (1u << 30)) != 0;
|
||||
}
|
||||
|
||||
static int hwrand(uint8_t *buf, size_t len) {
|
||||
|
@ -91,6 +91,15 @@ extern "C" {
|
||||
* Note: the CPUID bits are pre-adjusted for the OSXSAVE bit and the YMM and XMM
|
||||
* bits in XCR0, so it is not necessary to check those. */
|
||||
extern uint32_t OPENSSL_ia32cap_P[4];
|
||||
|
||||
#if defined(BORINGSSL_FIPS)
|
||||
const uint32_t *OPENSSL_ia32cap_get(void);
|
||||
#else
|
||||
static inline const uint32_t *OPENSSL_ia32cap_get(void) {
|
||||
return OPENSSL_ia32cap_P;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
|
||||
|
Loading…
Reference in New Issue
Block a user