Coverage Report

Created: 2026-02-14 06:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/blst/src/cpuid.c
Line
Count
Source
1
/*
2
 * Copyright Supranational LLC
3
 * Licensed under the Apache License, Version 2.0, see LICENSE for details.
4
 * SPDX-License-Identifier: Apache-2.0
5
 */
6
7
#if (defined(__GNUC__) || defined(__clang__) || defined(__SUNPRO_C)) && !defined(_WIN32)
8
__attribute__((visibility("hidden")))
9
#endif
10
int __blst_platform_cap = 0;
11
12
#if defined(__x86_64__) || defined(__x86_64) || (defined(_M_X64) && !defined(_M_ARM64EC))
13
14
# if defined(__GNUC__) || defined(__clang__) || defined(__SUNPRO_C)
15
static void __cpuidex(int info[4], int func, int sub)
16
4
{
17
4
    int eax, ebx, ecx, edx;
18
19
4
    __asm__("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx)
20
4
                    : "a"(func), "c"(sub));
21
22
4
    info[0] = eax;
23
4
    info[1] = ebx;
24
4
    info[2] = ecx;
25
4
    info[3] = edx;
26
4
}
27
# else
28
#  include <intrin.h>
29
# endif
30
31
# if defined(__GNUC__) || defined(__clang__)
32
__attribute__((constructor))
33
# endif
34
static int __blst_cpuid(void)
35
2
{
36
2
    int info[4], cap = 0;
37
38
2
    __cpuidex(info, 0, 0);
39
2
    if (info[0] > 6) {
40
2
        __cpuidex(info, 7, 0);
41
2
        cap |= (info[1]>>19) & 1; /* ADX */
42
2
        cap |= (info[1]>>28) & 2; /* SHA */
43
2
    }
44
45
2
    __blst_platform_cap = cap;
46
47
2
    return 0;
48
2
}
49
50
# if defined(_MSC_VER) && !defined(__clang__) && !defined(__BLST_DLL_MAIN__)
51
#  pragma section(".CRT$XCU",read)
52
__declspec(allocate(".CRT$XCU")) static int (*p)(void) = __blst_cpuid;
53
# elif defined(__SUNPRO_C)
54
#  pragma init(__blst_cpuid)
55
# endif
56
57
#elif defined(__aarch64__) || defined(__aarch64) || defined(_M_ARM64) || defined(_M_ARM64EC)
58
59
# if defined(__linux__) && (defined(__GNUC__) || defined(__clang__))
60
extern unsigned long getauxval(unsigned long type) __attribute__ ((weak));
61
62
__attribute__((constructor))
63
static int __blst_cpuid(void)
64
{
65
    int cap = 0;
66
67
    if (getauxval) {
68
        unsigned long hwcap_ce = getauxval(16);
69
        cap = (hwcap_ce>>6) & 1; /* SHA256 */
70
    }
71
72
    __blst_platform_cap = cap;
73
74
    return 0;
75
}
76
# elif defined(__APPLE__) && (defined(__GNUC__) || defined(__clang__))
77
__attribute__((constructor))
78
static int __blst_cpuid()
79
{
80
    __blst_platform_cap = 1; /* SHA256 */
81
    return 0;
82
}
83
# elif defined(__FreeBSD__) && __FreeBSD__ >= 12
84
#  include <sys/auxv.h>
85
__attribute__((constructor))
86
static int __blst_cpuid()
87
{
88
    unsigned long cap;
89
90
    if (elf_aux_info(AT_HWCAP, &cap, sizeof(cap)) == 0)
91
        __blst_platform_cap = (cap & HWCAP_SHA2) != 0;
92
93
    return 0;
94
}
95
# elif defined(_WIN64)
96
int IsProcessorFeaturePresent(int);
97
98
#  if defined(__GNUC__) || defined(__clang__)
99
__attribute__((constructor))
100
#  endif
101
static int __blst_cpuid(void)
102
{
103
    __blst_platform_cap = IsProcessorFeaturePresent(30); /* AES, SHA1, SHA2 */
104
105
    return 0;
106
}
107
108
#  if defined(_MSC_VER) && !defined(__clang__) && !defined(__BLST_DLL_MAIN__)
109
#   pragma section(".CRT$XCU",read)
110
__declspec(allocate(".CRT$XCU")) static int (*p)(void) = __blst_cpuid;
111
#  endif
112
# endif
113
114
#endif
115
116
#if defined(_WIN64) && defined(__BLST_DLL_MAIN__)
117
# define IsProcessorFeaturePresent mask_IsProcessorFeaturePresent
118
# define WIN32_LEAN_AND_MEAN
119
# include <windows.h>
120
121
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
122
{
123
    if (dwReason == DLL_PROCESS_ATTACH) {
124
        DisableThreadLibraryCalls(hinstDLL);
125
        __blst_cpuid();
126
    }
127
128
    return TRUE;
129
130
    (void)lpvReserved;
131
}
132
133
# if defined(_MSC_VER)
134
/*
135
 * Even though we don't have memcpy/memset anywhere, MSVC compiler
136
 * generates calls to them as it recognizes corresponding patterns.
137
 */
138
#pragma function(memcpy)
139
void *memcpy(unsigned char *dst, const unsigned char *src, size_t n)
140
{
141
    void *ret = dst;
142
143
    while(n--)
144
        *dst++ = *src++;
145
146
    return ret;
147
}
148
149
#pragma function(memset)
150
void *memset(unsigned char *dst, int c, size_t n)
151
{
152
    void *ret = dst;
153
154
    while(n--)
155
        *dst++ = (unsigned char)c;
156
157
    return ret;
158
}
159
# endif
160
#endif