forked from OSchip/llvm-project
[scudo] getauxval alternative for Android
Summary: `getauxval` was introduced with API level 18. In order to get things to work at lower API levels (for the toolchain itself which is built at 14 for 32-bit), we introduce an alternative implementation reading directly from `/proc/self/auxv`. Reviewers: alekseyshl Reviewed By: alekseyshl Subscribers: srhines, llvm-commits Differential Revision: https://reviews.llvm.org/D37488 llvm-svn: 312653
This commit is contained in:
parent
a353d9cb18
commit
6bc7b26d18
|
@ -13,15 +13,47 @@
|
|||
|
||||
#include "scudo_utils.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include "sanitizer_common/sanitizer_posix.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
# include <cpuid.h>
|
||||
#endif
|
||||
#if defined(__arm__) || defined(__aarch64__)
|
||||
# include <sys/auxv.h>
|
||||
# if SANITIZER_ANDROID && __ANDROID_API__ < 18
|
||||
// getauxval() was introduced with API level 18 on Android. Emulate it using
|
||||
// /proc/self/auxv for lower API levels.
|
||||
# include <fcntl.h>
|
||||
|
||||
# define AT_HWCAP 16
|
||||
|
||||
namespace __sanitizer {
|
||||
|
||||
uptr getauxval(uptr Type) {
|
||||
uptr F = internal_open("/proc/self/auxv", O_RDONLY);
|
||||
if (internal_iserror(F))
|
||||
return 0;
|
||||
struct { uptr Tag; uptr Value; } Entry;
|
||||
uptr Result = 0;
|
||||
for (;;) {
|
||||
uptr N = internal_read(F, &Entry, sizeof(Entry));
|
||||
if (internal_iserror(N))
|
||||
break;
|
||||
if (N == 0 || N != sizeof(Entry) || (Entry.Tag == 0 && Entry.Value == 0))
|
||||
break;
|
||||
if (Entry.Tag == Type) {
|
||||
Result = Entry.Value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
internal_close(F);
|
||||
return Result;
|
||||
}
|
||||
|
||||
} // namespace __sanitizer
|
||||
# else
|
||||
# include <sys/auxv.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// TODO(kostyak): remove __sanitizer *Printf uses in favor for our own less
|
||||
|
@ -82,9 +114,9 @@ CPUIDRegs getCPUFeatures() {
|
|||
return FeaturesRegs;
|
||||
}
|
||||
|
||||
#ifndef bit_SSE4_2
|
||||
# define bit_SSE4_2 bit_SSE42 // clang and gcc have different defines.
|
||||
#endif
|
||||
# ifndef bit_SSE4_2
|
||||
# define bit_SSE4_2 bit_SSE42 // clang and gcc have different defines.
|
||||
# endif
|
||||
|
||||
bool testCPUFeature(CPUFeature Feature)
|
||||
{
|
||||
|
@ -99,12 +131,12 @@ bool testCPUFeature(CPUFeature Feature)
|
|||
return false;
|
||||
}
|
||||
#elif defined(__arm__) || defined(__aarch64__)
|
||||
// For ARM and AArch64, hardware CRC32 support is indicated in the
|
||||
// AT_HWVAL auxiliary vector.
|
||||
// For ARM and AArch64, hardware CRC32 support is indicated in the AT_HWVAL
|
||||
// auxiliary vector.
|
||||
|
||||
#ifndef HWCAP_CRC32
|
||||
# define HWCAP_CRC32 (1<<7) // HWCAP_CRC32 is missing on older platforms.
|
||||
#endif
|
||||
# ifndef HWCAP_CRC32
|
||||
# define HWCAP_CRC32 (1 << 7) // HWCAP_CRC32 is missing on older platforms.
|
||||
# endif
|
||||
|
||||
bool testCPUFeature(CPUFeature Feature) {
|
||||
uptr HWCap = getauxval(AT_HWCAP);
|
||||
|
|
Loading…
Reference in New Issue