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

35 lines
1.3 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//===-- Implementation header for IRELATIVE relocations -------- *- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_STARTUP_LINUX_IRELATIVE_H
#define LLVM_LIBC_STARTUP_LINUX_IRELATIVE_H
#include "hdr/link_macros.h"
#include "hdr/stdint_proxy.h"
#include "src/__support/macros/config.h"
extern "C" {
[[gnu::weak, gnu::visibility("hidden")]] extern const ElfW(Rela)
__rela_iplt_start[]; // NOLINT
[[gnu::weak, gnu::visibility("hidden")]] extern const ElfW(Rela)
__rela_iplt_end[]; // NOLINT
}
namespace LIBC_NAMESPACE_DECL {
// Process IRELATIVE relocations (ifunc resolvers).
// base is the load bias (actual load address link-time address). It is
// intptr_t (signed) because it is a difference; it is negative if the binary
// loaded below its link address. (unlikely but possible in principle)
void apply_irelative_relocs(intptr_t base, unsigned long hwcap,
unsigned long hwcap2);
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_STARTUP_LINUX_IRELATIVE_H