Files
llvm-project/libc/test/integration/startup/linux/irelative_test.cpp
Jeff Bailey d1e29a4bf1 [libc] Enable ifunc support in static startup (#182841)
Resolves ifunc targets before `main()` runs in static libc

This enables static binaries to use ifunc-based dispatch during early
process startup, so optimized implementations can be selected based on
CPU features. Without this relocation step in startup, those targets are
not ready when program code begins executing.

This change:
- adds IRELATIVE relocation handling for x86_64, AArch64, ARMv7 and RISC-V,
- reads `AT_HWCAP` / `AT_HWCAP2` from auxv and passes them to resolvers
where required (notably AArch64),
- runs IRELATIVE processing after base-address discovery and before TLS
setup,
- adds integration tests for both the ifunc path and the no-ifunc path,
- Changed the load bias type for ptrdiff_t to intptr_t to align with
IRELATIVE handling, which uses intptr_t for load bias calculations.
2026-02-24 21:03:05 +00:00

49 lines
1.4 KiB
C++

//===-- 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