Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause 2 : : * Copyright 2018 Red Hat, Inc. 3 : : */ 4 : : 5 : : #include <elf.h> 6 : : #include <fcntl.h> 7 : : #include <string.h> 8 : : #include <unistd.h> 9 : : 10 : : #if defined(__GLIBC__) && defined(__GLIBC_PREREQ) 11 : : #if __GLIBC_PREREQ(2, 16) 12 : : #include <sys/auxv.h> 13 : : #define HAS_AUXV 1 14 : : #endif 15 : : #endif 16 : : 17 : : #include <rte_cpuflags.h> 18 : : 19 : : #ifndef HAS_AUXV 20 : : static unsigned long 21 : : getauxval(unsigned long type __rte_unused) 22 : : { 23 : : errno = ENOTSUP; 24 : : return 0; 25 : : } 26 : : #endif 27 : : 28 : : #ifdef RTE_ARCH_64 29 : : typedef Elf64_auxv_t Internal_Elfx_auxv_t; 30 : : #else 31 : : typedef Elf32_auxv_t Internal_Elfx_auxv_t; 32 : : #endif 33 : : 34 : : /** 35 : : * Provides a method for retrieving values from the auxiliary vector and 36 : : * possibly running a string comparison. 37 : : * 38 : : * @return Always returns a result. When the result is 0, check errno 39 : : * to see if an error occurred during processing. 40 : : */ 41 : : static unsigned long 42 : 0 : _rte_cpu_getauxval(unsigned long type, const char *str) 43 : : { 44 : : unsigned long val; 45 : : 46 : 0 : errno = 0; 47 : 0 : val = getauxval(type); 48 : : 49 [ # # # # ]: 0 : if (!val && (errno == ENOTSUP || errno == ENOENT)) { 50 : : int auxv_fd = open("/proc/self/auxv", O_RDONLY); 51 : : Internal_Elfx_auxv_t auxv; 52 : : 53 [ # # ]: 0 : if (auxv_fd == -1) 54 : 0 : return 0; 55 : : 56 : 0 : errno = ENOENT; 57 [ # # ]: 0 : while (read(auxv_fd, &auxv, sizeof(auxv)) == sizeof(auxv)) { 58 [ # # ]: 0 : if (auxv.a_type == type) { 59 : 0 : errno = 0; 60 : 0 : val = auxv.a_un.a_val; 61 [ # # ]: 0 : if (str) 62 : 0 : val = strcmp((const char *)val, str); 63 : : break; 64 : : } 65 : : } 66 : 0 : close(auxv_fd); 67 : : } 68 : : 69 : : return val; 70 : : } 71 : : 72 : : unsigned long 73 : 0 : rte_cpu_getauxval(unsigned long type) 74 : : { 75 : 0 : return _rte_cpu_getauxval(type, NULL); 76 : : } 77 : : 78 : : int 79 : 0 : rte_cpu_strcmp_auxval(unsigned long type, const char *str) 80 : : { 81 : 0 : return _rte_cpu_getauxval(type, str); 82 : : }