blob: 0fda65c95660b23ce66cfd1e32f9cc7e6066acc0 [file] [edit]
//===-- Implementation of apply_irelative_relocs test ---------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "test/IntegrationTest/test.h"
#ifndef __has_attribute
#define __has_attribute(x) 0
#endif
#if __has_attribute(ifunc)
// Two trivial implementations that return different constants.
static int impl_a() { return 42; }
static int impl_b() { return 84; }
// The resolver function. On x86_64 this takes no arguments; on AArch64 it
// receives (hwcap, hwcap2). We use extern "C" to ensure C linkage for the
// ifunc attribute.
extern "C" {
// Declare the resolver to return a generic function pointer.
// For testing, unconditionally select impl_a.
void *my_ifunc_resolver() {
(void)impl_b; // Suppress unused warning.
return reinterpret_cast<void *>(impl_a);
}
}
// Declare the ifunc. The compiler and linker will generate an IRELATIVE
// relocation that calls my_ifunc_resolver at startup.
extern "C" int my_ifunc() __attribute__((ifunc("my_ifunc_resolver")));
TEST_MAIN() {
// If IRELATIVE processing works correctly, my_ifunc() should call impl_a
// and return 42.
ASSERT_EQ(my_ifunc(), 42);
return 0;
}
#else
TEST_MAIN() { return 0; }
#endif