12c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich/*
22c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich * Copyright (C) 2013 The Android Open Source Project
32c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich *
42c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich * Licensed under the Apache License, Version 2.0 (the "License");
52c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich * you may not use this file except in compliance with the License.
62c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich * You may obtain a copy of the License at
72c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich *
82c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich *      http://www.apache.org/licenses/LICENSE-2.0
92c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich *
102c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich * Unless required by applicable law or agreed to in writing, software
112c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich * distributed under the License is distributed on an "AS IS" BASIS,
122c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich * See the License for the specific language governing permissions and
142c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich * limitations under the License.
152c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich */
162c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich
17ee7649c5ac5f1e56cc8193cd4cee73004c04893dDaniel Micay#include <errno.h>
182c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich#include <sys/cdefs.h>
195ca2bddae3c468cd37f028cdc2d5a5f5d98b3545Elliott Hughes#include <sys/utsname.h>
202c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich#include <gtest/gtest.h>
212c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich
222c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich// getauxval() was only added as of glibc version 2.16.
232c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich// See: http://lwn.net/Articles/519085/
242c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich// Don't try to compile this code on older glibc versions.
252c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich
262c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich#if defined(__BIONIC__)
272c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich  #define GETAUXVAL_CAN_COMPILE 1
282c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich#elif defined(__GLIBC_PREREQ)
292c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich  #if __GLIBC_PREREQ(2, 16)
302c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich    #define GETAUXVAL_CAN_COMPILE 1
312c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich  #endif
322c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich#endif
332c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich
342c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich#if defined(GETAUXVAL_CAN_COMPILE)
352c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich#include <sys/auxv.h>
36f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#endif
372c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich
382c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick KralevichTEST(getauxval, expected_values) {
39f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#if defined(GETAUXVAL_CAN_COMPILE)
40a65a3ad837618c5bf5c0b798bf9217a509ab5c61Elliott Hughes  ASSERT_EQ(0UL, getauxval(AT_SECURE));
412c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich  ASSERT_EQ(getuid(), getauxval(AT_UID));
422c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich  ASSERT_EQ(geteuid(), getauxval(AT_EUID));
432c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich  ASSERT_EQ(getgid(), getauxval(AT_GID));
442c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich  ASSERT_EQ(getegid(), getauxval(AT_EGID));
45a65a3ad837618c5bf5c0b798bf9217a509ab5c61Elliott Hughes  ASSERT_EQ(static_cast<unsigned long>(getpagesize()), getauxval(AT_PAGESZ));
462c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich
47a65a3ad837618c5bf5c0b798bf9217a509ab5c61Elliott Hughes  ASSERT_NE(0UL, getauxval(AT_PHDR));
48a65a3ad837618c5bf5c0b798bf9217a509ab5c61Elliott Hughes  ASSERT_NE(0UL, getauxval(AT_PHNUM));
49a65a3ad837618c5bf5c0b798bf9217a509ab5c61Elliott Hughes  ASSERT_NE(0UL, getauxval(AT_ENTRY));
50a65a3ad837618c5bf5c0b798bf9217a509ab5c61Elliott Hughes  ASSERT_NE(0UL, getauxval(AT_PAGESZ));
51f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#else
52a65a3ad837618c5bf5c0b798bf9217a509ab5c61Elliott Hughes  GTEST_LOG_(INFO) << "This test requires a C library with getauxval.\n";
53f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#endif
542c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich}
552c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich
562c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick KralevichTEST(getauxval, unexpected_values) {
57f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#if defined(GETAUXVAL_CAN_COMPILE)
58ee7649c5ac5f1e56cc8193cd4cee73004c04893dDaniel Micay  errno = 0;
59a65a3ad837618c5bf5c0b798bf9217a509ab5c61Elliott Hughes  ASSERT_EQ(0UL, getauxval(0xdeadbeef));
60ee7649c5ac5f1e56cc8193cd4cee73004c04893dDaniel Micay  ASSERT_EQ(ENOENT, errno);
61f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#else
62a65a3ad837618c5bf5c0b798bf9217a509ab5c61Elliott Hughes  GTEST_LOG_(INFO) << "This test requires a C library with getauxval.\n";
63a65a3ad837618c5bf5c0b798bf9217a509ab5c61Elliott Hughes#endif
64a65a3ad837618c5bf5c0b798bf9217a509ab5c61Elliott Hughes}
65a65a3ad837618c5bf5c0b798bf9217a509ab5c61Elliott Hughes
66a65a3ad837618c5bf5c0b798bf9217a509ab5c61Elliott HughesTEST(getauxval, arm_has_AT_HWCAP2) {
67a65a3ad837618c5bf5c0b798bf9217a509ab5c61Elliott Hughes#if defined(__arm__)
685ca2bddae3c468cd37f028cdc2d5a5f5d98b3545Elliott Hughes  // There are no known 32-bit processors that implement any of these instructions, so rather
695ca2bddae3c468cd37f028cdc2d5a5f5d98b3545Elliott Hughes  // than require that OEMs backport kernel patches, let's just ignore old hardware. Strictly
705ca2bddae3c468cd37f028cdc2d5a5f5d98b3545Elliott Hughes  // speaking this would be fooled by someone choosing to ship a 32-bit kernel on 64-bit hardware,
715ca2bddae3c468cd37f028cdc2d5a5f5d98b3545Elliott Hughes  // but that doesn't seem very likely in 2016.
725ca2bddae3c468cd37f028cdc2d5a5f5d98b3545Elliott Hughes  utsname u;
735ca2bddae3c468cd37f028cdc2d5a5f5d98b3545Elliott Hughes  ASSERT_EQ(0, uname(&u));
74dbf6f82e8703f7cf72ffe5cedb4a37a0dfb78e7cYabin Cui  if (strcmp(u.machine, "aarch64") == 0) {
75dbf6f82e8703f7cf72ffe5cedb4a37a0dfb78e7cYabin Cui    // If this test fails, apps that use getauxval to decide at runtime whether crypto hardware is
76dbf6f82e8703f7cf72ffe5cedb4a37a0dfb78e7cYabin Cui    // available will incorrectly assume that it isn't, and will have really bad performance.
77dbf6f82e8703f7cf72ffe5cedb4a37a0dfb78e7cYabin Cui    // If this test fails, ensure that you've enabled COMPAT_BINFMT_ELF in your kernel configuration.
78dbf6f82e8703f7cf72ffe5cedb4a37a0dfb78e7cYabin Cui    // Note that 0 ("I don't support any of these things") is a legitimate response --- we need
79dbf6f82e8703f7cf72ffe5cedb4a37a0dfb78e7cYabin Cui    // to check errno to see whether we got a "true" 0 or a "not found" 0.
80dbf6f82e8703f7cf72ffe5cedb4a37a0dfb78e7cYabin Cui    errno = 0;
81dbf6f82e8703f7cf72ffe5cedb4a37a0dfb78e7cYabin Cui    getauxval(AT_HWCAP2);
82dbf6f82e8703f7cf72ffe5cedb4a37a0dfb78e7cYabin Cui    ASSERT_EQ(0, errno) << "64-bit kernel not reporting AT_HWCAP2 to 32-bit ARM process";
835ca2bddae3c468cd37f028cdc2d5a5f5d98b3545Elliott Hughes    return;
845ca2bddae3c468cd37f028cdc2d5a5f5d98b3545Elliott Hughes  }
85f04935c85e0b466f0d30d2cd4c0fa2fff62e7d6dChristopher Ferris#endif
86dbf6f82e8703f7cf72ffe5cedb4a37a0dfb78e7cYabin Cui  GTEST_LOG_(INFO) << "This test is only meaningful for 32-bit ARM code on 64-bit devices.\n";
872c5153b043b44e9935a334ae9b2d5a4bc5258b40Nick Kralevich}
88