Files
TheRock/debug-tools/rocgdb/source/gold/testsuite/ifunc-sel.h
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

93 lines
2.7 KiB
C

/* Used by the elf ifunc tests. */
#ifndef ELF_IFUNC_SEL_H
#define ELF_IFUNC_SEL_H 1
extern int global;
static inline __attribute__ ((always_inline)) void *
ifunc_sel (int (*f1) (void), int (*f2) (void), int (*f3) (void))
{
#ifdef __powerpc__
/* When generating PIC, powerpc gcc loads the address of "global"
from the GOT, but the GOT may not have been relocated.
Similarly, "f1", "f2" and "f3" may be loaded from non-relocated
GOT entries.
There is NO WAY to make this ill conceived IFUNC misfeature
reliably work on targets that use a GOT for function or variable
addresses, short of implementing two passes over relocations in
ld.so, with ifunc relocations being applied after all other
relocations, globally.
Cheat. Don't use the GOT. Rely on this function being inlined
and calculate all variable and function addresses relative to pc.
Using the 'X' constraint is risky, but that's the only way to
make the asm here see the function names for %4, %5 and %6.
Sadly, powerpc64 gcc doesn't accept use of %3 here with 'X' for
some reason, so we expand it ourselves. */
register void *ret __asm__ ("r3");
void *temp1, *temp2;
__asm__ ("mflr %1\n\t"
"bcl 20,31,1f\n"
"1:\tmflr %2\n\t"
"mtlr %1\n\t"
"addis %1,%2,global-1b@ha\n\t"
"lwz %1,global-1b@l(%1)\n\t"
"addis %0,%2,%4-1b@ha\n\t"
"addi %0,%0,%4-1b@l\n\t"
"cmpwi %1,1\n\t"
"beqlr\n\t"
"addis %0,%2,%5-1b@ha\n\t"
"addi %0,%0,%5-1b@l\n\t"
"cmpwi %1,-1\n\t"
"beqlr\n\t"
"addis %0,%2,%6-1b@ha\n\t"
"addi %0,%0,%6-1b@l"
: "=&b" (ret), "=&b" (temp1), "=&b" (temp2)
: "X" (&global), "X" (f1), "X" (f2), "X" (f3));
return ret;
#else
switch (global)
{
case 1:
return f1;
case -1:
return f2;
default:
return f3;
}
#endif
}
static inline __attribute__ ((always_inline)) void *
ifunc_one (int (*f1) (void))
{
#ifdef __powerpc__
/* As above, PIC may use an unrelocated GOT entry for f1.
Case study: ifuncmain6pie's shared library, ifuncmod6.so, wants
the address of "foo" in function get_foo(). So there is a GOT
entry for "foo" in ifuncmod6.so. ld.so relocates ifuncmod6.so
*before* ifuncmain6pie, and on finding "foo" to be STT_GNU_IFUNC,
calls this function with f1 set to "one". But the address of
"one" is loaded from ifuncmain6pie's GOT, which hasn't been
relocated yet.
Cheat as for ifunc-sel. */
register void *ret __asm__ ("r3");
void *temp;
__asm__ ("mflr %1\n\t"
"bcl 20,31,1f\n"
"1:\tmflr %0\n\t"
"mtlr %1\n\t"
"addis %0,%0,%2-1b@ha\n\t"
"addi %0,%0,%2-1b@l"
: "=&b" (ret), "=&r" (temp)
: "X" (f1));
return ret;
#else
return f1;
#endif
}
#endif