summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2021-08-04 15:30:56 +0000
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2021-09-10 15:07:38 -0300
commitc8315ccd30fcecc1b93a9bc3f073010190a86e05 (patch)
tree5f8cc1af7a951206e25b72eeca7875561f024a4f
parent171fdd4bd4f337001db053721477add60d205ed8 (diff)
downloadglibc-azanella/ld-audit-fixes.tar.gz
elf: Add SVE support for aarch64 rtld-auditazanella/ld-audit-fixes
To implement lazy binding is enabled when profiling or auditing used, even when STO_AARCH64_VARIANT_PCS is set. Also, to not incur in performance penalties on architecture without SVE, the PLT entrypoint is set to a newer one, _dl_runtime_profile_sve, which is used iff 'hwcap' has HWCAP_SVE bit set. This should be a fair assumption since SVE has a defined set of registers for argument passing and return values. A new ABI with either different argument passing or different registers would require a different PLT entry, but I assume this would require another symbol flag anyway (or at least a different ELF mark to indicate so). The profile '_dl_runtime_profile_sve' entrypoint assumes the largest SVE register size possible (2048 bits) and thus it requires a quite large stack (8976 bytes). I think it would be possible make the stack requirement dynamic depending of the vector length, but it would make the PLT audit function way more complex. It extends the La_aarch64_vector with a long double pointer to a stack alloced buffer to hold the SVE Z register, along with a pointer to hold the P registers on La_aarch64_regs. It means the if 'lr_sve' is 0 in either La_aarch64_regs or La_aarch64_retval the La_aarch64_vector contains the floating-pointer registers that can be accessed directly (non SVE hardware). Otherwise, 'La_aarch64_vector.z' points to a memory area that holds up to 'lr_sve' bytes for the Z registers, which can be loaded with svld1 intrinsic for instance (as tst-audit28.c does). The P register follows the same logic, with each La_aarch64_regs.lr_sve_pregs pointing to an area of memory 'lr_sve/8' in size. So, to access the FP register as float you can use: static inline float regs_vec_to_float (const La_aarch64_regs *regs, int idx) { float r; if (regs->lr_sve == 0) r = regs->lr_vreg[idx].s; else memcpy (&r, &regs->lr_vreg[idx].z[0], sizeof (r)); return r; } This patch is not complete yet: the tst-audit28 does not check if compiler supports SVE (we would need a configure check to disable for such case), I need to add a proper comment for the _dl_runtime_profile_sve stack layout, the test need to check for the P register state clobbering. I also haven't check the performance penalties with this approach, and maybe the way I am saving/restoring the SVE register might be optimized. In any case, I checked on a SVE machine and at least the testcase work as expected without any regressions. I also did a sniff test on a non SVE machine.
-rw-r--r--elf/do-rel.h6
-rw-r--r--elf/dynamic-link.h23
-rw-r--r--sysdeps/aarch64/Makefile16
-rw-r--r--sysdeps/aarch64/bits/link.h4
-rw-r--r--sysdeps/aarch64/dl-link.sym3
-rw-r--r--sysdeps/aarch64/dl-machine.h14
-rw-r--r--sysdeps/aarch64/dl-trampoline.S296
-rw-r--r--sysdeps/aarch64/tst-audit28.c44
-rw-r--r--sysdeps/aarch64/tst-audit28mod.c48
-rw-r--r--sysdeps/aarch64/tst-audit28mod.h74
-rw-r--r--sysdeps/aarch64/tst-auditmod27.c187
-rw-r--r--sysdeps/aarch64/tst-auditmod28.c193
-rw-r--r--sysdeps/alpha/dl-machine.h2
-rw-r--r--sysdeps/arc/dl-machine.h2
-rw-r--r--sysdeps/arm/dl-machine.h2
-rw-r--r--sysdeps/csky/dl-machine.h2
-rw-r--r--sysdeps/hppa/dl-machine.h2
-rw-r--r--sysdeps/i386/dl-machine.h2
-rw-r--r--sysdeps/ia64/dl-machine.h2
-rw-r--r--sysdeps/m68k/dl-machine.h2
-rw-r--r--sysdeps/microblaze/dl-machine.h2
-rw-r--r--sysdeps/mips/dl-machine.h2
-rw-r--r--sysdeps/nios2/dl-machine.h2
-rw-r--r--sysdeps/powerpc/powerpc32/dl-machine.h2
-rw-r--r--sysdeps/powerpc/powerpc64/dl-machine.h2
-rw-r--r--sysdeps/riscv/dl-machine.h2
-rw-r--r--sysdeps/s390/s390-32/dl-machine.h2
-rw-r--r--sysdeps/s390/s390-64/dl-machine.h2
-rw-r--r--sysdeps/sh/dl-machine.h2
-rw-r--r--sysdeps/sparc/sparc32/dl-machine.h2
-rw-r--r--sysdeps/sparc/sparc64/dl-machine.h2
-rw-r--r--sysdeps/x86_64/dl-machine.h2
32 files changed, 856 insertions, 92 deletions
diff --git a/elf/do-rel.h b/elf/do-rel.h
index af14ed3fb3..b27244cf77 100644
--- a/elf/do-rel.h
+++ b/elf/do-rel.h
@@ -43,7 +43,7 @@ auto inline void __attribute__ ((always_inline))
elf_dynamic_do_Rel (struct link_map *map,
ElfW(Addr) reladdr, ElfW(Addr) relsize,
__typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative,
- int lazy, int skip_ifunc)
+ int lazy, int profile, int skip_ifunc)
{
const ElfW(Rel) *r = (const void *) reladdr;
const ElfW(Rel) *end = (const void *) (reladdr + relsize);
@@ -70,13 +70,13 @@ elf_dynamic_do_Rel (struct link_map *map,
}
else
# endif
- elf_machine_lazy_rel (map, l_addr, r, skip_ifunc);
+ elf_machine_lazy_rel (map, l_addr, r, profile, skip_ifunc);
# ifdef ELF_MACHINE_IRELATIVE
if (r2 != NULL)
for (; r2 <= end2; ++r2)
if (ELFW(R_TYPE) (r2->r_info) == ELF_MACHINE_IRELATIVE)
- elf_machine_lazy_rel (map, l_addr, r2, skip_ifunc);
+ elf_machine_lazy_rel (map, l_addr, r2, profile, skip_ifunc);
# endif
}
else
diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h
index 3eb24ba3a6..7e71da3133 100644
--- a/elf/dynamic-link.h
+++ b/elf/dynamic-link.h
@@ -80,11 +80,13 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
auto inline void __attribute__((always_inline))
elf_machine_lazy_rel (struct link_map *map,
ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
+ int profile,
int skip_ifunc);
# else
auto inline void __attribute__((always_inline))
elf_machine_lazy_rel (struct link_map *map,
ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
+ int profile,
int skip_ifunc);
# endif
#endif
@@ -114,7 +116,7 @@ elf_machine_lazy_rel (struct link_map *map,
consumes precisely the very end of the DT_REL*, or DT_JMPREL and DT_REL*
are completely separate and there is a gap between them. */
-# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, skip_ifunc, test_rel) \
+# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, do_profile, skip_ifunc, test_rel) \
do { \
struct { ElfW(Addr) start, size; \
__typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative; int lazy; } \
@@ -153,7 +155,7 @@ elf_machine_lazy_rel (struct link_map *map,
\
if (ELF_DURING_STARTUP) \
elf_dynamic_do_##reloc ((map), ranges[0].start, ranges[0].size, \
- ranges[0].nrelative, 0, skip_ifunc); \
+ ranges[0].nrelative, 0, 0, skip_ifunc); \
else \
{ \
int ranges_index; \
@@ -163,6 +165,7 @@ elf_machine_lazy_rel (struct link_map *map,
ranges[ranges_index].size, \
ranges[ranges_index].nrelative, \
ranges[ranges_index].lazy, \
+ do_profile, \
skip_ifunc); \
} \
} while (0)
@@ -175,19 +178,19 @@ elf_machine_lazy_rel (struct link_map *map,
# if ! ELF_MACHINE_NO_REL
# include "do-rel.h"
-# define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc) \
- _ELF_DYNAMIC_DO_RELOC (REL, Rel, map, lazy, skip_ifunc, _ELF_CHECK_REL)
+# define ELF_DYNAMIC_DO_REL(map, lazy, profiling, skip_ifunc) \
+ _ELF_DYNAMIC_DO_RELOC (REL, Rel, map, lazy, profiling, skip_ifunc, _ELF_CHECK_REL)
# else
-# define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc) /* Nothing to do. */
+# define ELF_DYNAMIC_DO_REL(map, lazy, profiling, skip_ifunc) /* Nothing to do. */
# endif
# if ! ELF_MACHINE_NO_RELA
# define DO_RELA
# include "do-rel.h"
-# define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc) \
- _ELF_DYNAMIC_DO_RELOC (RELA, Rela, map, lazy, skip_ifunc, _ELF_CHECK_REL)
+# define ELF_DYNAMIC_DO_RELA(map, lazy, profiling, skip_ifunc) \
+ _ELF_DYNAMIC_DO_RELOC (RELA, Rela, map, lazy, profiling, skip_ifunc, _ELF_CHECK_REL)
# else
-# define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc) /* Nothing to do. */
+# define ELF_DYNAMIC_DO_RELA(map, lazy, profiling, skip_ifunc) /* Nothing to do. */
# endif
/* This can't just be an inline function because GCC is too dumb
@@ -196,8 +199,8 @@ elf_machine_lazy_rel (struct link_map *map,
do { \
int edr_lazy = elf_machine_runtime_setup ((map), (lazy), \
(consider_profile)); \
- ELF_DYNAMIC_DO_REL ((map), edr_lazy, skip_ifunc); \
- ELF_DYNAMIC_DO_RELA ((map), edr_lazy, skip_ifunc); \
+ ELF_DYNAMIC_DO_REL ((map), edr_lazy, (consider_profile), skip_ifunc); \
+ ELF_DYNAMIC_DO_RELA ((map), edr_lazy, (consider_profile), skip_ifunc); \
} while (0)
#endif
diff --git a/sysdeps/aarch64/Makefile b/sysdeps/aarch64/Makefile
index 7183895d04..a2c64d7d5d 100644
--- a/sysdeps/aarch64/Makefile
+++ b/sysdeps/aarch64/Makefile
@@ -12,13 +12,16 @@ ifeq ($(subdir),elf)
sysdep-dl-routines += dl-bti
tests += tst-audit26 \
- tst-audit27
+ tst-audit27 \
+ tst-audit28
modules-names += \
tst-audit26mod \
tst-auditmod26 \
tst-audit27mod \
- tst-auditmod27
+ tst-auditmod27 \
+ tst-audit28mod \
+ tst-auditmod28
$(objpfx)tst-audit26: $(objpfx)tst-audit26mod.so \
$(objpfx)tst-auditmod26.so
@@ -30,6 +33,15 @@ $(objpfx)tst-audit27: $(objpfx)tst-audit27mod.so \
$(objpfx)tst-audit27mod.so: $(libsupport)
LDFLAGS-tst-audit27 += -Wl,-z,lazy
tst-audit27-ENV = LD_AUDIT=$(objpfx)tst-auditmod27.so
+
+$(objpfx)tst-audit28: $(objpfx)tst-audit28mod.so \
+ $(objpfx)tst-auditmod28.so
+CFLAGS-tst-audit28.c += -march=armv8.2-a+sve
+CFLAGS-tst-audit28mod.c += -march=armv8.2-a+sve
+CFLAGS-tst-auditmod28.c += -march=armv8.2-a+sve
+$(objpfx)tst-audit28mod.so: $(libsupport)
+LDFLAGS-tst-audit28 += -Wl,-z,lazy
+tst-audit28-ENV = LD_AUDIT=$(objpfx)tst-auditmod28.so
endif
ifeq ($(subdir),elf)
diff --git a/sysdeps/aarch64/bits/link.h b/sysdeps/aarch64/bits/link.h
index 2af90ca6be..2ad0f5d500 100644
--- a/sysdeps/aarch64/bits/link.h
+++ b/sysdeps/aarch64/bits/link.h
@@ -25,6 +25,7 @@ typedef union
float s;
double d;
long double q;
+ long double *z;
} La_aarch64_vector;
/* Registers for entry into PLT on AArch64. */
@@ -34,6 +35,8 @@ typedef struct La_aarch64_regs
La_aarch64_vector lr_vreg[8];
uint64_t lr_sp;
uint64_t lr_lr;
+ uint8_t lr_sve;
+ uint16_t *lr_sve_pregs[4];
} La_aarch64_regs;
/* Return values for calls from PLT on AArch64. */
@@ -43,6 +46,7 @@ typedef struct La_aarch64_retval
uint64_t lrv_xreg[8];
/* Up to eight V registers can be used for a return value. */
La_aarch64_vector lrv_vreg[8];
+ uint8_t lrv_sve;
} La_aarch64_retval;
__BEGIN_DECLS
diff --git a/sysdeps/aarch64/dl-link.sym b/sysdeps/aarch64/dl-link.sym
index 70d153a1d5..9bc56b98ec 100644
--- a/sysdeps/aarch64/dl-link.sym
+++ b/sysdeps/aarch64/dl-link.sym
@@ -10,6 +10,9 @@ DL_OFFSET_RG_X0 offsetof(struct La_aarch64_regs, lr_xreg)
DL_OFFSET_RG_V0 offsetof(struct La_aarch64_regs, lr_vreg)
DL_OFFSET_RG_SP offsetof(struct La_aarch64_regs, lr_sp)
DL_OFFSET_RG_LR offsetof(struct La_aarch64_regs, lr_lr)
+DL_OFFSET_RG_SVE offsetof(struct La_aarch64_regs, lr_sve)
+DL_OFFSET_RG_SVE_PREGS offsetof(struct La_aarch64_regs, lr_sve_pregs)
DL_OFFSET_RV_X0 offsetof(struct La_aarch64_retval, lrv_xreg)
DL_OFFSET_RV_V0 offsetof(struct La_aarch64_retval, lrv_vreg)
+DL_OFFSET_RV_SVE offsetof(struct La_aarch64_retval, lrv_sve)
diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h
index 3e10cb462f..38fa07f111 100644
--- a/sysdeps/aarch64/dl-machine.h
+++ b/sysdeps/aarch64/dl-machine.h
@@ -66,6 +66,9 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
ElfW(Addr) *got;
extern void _dl_runtime_resolve (ElfW(Word));
extern void _dl_runtime_profile (ElfW(Word));
+#if HAVE_AARCH64_SVE_ASM
+ extern void _dl_runtime_profile_sve (ElfW(Word));
+#endif
got = (ElfW(Addr) *) D_PTR (l, l_info[DT_PLTGOT]);
if (got[1])
@@ -82,7 +85,12 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
end in this function. */
if ( profile)
{
- got[2] = (ElfW(Addr)) &_dl_runtime_profile;
+#if HAVE_AARCH64_SVE_ASM
+ if (GLRO(dl_hwcap) & HWCAP_SVE)
+ got[2] = (ElfW(Addr)) &_dl_runtime_profile_sve;
+ else
+#endif
+ got[2] = (ElfW(Addr)) &_dl_runtime_profile;
if (GLRO(dl_profile) != NULL
&& _dl_name_match_p (GLRO(dl_profile), l))
@@ -382,6 +390,7 @@ __attribute__ ((always_inline))
elf_machine_lazy_rel (struct link_map *map,
ElfW(Addr) l_addr,
const ElfW(Rela) *reloc,
+ int profile,
int skip_ifunc)
{
ElfW(Addr) *const reloc_addr = (void *) (l_addr + reloc->r_offset);
@@ -389,7 +398,8 @@ elf_machine_lazy_rel (struct link_map *map,
/* Check for unexpected PLT reloc type. */
if (__builtin_expect (r_type == AARCH64_R(JUMP_SLOT), 1))
{
- if (__glibc_unlikely (map->l_info[DT_AARCH64 (VARIANT_PCS)] != NULL))
+ if (__glibc_unlikely (map->l_info[DT_AARCH64 (VARIANT_PCS)] != NULL)
+ && profile == 0)
{
/* Check the symbol table for variant PCS symbols. */
const Elf_Symndx symndx = ELFW (R_SYM) (reloc->r_info);
diff --git a/sysdeps/aarch64/dl-trampoline.S b/sysdeps/aarch64/dl-trampoline.S
index 0d540651d4..6025de64ee 100644
--- a/sysdeps/aarch64/dl-trampoline.S
+++ b/sysdeps/aarch64/dl-trampoline.S
@@ -205,6 +205,9 @@ _dl_runtime_profile:
cfi_rel_offset (q6, OFFSET_RG + DL_OFFSET_RG_V0 + 32*3 + 0)
cfi_rel_offset (q7, OFFSET_RG + DL_OFFSET_RG_V0 + 32*3 + 16)
+ strb wzr, [x29, #OFFSET_RG + DL_OFFSET_RG_SVE]
+ strb wzr, [x29, #OFFSET_RV + DL_OFFSET_RV_SVE]
+
add x0, x29, #SF_SIZE + 16
ldr x1, [x29, #OFFSET_LR]
stp x0, x1, [x29, #OFFSET_RG + DL_OFFSET_RG_SP]
@@ -341,3 +344,296 @@ _dl_runtime_profile:
.size _dl_runtime_profile, .-_dl_runtime_profile
#endif
.previous
+
+
+#define HWCAP_SVE 22
+#define ZCR_ELx_LEN_MASK 0x1ff
+
+#if HAVE_AARCH64_SVE_ASM
+ .arch armv8.2-a+sve
+ .globl _dl_runtime_profile_sve
+ .type _dl_runtime_profile_sve, #function
+ cfi_startproc
+ .align 2
+_dl_runtime_profile_sve:
+# if HAVE_AARCH64_PAC_RET
+ PACIASP
+ cfi_window_save
+# else
+ BTI_C
+# endif
+ /* AArch64 we get called with:
+ ip0 &PLTGOT[2]
+ ip1 temp(dl resolver entry point)
+ [sp, #8] lr
+ [sp, #0] &PLTGOT[n]
+
+ Stack frame layout:
+ [sp, #...] lr
+ [sp, #...] &PLTGOT[n]
+ -------------------------
+ TODO
+ [sp, # 0] x29, lr <- x29
+ */
+
+# define OFFSET_SVE_T1 16
+# define OFFSET_SVE_SAVED_CALL_X0 OFFSET_SVE_T1 + 8
+# define OFFSET_SVE_FS OFFSET_SVE_SAVED_CALL_X0 + 16
+# define OFFSET_SVE_RV OFFSET_SVE_FS + 8
+# define OFFSET_SVE_RG OFFSET_SVE_RV + DL_SIZEOF_RV
+/* Maximum supported z and pregisters size in bytes. */
+# define SIZEOF_SVE_Z_REG 512
+# define SIZEOF_SVE_P_REG SIZEOF_SVE_Z_REG / 8
+/* z0-z7 for argument passing. */
+# define SIZEOF_SVE_RG_Z 8 * SIZEOF_SVE_Z_REG
+/* p0-p3 for argument passing. */
+# define SIZEOF_SVE_RG_P 4 * SIZEOF_SVE_P_REG
+/* z0-z7 for function return. */
+# define SIZEOF_SVE_RV_P 8 * SIZEOF_SVE_Z_REG
+/* SVE registers contents for La_aarch64_regs.lr_vreg */
+# define OFFSET_SVE_RG_Z OFFSET_SVE_RG + DL_SIZEOF_RG
+/* SVE registers contents for La_aarch64.regs.lr_sve_pregs */
+# define OFFSET_SVE_RG_P OFFSET_SVE_RG_Z + SIZEOF_SVE_RG_Z
+/* SVE registers contents for La_aarch64_retval.lrv_vreg */
+# define OFFSET_SVE_RV_Z OFFSET_SVE_RG_P + SIZEOF_SVE_RG_P
+
+# define SF_SVE_SIZE OFFSET_SVE_RV_Z + SIZEOF_SVE_RV_P
+
+# define OFFSET_SVE_PLTGOTN SF_SVE_SIZE
+# define OFFSET_SVE_LR OFFSET_SVE_PLTGOTN + 8
+
+ .macro save_sve_z_reg zreg idx offset save_addr
+ .ifc \zreg, z0
+ .if \offset < 4096
+ add x0, x29, \offset
+ .else
+ mov x0, \offset
+ add x0, x29, x0
+ .endif
+ .else
+ add x0, x0, SIZEOF_SVE_Z_REG
+ .endif
+ str \zreg, [x0, #0]
+ .if \save_addr == 1
+ str x0, [X29, #OFFSET_RG + DL_OFFSET_RG_V0 + 16*\idx]
+ .else
+ str x0, [X29, #OFFSET_RV + DL_OFFSET_RV_V0 + 16*\idx]
+ .endif
+ .endm
+
+ .macro save_sve_regs offset save_addr
+ save_sve_z_reg z0 0 \offset \save_addr
+ save_sve_z_reg z1 1 \offset \save_addr
+ save_sve_z_reg z2 2 \offset \save_addr
+ save_sve_z_reg z3 3 \offset \save_addr
+ save_sve_z_reg z4 4 \offset \save_addr
+ save_sve_z_reg z5 5 \offset \save_addr
+ save_sve_z_reg z6 6 \offset \save_addr
+ save_sve_z_reg z7 7 \offset \save_addr
+ .if \save_addr == 1
+ add x0, x0, SIZEOF_SVE_P_REG
+ str p0, [x0, #0]
+ add x0, x0, SIZEOF_SVE_P_REG
+ str p1, [x0, #0]
+ add x0, x0, SIZEOF_SVE_P_REG
+ str p2, [x0, #0]
+ add x0, x0, SIZEOF_SVE_P_REG
+ str p3, [x0, #0]
+ .endif
+ .endm
+
+ .macro load_sve_regs offset
+ .if \offset < 4096
+ add x12, x29, \offset
+ .else
+ mov x12, \offset
+ add x12, x29, x12
+ .endif
+ ldr z0, [x12, #0]
+ add x12, x12, SIZEOF_SVE_Z_REG
+ ldr z1, [x12, #0]
+ add x12, x12, SIZEOF_SVE_Z_REG
+ ldr z2, [x12, #0]
+ add x12, x12, SIZEOF_SVE_Z_REG
+ ldr z3, [x12, #0]
+ add x12, x12, SIZEOF_SVE_Z_REG
+ ldr z4, [x12, #0]
+ add x12, x12, SIZEOF_SVE_Z_REG
+ ldr z5, [x12, #0]
+ add x12, x12, SIZEOF_SVE_Z_REG
+ ldr z6, [x12, #0]
+ add x12, x12, SIZEOF_SVE_Z_REG
+ ldr z7, [x12, #0]
+ add x12, x12, SIZEOF_SVE_P_REG
+ ldr p0, [x12, #0]
+ add x12, x12, SIZEOF_SVE_P_REG
+ ldr p1, [x12, #0]
+ add x12, x12, SIZEOF_SVE_P_REG
+ ldr p2, [x12, #0]
+ add x12, x12, SIZEOF_SVE_P_REG
+ ldr p3, [x12, #0]
+ .endm
+
+
+ /* Save arguments. */
+ mov x12, #SF_SVE_SIZE
+ sub sp, sp, x12
+ cfi_adjust_cfa_offset (SF_SVE_SIZE)
+ stp x29, x30, [SP, #0]
+ mov x29, sp
+ cfi_def_cfa_register (x29)
+ cfi_rel_offset (x29, 0)
+ cfi_rel_offset (lr, 8)
+
+ stp x0, x1, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*0]
+ cfi_rel_offset (x0, OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*0 + 0)
+ cfi_rel_offset (x1, OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*0 + 8)
+ stp x2, x3, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*1]
+ cfi_rel_offset (x2, OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*1 + 0)
+ cfi_rel_offset (x3, OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*1 + 8)
+ stp x4, x5, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*2]
+ cfi_rel_offset (x4, OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*2 + 0)
+ cfi_rel_offset (x5, OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*2 + 8)
+ stp x6, x7, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*3]
+ cfi_rel_offset (x6, OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*3 + 0)
+ cfi_rel_offset (x7, OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*3 + 8)
+ str x8, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*4 + 0]
+ cfi_rel_offset (x8, OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*4 + 0)
+ /* Note 8 bytes of padding is in the stack frame for alignment */
+ save_sve_regs OFFSET_SVE_RG_Z 1
+
+ /* Store the vector length on lr_sve */
+ mov x0, #0
+ addvl x0, x0, #1
+ strb w0, [x29, #OFFSET_RG + DL_OFFSET_RG_SVE]
+ strb w0, [x29, #OFFSET_RV + DL_OFFSET_RV_SVE]
+
+ mov x0, #SF_SVE_SIZE + 16
+ add x0, x29, x0
+ ldr x1, [x29, #OFFSET_SVE_LR]
+ stp x0, x1, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_SP]
+
+ /* Get pointer to linker struct. */
+ ldr PTR_REG (0), [ip0, #-PTR_SIZE]
+
+ /* Prepare to call _dl_profile_fixup(). */
+ ldr x1, [x29, OFFSET_SVE_PLTGOTN] /* Recover &PLTGOT[n] */
+
+ sub x1, x1, ip0
+ add x1, x1, x1, lsl #1
+ lsl x1, x1, #3
+ sub x1, x1, #(RELA_SIZE<<3)
+ lsr x1, x1, #3
+
+ stp x0, x1, [x29, #OFFSET_SVE_SAVED_CALL_X0]
+
+ /* Set up extra args for _dl_profile_fixup */
+ ldr x2, [x29, #OFFSET_SVE_LR] /* load saved LR */
+ add x3, x29, #OFFSET_SVE_RG /* address of La_aarch64_reg */
+ add x4, x29, #OFFSET_SVE_FS /* address of framesize */
+ bl _dl_profile_fixup
+
+ ldr ip0l, [x29, #OFFSET_SVE_FS] /* framesize == 0 */
+ cmp ip0l, #0
+ bge 1f
+ cfi_remember_state
+
+ /* Save the return. */
+ mov ip0, x0
+
+ /* Get arguments and return address back. */
+ ldp x0, x1, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*0]
+ ldp x2, x3, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*1]
+ ldp x4, x5, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*2]
+ ldp x6, x7, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*3]
+ ldr x8, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*4]
+ load_sve_regs OFFSET_SVE_RG_Z
+
+ cfi_def_cfa_register (sp)
+ ldp x29, x30, [x29, #0]
+ cfi_restore (x29)
+ cfi_restore (x30)
+
+# if HAVE_AARCH64_PAC_RET
+ mov x12, SF_SVE_SIZE
+ add sp, sp, x12
+ cfi_adjust_cfa_offset (-SF_SVE_SIZE)
+ AUTIASP
+ cfi_window_save
+ add sp, sp, 16
+ cfi_adjust_cfa_offset (-16)
+# else
+ mov x12, SF_SVE_SIZE + 16
+ add sp, sp, x12
+ cfi_adjust_cfa_offset (- SF_SVE_SIZE - 16)
+# endif
+
+ /* Jump to the newly found address. */
+ br ip0
+
+ cfi_restore_state
+1:
+ /* The new frame size is in ip0. */
+
+ sub PTR_REG (1), PTR_REG (29), ip0l
+ and sp, x1, #0xfffffffffffffff0
+
+ str x0, [x29, #OFFSET_SVE_T1]
+
+ mov x0, sp
+ mov x1, #SF_SVE_SIZE + 16
+ add x1, x29, x1
+ mov x2, ip0
+ bl memcpy
+
+ ldr ip0, [x29, #OFFSET_SVE_T1]
+
+ /* Call the function. */
+ ldp x0, x1, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*0]
+ ldp x2, x3, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*1]
+ ldp x4, x5, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*2]
+ ldp x6, x7, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*3]
+ ldr x8, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*4]
+ load_sve_regs OFFSET_SVE_RG_Z
+ blr ip0
+ stp x0, x1, [x29, #OFFSET_SVE_RV + DL_OFFSET_RV_X0 + 16*0]
+ stp x2, x3, [x29, #OFFSET_SVE_RV + DL_OFFSET_RV_X0 + 16*1]
+ stp x4, x5, [x29, #OFFSET_SVE_RV + DL_OFFSET_RV_X0 + 16*2]
+ stp x6, x7, [x29, #OFFSET_SVE_RV + DL_OFFSET_RV_X0 + 16*3]
+ str x8, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_X0 + 16*4]
+ save_sve_regs OFFSET_SVE_RV_Z 0
+
+ /* Setup call to pltexit */
+ ldp x0, x1, [x29, #OFFSET_SVE_SAVED_CALL_X0]
+ add x2, x29, #OFFSET_SVE_RG
+ add x3, x29, #OFFSET_SVE_RV
+ bl _dl_audit_pltexit
+
+ ldp x0, x1, [x29, #OFFSET_SVE_RV + DL_OFFSET_RV_X0 + 16*0]
+ ldp x2, x3, [x29, #OFFSET_SVE_RV + DL_OFFSET_RV_X0 + 16*1]
+ ldp x4, x5, [x29, #OFFSET_SVE_RV + DL_OFFSET_RV_X0 + 16*2]
+ ldp x6, x7, [x29, #OFFSET_SVE_RV + DL_OFFSET_RV_X0 + 16*3]
+ ldr x8, [x29, #OFFSET_SVE_RV + DL_OFFSET_RV_X0 + 16*4]
+ load_sve_regs OFFSET_SVE_RV_Z
+
+ /* LR from within La_aarch64_reg */
+ ldr lr, [x29, #OFFSET_SVE_RG + DL_OFFSET_RG_LR]
+ cfi_restore(lr)
+# if HAVE_AARCH64_PAC_RET
+ /* Note: LR restored from La_aarch64_reg has no PAC. */
+ cfi_window_save
+# endif
+ mov sp, x29
+ cfi_def_cfa_register (sp)
+ ldr x29, [x29, #0]
+ cfi_restore(x29)
+ mov x12, SF_SVE_SIZE + 16
+ add sp, sp, x12
+ cfi_adjust_cfa_offset (- SF_SVE_SIZE - 16)
+
+ br lr
+
+ cfi_endproc
+ .size _dl_runtime_profile_sve, .-_dl_runtime_profile_sve
+ .previous
+#endif /* HAVE_AARCH64_SVE_ASM */
diff --git a/sysdeps/aarch64/tst-audit28.c b/sysdeps/aarch64/tst-audit28.c
new file mode 100644
index 0000000000..28ffbd141f
--- /dev/null
+++ b/sysdeps/aarch64/tst-audit28.c
@@ -0,0 +1,44 @@
+/* Check DT_AUDIT for aarch64 ABI specifics.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <array_length.h>
+#include <string.h>
+#include <support/check.h>
+#include <sys/auxv.h>
+#include "tst-audit28mod.h"
+
+int
+do_test (void)
+{
+ unsigned long hwcap = getauxval (AT_HWCAP);
+ if ((hwcap & HWCAP_SVE) == 0)
+ FAIL_UNSUPPORTED ("system does not support SVE");
+
+ {
+ svint8_t r = tst_audit28_func_sve_args (sve_args_z0 (), sve_args_z1 (),
+ sve_args_z2 (), sve_args_z3 (),
+ sve_args_z4 (), sve_args_z5 (),
+ sve_args_z6 (), sve_args_z7 ());
+ if (!svptest_any (svptrue_b8 (), svcmpeq_s8 (svptrue_b8 (), r, sve_ret ())))
+ FAIL_EXIT1 ("tst_audit28_func_sve_args(): wrong return value");
+ }
+
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/aarch64/tst-audit28mod.c b/sysdeps/aarch64/tst-audit28mod.c
new file mode 100644
index 0000000000..f5e24346b4
--- /dev/null
+++ b/sysdeps/aarch64/tst-audit28mod.c
@@ -0,0 +1,48 @@
+/* Check DT_AUDIT for aarch64 ABI specifics.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <array_length.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <support/check.h>
+#include "tst-audit28mod.h"
+
+svint8_t
+tst_audit28_func_sve_args (svint8_t z0, svint16_t z1, svint32_t z2,
+ svint64_t z3, svuint8_t z4, svuint16_t z5,
+ svuint32_t z6, svuint64_t z7)
+{
+ assert (svptest_any (svptrue_b8 (), svcmpeq_s8 (svptrue_b8 (),
+ z0, sve_args_z0 ())));
+ assert (svptest_any (svptrue_b16 (), svcmpeq_s16 (svptrue_b16 (),
+ z1, sve_args_z1 ())));
+ assert (svptest_any (svptrue_b32 (), svcmpeq_s32 (svptrue_b32 (),
+ z2, sve_args_z2 ())));
+ assert (svptest_any (svptrue_b64 (), svcmpeq_s64 (svptrue_b64 (),
+ z3, sve_args_z3 ())));
+ assert (svptest_any (svptrue_b16 (), svcmpeq_u8 (svptrue_b8 (),
+ z4, sve_args_z4 ())));
+ assert (svptest_any (svptrue_b16 (), svcmpeq_u16 (svptrue_b16 (),
+ z5, sve_args_z5 ())));
+ assert (svptest_any (svptrue_b16 (), svcmpeq_u32 (svptrue_b32 (),
+ z6, sve_args_z6 ())));
+ assert (svptest_any (svptrue_b16 (), svcmpeq_u64 (svptrue_b64 (),
+ z7, sve_args_z7 ())));
+
+ return sve_ret ();
+}
diff --git a/sysdeps/aarch64/tst-audit28mod.h b/sysdeps/aarch64/tst-audit28mod.h
new file mode 100644
index 0000000000..55e3cdbbc6
--- /dev/null
+++ b/sysdeps/aarch64/tst-audit28mod.h
@@ -0,0 +1,74 @@
+/* Check DT_AUDIT for aarch64 specific ABI.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _TST_AUDIT27MOD_H
+#define _TST_AUDIT27MOD_H 1
+
+#include <arm_sve.h>
+
+static inline svint8_t sve_args_z0 (void)
+{
+ return svdup_s8 (INT8_MAX);
+}
+
+static inline svint16_t sve_args_z1 (void)
+{
+ return svdup_s16 (INT16_MAX);
+}
+
+static inline svint32_t sve_args_z2 (void)
+{
+ return svdup_s32 (INT32_MAX);
+}
+
+static inline svint64_t sve_args_z3 (void)
+{
+ return svdup_s64 (INT64_MAX);
+}
+
+static inline svuint8_t sve_args_z4 (void)
+{
+ return svdup_u8 (UINT8_MAX);
+}
+
+static inline svuint16_t sve_args_z5 (void)
+{
+ return svdup_u16 (UINT16_MAX);
+}
+
+static inline svuint32_t sve_args_z6 (void)
+{
+ return svdup_u32 (UINT32_MAX);
+}
+
+static inline svuint64_t sve_args_z7 (void)
+{
+ return svdup_u64 (UINT64_MAX);
+}
+
+static inline svint8_t sve_ret (void)
+{
+ return svdup_s8 (INT8_MIN);
+}
+
+#define INT_ARGS_RET 0x21
+
+svint8_t tst_audit28_func_sve_args (svint8_t z0, svint16_t z1, svint32_t z2, svint64_t z3,
+ svuint8_t z4, svuint16_t z5, svuint32_t z6, svuint64_t z7);
+
+#endif
diff --git a/sysdeps/aarch64/tst-auditmod27.c b/sysdeps/aarch64/tst-auditmod27.c
index b1dbff8330..9a6e23d752 100644
--- a/sysdeps/aarch64/tst-auditmod27.c
+++ b/sysdeps/aarch64/tst-auditmod27.c
@@ -16,18 +16,82 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
+#include <array_length.h>
#include <assert.h>
#include <link.h>
#include <string.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
+#include "tst-audit.h"
#include "tst-audit27mod.h"
#define TEST_NAME "tst-audit27"
#define AUDIT27_COOKIE 0
+static inline float regs_vec_to_float (const La_aarch64_regs *regs, int i)
+{
+ float r;
+ if (regs->lr_sve == 0)
+ r = regs->lr_vreg[i].s;
+ else
+ memcpy (&r, &regs->lr_vreg[i].z[0], sizeof (r));
+ return r;
+}
+
+static inline double regs_vec_to_double (const La_aarch64_regs *regs, int i)
+{
+ double r;
+ if (regs->lr_sve == 0)
+ r = regs->lr_vreg[i].d;
+ else
+ memcpy (&r, &regs->lr_vreg[i].z[0], sizeof (r));
+ return r;
+}
+
+static inline long double regs_vec_to_ldouble (const La_aarch64_regs *regs,
+ int i)
+{
+ long double r;
+ if (regs->lr_sve == 0)
+ r = regs->lr_vreg[i].q;
+ else
+ memcpy (&r, &regs->lr_vreg[i].z[0], sizeof (r));
+ return r;
+}
+
+static inline float ret_vec_to_float (const La_aarch64_retval *regs, int i)
+{
+ float r;
+ if (regs->lrv_sve == 0)
+ r = regs->lrv_vreg[i].s;
+ else
+ memcpy (&r, &regs->lrv_vreg[i].z[0], sizeof (r));
+ return r;
+}
+
+static inline double ret_vec_to_double (const La_aarch64_retval *regs, int i)
+{
+ double r;
+ if (regs->lrv_sve == 0)
+ r = regs->lrv_vreg[i].d;
+ else
+ memcpy (&r, &regs->lrv_vreg[i].z[0], sizeof (r));
+ return r;
+}
+
+static inline long double ret_vec_to_ldouble (const La_aarch64_retval *regs,
+ int i)
+{
+ long double r;
+ if (regs->lrv_sve == 0)
+ r = regs->lrv_vreg[i].q;
+ else
+ memcpy (&r, &regs->lrv_vreg[i].z[0], sizeof (r));
+ return r;
+}
+
unsigned int
la_version (unsigned int v)
{
@@ -47,6 +111,7 @@ la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO;
}
+
ElfW(Addr)
la_aarch64_gnu_pltenter (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook,
uintptr_t *defcook, La_aarch64_regs *regs,
@@ -55,39 +120,43 @@ la_aarch64_gnu_pltenter (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook,
{
printf ("pltenter: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n",
symname, (long int) sym->st_value, ndx, *flags);
+ printf (" regs->lr_sve=%d\n", regs->lr_sve);
+ if (regs->lr_sve > 0)
+ for (int i = 0; i < array_length (regs->lr_vreg); i++)
+ printf (" inregs->lr_vreg[%d]=%p\n", i, regs->lr_vreg[i].z);
if (strcmp (symname, "tst_audit27_func_float") == 0)
{
- assert (regs->lr_vreg[0].s == FUNC_FLOAT_ARG0);
- assert (regs->lr_vreg[1].s == FUNC_FLOAT_ARG1);
- assert (regs->lr_vreg[2].s == FUNC_FLOAT_ARG2);
- assert (regs->lr_vreg[3].s == FUNC_FLOAT_ARG3);
- assert (regs->lr_vreg[4].s == FUNC_FLOAT_ARG4);
- assert (regs->lr_vreg[5].s == FUNC_FLOAT_ARG5);
- assert (regs->lr_vreg[6].s == FUNC_FLOAT_ARG6);
- assert (regs->lr_vreg[7].s == FUNC_FLOAT_ARG7);
+ assert (regs_vec_to_float (regs, 0) == FUNC_FLOAT_ARG0);
+ assert (regs_vec_to_float (regs, 1) == FUNC_FLOAT_ARG1);
+ assert (regs_vec_to_float (regs, 2) == FUNC_FLOAT_ARG2);
+ assert (regs_vec_to_float (regs, 3) == FUNC_FLOAT_ARG3);
+ assert (regs_vec_to_float (regs, 4) == FUNC_FLOAT_ARG4);
+ assert (regs_vec_to_float (regs, 5) == FUNC_FLOAT_ARG5);
+ assert (regs_vec_to_float (regs, 6) == FUNC_FLOAT_ARG6);
+ assert (regs_vec_to_float (regs, 7) == FUNC_FLOAT_ARG7);
}
else if (strcmp (symname, "tst_audit27_func_double") == 0)
{
- assert (regs->lr_vreg[0].d == FUNC_DOUBLE_ARG0);
- assert (regs->lr_vreg[1].d == FUNC_DOUBLE_ARG1);
- assert (regs->lr_vreg[2].d == FUNC_DOUBLE_ARG2);
- assert (regs->lr_vreg[3].d == FUNC_DOUBLE_ARG3);
- assert (regs->lr_vreg[4].d == FUNC_DOUBLE_ARG4);
- assert (regs->lr_vreg[5].d == FUNC_DOUBLE_ARG5);
- assert (regs->lr_vreg[6].d == FUNC_DOUBLE_ARG6);
- assert (regs->lr_vreg[7].d == FUNC_DOUBLE_ARG7);
+ assert (regs_vec_to_double (regs, 0) == FUNC_DOUBLE_ARG0);
+ assert (regs_vec_to_double (regs, 1) == FUNC_DOUBLE_ARG1);
+ assert (regs_vec_to_double (regs, 2) == FUNC_DOUBLE_ARG2);
+ assert (regs_vec_to_double (regs, 3) == FUNC_DOUBLE_ARG3);
+ assert (regs_vec_to_double (regs, 4) == FUNC_DOUBLE_ARG4);
+ assert (regs_vec_to_double (regs, 5) == FUNC_DOUBLE_ARG5);
+ assert (regs_vec_to_double (regs, 6) == FUNC_DOUBLE_ARG6);
+ assert (regs_vec_to_double (regs, 7) == FUNC_DOUBLE_ARG7);
}
else if (strcmp (symname, "tst_audit27_func_ldouble") == 0)
{
- assert (regs->lr_vreg[0].q == FUNC_LDOUBLE_ARG0);
- assert (regs->lr_vreg[1].q == FUNC_LDOUBLE_ARG1);
- assert (regs->lr_vreg[2].q == FUNC_LDOUBLE_ARG2);
- assert (regs->lr_vreg[3].q == FUNC_LDOUBLE_ARG3);
- assert (regs->lr_vreg[4].q == FUNC_LDOUBLE_ARG4);
- assert (regs->lr_vreg[5].q == FUNC_LDOUBLE_ARG5);
- assert (regs->lr_vreg[6].q == FUNC_LDOUBLE_ARG6);
- assert (regs->lr_vreg[7].q == FUNC_LDOUBLE_ARG7);
+ assert (regs_vec_to_ldouble (regs, 0) == FUNC_LDOUBLE_ARG0);
+ assert (regs_vec_to_ldouble (regs, 1) == FUNC_LDOUBLE_ARG1);
+ assert (regs_vec_to_ldouble (regs, 2) == FUNC_LDOUBLE_ARG2);
+ assert (regs_vec_to_ldouble (regs, 3) == FUNC_LDOUBLE_ARG3);
+ assert (regs_vec_to_ldouble (regs, 4) == FUNC_LDOUBLE_ARG4);
+ assert (regs_vec_to_ldouble (regs, 5) == FUNC_LDOUBLE_ARG5);
+ assert (regs_vec_to_ldouble (regs, 6) == FUNC_LDOUBLE_ARG6);
+ assert (regs_vec_to_ldouble (regs, 7) == FUNC_LDOUBLE_ARG7);
}
else
abort ();
@@ -117,48 +186,56 @@ la_aarch64_gnu_pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook,
{
printf ("pltexit: symname=%s, st_value=%#lx, ndx=%u\n",
symname, (long int) sym->st_value, ndx);
+ printf (" inregs->lr_sve=%d\n", inregs->lr_sve);
+ if (inregs->lr_sve > 0)
+ for (int i = 0; i < array_length (inregs->lr_vreg); i++)
+ printf (" inregs->lr_vreg[%d]=%p\n", i, inregs->lr_vreg[i].z);
+ printf (" outregs->lr_sve=%d\n", outregs->lrv_sve);
+ if (outregs->lrv_sve > 0)
+ for (int i = 0; i < array_length (outregs->lrv_vreg); i++)
+ printf (" outregs->lr_vreg[%d]=%p\n", i, outregs->lrv_vreg[i].z);
if (strcmp (symname, "tst_audit27_func_float") == 0)
{
- assert (inregs->lr_vreg[0].s == FUNC_FLOAT_ARG0);
- assert (inregs->lr_vreg[1].s == FUNC_FLOAT_ARG1);
- assert (inregs->lr_vreg[2].s == FUNC_FLOAT_ARG2);
- assert (inregs->lr_vreg[3].s == FUNC_FLOAT_ARG3);
- assert (inregs->lr_vreg[4].s == FUNC_FLOAT_ARG4);
- assert (inregs->lr_vreg[5].s == FUNC_FLOAT_ARG5);
- assert (inregs->lr_vreg[6].s == FUNC_FLOAT_ARG6);
- assert (inregs->lr_vreg[7].s == FUNC_FLOAT_ARG7);
-
- assert (outregs->lrv_vreg[0].s == FUNC_FLOAT_RET);
+ assert (regs_vec_to_float (inregs, 0) == FUNC_FLOAT_ARG0);
+ assert (regs_vec_to_float (inregs, 1) == FUNC_FLOAT_ARG1);
+ assert (regs_vec_to_float (inregs, 2) == FUNC_FLOAT_ARG2);
+ assert (regs_vec_to_float (inregs, 3) == FUNC_FLOAT_ARG3);
+ assert (regs_vec_to_float (inregs, 4) == FUNC_FLOAT_ARG4);
+ assert (regs_vec_to_float (inregs, 5) == FUNC_FLOAT_ARG5);
+ assert (regs_vec_to_float (inregs, 6) == FUNC_FLOAT_ARG6);
+ assert (regs_vec_to_float (inregs, 7) == FUNC_FLOAT_ARG7);
+
+ assert (ret_vec_to_float (outregs, 0) == FUNC_FLOAT_RET);
}
else if (strcmp (symname, "tst_audit27_func_double") == 0)
{
- assert (inregs->lr_vreg[0].d == FUNC_DOUBLE_ARG0);
- assert (inregs->lr_vreg[1].d == FUNC_DOUBLE_ARG1);
- assert (inregs->lr_vreg[2].d == FUNC_DOUBLE_ARG2);
- assert (inregs->lr_vreg[3].d == FUNC_DOUBLE_ARG3);
- assert (inregs->lr_vreg[4].d == FUNC_DOUBLE_ARG4);
- assert (inregs->lr_vreg[5].d == FUNC_DOUBLE_ARG5);
- assert (inregs->lr_vreg[6].d == FUNC_DOUBLE_ARG6);
- assert (inregs->lr_vreg[7].d == FUNC_DOUBLE_ARG7);
-
- assert (outregs->lrv_vreg[0].d == FUNC_DOUBLE_RET);
+ assert (regs_vec_to_double (inregs, 0) == FUNC_DOUBLE_ARG0);
+ assert (regs_vec_to_double (inregs, 1) == FUNC_DOUBLE_ARG1);
+ assert (regs_vec_to_double (inregs, 2) == FUNC_DOUBLE_ARG2);
+ assert (regs_vec_to_double (inregs, 3) == FUNC_DOUBLE_ARG3);
+ assert (regs_vec_to_double (inregs, 4) == FUNC_DOUBLE_ARG4);
+ assert (regs_vec_to_double (inregs, 5) == FUNC_DOUBLE_ARG5);
+ assert (regs_vec_to_double (inregs, 6) == FUNC_DOUBLE_ARG6);
+ assert (regs_vec_to_double (inregs, 7) == FUNC_DOUBLE_ARG7);
+
+ assert (ret_vec_to_double (outregs, 0) == FUNC_DOUBLE_RET);
}
else if (strcmp (symname, "tst_audit27_func_ldouble") == 0)
{
- assert (inregs->lr_vreg[0].q == FUNC_LDOUBLE_ARG0);
- assert (inregs->lr_vreg[1].q == FUNC_LDOUBLE_ARG1);
- assert (inregs->lr_vreg[2].q == FUNC_LDOUBLE_ARG2);
- assert (inregs->lr_vreg[3].q == FUNC_LDOUBLE_ARG3);
- assert (inregs->lr_vreg[4].q == FUNC_LDOUBLE_ARG4);
- assert (inregs->lr_vreg[5].q == FUNC_LDOUBLE_ARG5);
- assert (inregs->lr_vreg[6].q == FUNC_LDOUBLE_ARG6);
- assert (inregs->lr_vreg[7].q == FUNC_LDOUBLE_ARG7);
-
- assert (outregs->lrv_vreg[0].q == FUNC_LDOUBLE_RET);
+ assert (regs_vec_to_ldouble (inregs, 0) == FUNC_LDOUBLE_ARG0);
+ assert (regs_vec_to_ldouble (inregs, 1) == FUNC_LDOUBLE_ARG1);
+ assert (regs_vec_to_ldouble (inregs, 2) == FUNC_LDOUBLE_ARG2);
+ assert (regs_vec_to_ldouble (inregs, 3) == FUNC_LDOUBLE_ARG3);
+ assert (regs_vec_to_ldouble (inregs, 4) == FUNC_LDOUBLE_ARG4);
+ assert (regs_vec_to_ldouble (inregs, 5) == FUNC_LDOUBLE_ARG5);
+ assert (regs_vec_to_ldouble (inregs, 6) == FUNC_LDOUBLE_ARG6);
+ assert (regs_vec_to_ldouble (inregs, 7) == FUNC_LDOUBLE_ARG7);
+
+ assert (ret_vec_to_ldouble (outregs, 0) == FUNC_LDOUBLE_RET);
}
else
- abort ();
+ return 0;
/* Clobber the q registers on exit. */
uint8_t v = 0xff;
diff --git a/sysdeps/aarch64/tst-auditmod28.c b/sysdeps/aarch64/tst-auditmod28.c
new file mode 100644
index 0000000000..53a2162bfb
--- /dev/null
+++ b/sysdeps/aarch64/tst-auditmod28.c
@@ -0,0 +1,193 @@
+/* Check DT_AUDIT for aarch64 specific ABI.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <array_length.h>
+#include <assert.h>
+#include <link.h>
+#include <string.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "tst-audit28mod.h"
+
+#define TEST_NAME "tst-audit28"
+#define TEST_FUNC "tst_audit28_func"
+
+#define AUDIT28_COOKIE 0
+
+unsigned int
+la_version (unsigned int v)
+{
+ return v;
+}
+
+unsigned int
+la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
+{
+ const char *p = strrchr (map->l_name, '/');
+ const char *l_name = p == NULL ? map->l_name : p + 1;
+ uintptr_t ck = -1;
+ if (strncmp (l_name, TEST_NAME, strlen (TEST_NAME)) == 0)
+ ck = AUDIT28_COOKIE;
+ *cookie = ck;
+ printf ("objopen: %ld, %s [%ld]\n", lmid, l_name, ck);
+ return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO;
+}
+
+ElfW(Addr)
+la_aarch64_gnu_pltenter (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook,
+ uintptr_t *defcook, La_aarch64_regs *regs,
+ unsigned int *flags, const char *symname,
+ long int *framesizep)
+{
+ printf ("pltenter: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n",
+ symname, (long int) sym->st_value, ndx, *flags);
+ printf (" regs->lr_sve=%d\n", regs->lr_sve);
+ if (regs->lr_sve > 0)
+ for (int i = 0; i < array_length (regs->lr_vreg); i++)
+ printf (" inregs->lr_vreg[%d]=%p\n", i, regs->lr_vreg[i].z);
+
+
+ if (strcmp (symname, TEST_FUNC "_sve_args") == 0)
+ {
+ svint8_t z0 = svld1_s8 (svptrue_b8 (),
+ (const int8_t *) regs->lr_vreg[0].z);
+ svint16_t z1 = svld1_s16 (svptrue_b16 (),
+ (const int16_t *) regs->lr_vreg[1].z);
+ svint32_t z2 = svld1_s32 (svptrue_b32 (),
+ (const int32_t *) regs->lr_vreg[2].z);
+ svint64_t z3 = svld1_s64 (svptrue_b64 (),
+ (const int64_t *) regs->lr_vreg[3].z);
+ svuint8_t z4 = svld1_u8 (svptrue_b8 (),
+ (const uint8_t *) regs->lr_vreg[4].z);
+ svuint16_t z5 = svld1_u16 (svptrue_b16 (),
+ (const uint16_t *) regs->lr_vreg[5].z);
+ svuint32_t z6 = svld1_u32 (svptrue_b32 (),
+ (const uint32_t *) regs->lr_vreg[6].z);
+ svuint64_t z7 = svld1_u64 (svptrue_b64 (),
+ (const uint64_t *) regs->lr_vreg[7].z);
+ assert (svptest_any (svptrue_b8 (), svcmpeq_s8 (svptrue_b8 (),
+ z0, sve_args_z0 ())));
+ assert (svptest_any (svptrue_b16 (), svcmpeq_s16 (svptrue_b16 (),
+ z1, sve_args_z1 ())));
+ assert (svptest_any (svptrue_b32 (), svcmpeq_s32 (svptrue_b32 (),
+ z2, sve_args_z2 ())));
+ assert (svptest_any (svptrue_b64 (), svcmpeq_s64 (svptrue_b64 (),
+ z3, sve_args_z3 ())));
+ assert (svptest_any (svptrue_b8 (), svcmpeq_u8 (svptrue_b8 (),
+ z4, sve_args_z4 ())));
+ assert (svptest_any (svptrue_b16 (), svcmpeq_u16 (svptrue_b16 (),
+ z5, sve_args_z5 ())));
+ assert (svptest_any (svptrue_b32 (), svcmpeq_u32 (svptrue_b32 (),
+ z6, sve_args_z6 ())));
+ assert (svptest_any (svptrue_b64 (), svcmpeq_u64 (svptrue_b64 (),
+ z7, sve_args_z7 ())));
+ }
+ else
+ abort ();
+
+ /* Clobber the q registers on exit. */
+ uint8_t v = 0xff;
+ asm volatile ("dup z0.b, %w0" : : "r" (v) : "z0");
+ asm volatile ("dup z1.b, %w0" : : "r" (v) : "z1");
+ asm volatile ("dup z2.b, %w0" : : "r" (v) : "z2");
+ asm volatile ("dup z3.b, %w0" : : "r" (v) : "z3");
+ asm volatile ("dup z4.b, %w0" : : "r" (v) : "z4");
+ asm volatile ("dup z5.b, %w0" : : "r" (v) : "z5");
+ asm volatile ("dup z6.b, %w0" : : "r" (v) : "z6");
+ asm volatile ("dup z7.b, %w0" : : "r" (v) : "z7");
+
+ *framesizep = 1024;
+
+ return sym->st_value;
+}
+
+unsigned int
+la_aarch64_gnu_pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook,
+ uintptr_t *defcook,
+ const struct La_aarch64_regs *inregs,
+ struct La_aarch64_retval *outregs,
+ const char *symname)
+{
+ printf ("pltexit: symname=%s, st_value=%#lx, ndx=%u\n",
+ symname, (long int) sym->st_value, ndx);
+ printf (" inregs->lr_sve=%d\n", inregs->lr_sve);
+ if (inregs->lr_sve > 0)
+ for (int i = 0; i < array_length (inregs->lr_vreg); i++)
+ printf (" inregs->lr_vreg[%d]=%p\n", i, inregs->lr_vreg[i].z);
+ printf (" outregs->lr_sve=%d\n", outregs->lrv_sve);
+ if (outregs->lrv_sve > 0)
+ for (int i = 0; i < array_length (outregs->lrv_vreg); i++)
+ printf (" outregs->lr_vreg[%d]=%p\n", i, outregs->lrv_vreg[i].z);
+
+ if (strcmp (symname, TEST_FUNC "_sve_args") == 0)
+ {
+ svint8_t z0 = svld1_s8 (svptrue_b8 (),
+ (const int8_t *) inregs->lr_vreg[0].z);
+ svint16_t z1 = svld1_s16 (svptrue_b16 (),
+ (const int16_t *) inregs->lr_vreg[1].z);
+ svint32_t z2 = svld1_s32 (svptrue_b32 (),
+ (const int32_t *) inregs->lr_vreg[2].z);
+ svint64_t z3 = svld1_s64 (svptrue_b64 (),
+ (const int64_t *) inregs->lr_vreg[3].z);
+ svuint8_t z4 = svld1_u8 (svptrue_b8 (),
+ (const uint8_t *) inregs->lr_vreg[4].z);
+ svuint16_t z5 = svld1_u16 (svptrue_b16 (),
+ (const uint16_t *) inregs->lr_vreg[5].z);
+ svuint32_t z6 = svld1_u32 (svptrue_b32 (),
+ (const uint32_t *) inregs->lr_vreg[6].z);
+ svuint64_t z7 = svld1_u64 (svptrue_b64 (),
+ (const uint64_t *) inregs->lr_vreg[7].z);
+ assert (svptest_any (svptrue_b8 (), svcmpeq_s8 (svptrue_b8 (),
+ z0, sve_args_z0 ())));
+ assert (svptest_any (svptrue_b16 (), svcmpeq_s16 (svptrue_b16 (),
+ z1, sve_args_z1 ())));
+ assert (svptest_any (svptrue_b32 (), svcmpeq_s32 (svptrue_b32 (),
+ z2, sve_args_z2 ())));
+ assert (svptest_any (svptrue_b64 (), svcmpeq_s64 (svptrue_b64 (),
+ z3, sve_args_z3 ())));
+ assert (svptest_any (svptrue_b8 (), svcmpeq_u8 (svptrue_b8 (),
+ z4, sve_args_z4 ())));
+ assert (svptest_any (svptrue_b16 (), svcmpeq_u16 (svptrue_b16 (),
+ z5, sve_args_z5 ())));
+ assert (svptest_any (svptrue_b32 (), svcmpeq_u32 (svptrue_b32 (),
+ z6, sve_args_z6 ())));
+ assert (svptest_any (svptrue_b64 (), svcmpeq_u64 (svptrue_b64 (),
+ z7, sve_args_z7 ())));
+
+ svint8_t r0 = svld1_s8 (svptrue_b8 (),
+ (const int8_t *) outregs->lrv_vreg[0].z);
+ assert (svptest_any (svptrue_b8 (), svcmpeq_s8 (svptrue_b8 (),
+ r0, sve_ret ())));
+ }
+ else
+ abort ();
+
+ /* Clobber the q registers on exit. */
+ uint8_t v = 0xff;
+ asm volatile ("dup z0.b, %w0" : : "r" (v) : "z0");
+ asm volatile ("dup z1.b, %w0" : : "r" (v) : "z1");
+ asm volatile ("dup z2.b, %w0" : : "r" (v) : "z2");
+ asm volatile ("dup z3.b, %w0" : : "r" (v) : "z3");
+ asm volatile ("dup z4.b, %w0" : : "r" (v) : "z4");
+ asm volatile ("dup z5.b, %w0" : : "r" (v) : "z5");
+ asm volatile ("dup z6.b, %w0" : : "r" (v) : "z6");
+ asm volatile ("dup z7.b, %w0" : : "r" (v) : "z7");
+
+ return 0;
+}
diff --git a/sysdeps/alpha/dl-machine.h b/sysdeps/alpha/dl-machine.h
index 9e327b7f17..90a76c547b 100644
--- a/sysdeps/alpha/dl-machine.h
+++ b/sysdeps/alpha/dl-machine.h
@@ -509,7 +509,7 @@ auto inline void
__attribute__ ((always_inline))
elf_machine_lazy_rel (struct link_map *map,
Elf64_Addr l_addr, const Elf64_Rela *reloc,
- int skip_ifunc)
+ int profile, int skip_ifunc)
{
Elf64_Addr * const reloc_addr = (void *)(l_addr + reloc->r_offset);
unsigned long int const r_type = ELF64_R_TYPE (reloc->r_info);
diff --git a/sysdeps/arc/dl-machine.h b/sysdeps/arc/dl-machine.h
index e6ce7f0ff6..787db1205c 100644
--- a/sysdeps/arc/dl-machine.h
+++ b/sysdeps/arc/dl-machine.h
@@ -327,7 +327,7 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
inline void
__attribute__ ((always_inline))
elf_machine_lazy_rel (struct link_map *map, ElfW(Addr) l_addr,
- const ElfW(Rela) *reloc, int skip_ifunc)
+ const ElfW(Rela) *reloc, int profile, int skip_ifunc)
{
ElfW(Addr) *const reloc_addr = (void *) (l_addr + reloc->r_offset);
const unsigned int r_type = ELFW (R_TYPE) (reloc->r_info);
diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h
index eb13cb8b57..467a80d656 100644
--- a/sysdeps/arm/dl-machine.h
+++ b/sysdeps/arm/dl-machine.h
@@ -625,7 +625,7 @@ auto inline void
__attribute__ ((always_inline))
elf_machine_lazy_rel (struct link_map *map,
Elf32_Addr l_addr, const Elf32_Rel *reloc,
- int skip_ifunc)
+ int profile, int skip_ifunc)
{
Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
diff --git a/sysdeps/csky/dl-machine.h b/sysdeps/csky/dl-machine.h
index b08f06d74c..55925596b5 100644
--- a/sysdeps/csky/dl-machine.h
+++ b/sysdeps/csky/dl-machine.h
@@ -342,7 +342,7 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
auto inline void __attribute__ ((unused, always_inline))
elf_machine_lazy_rel (struct link_map *map,
Elf32_Addr l_addr, const Elf32_Rela *reloc,
- int skip_ifunc)
+ int profile, int skip_ifunc)
{
Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
diff --git a/sysdeps/hppa/dl-machine.h b/sysdeps/hppa/dl-machine.h
index ded9c193d6..2ad78dc18b 100644
--- a/sysdeps/hppa/dl-machine.h
+++ b/sysdeps/hppa/dl-machine.h
@@ -796,7 +796,7 @@ elf_machine_rela_relative (Elf32_Addr l_addr,
auto void __attribute__((always_inline))
elf_machine_lazy_rel (struct link_map *map,
Elf32_Addr l_addr, const Elf32_Rela *reloc,
- int skip_ifunc)
+ int profile, int skip_ifunc)
{
/* We don't have anything to do here. elf_machine_runtime_setup has
done all the relocs already. */
diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h
index 4751738731..14a93c7717 100644
--- a/sysdeps/i386/dl-machine.h
+++ b/sysdeps/i386/dl-machine.h
@@ -649,7 +649,7 @@ auto inline void
__attribute__ ((always_inline))
elf_machine_lazy_rel (struct link_map *map,
Elf32_Addr l_addr, const Elf32_Rel *reloc,
- int skip_ifunc)
+ int profile, int skip_ifunc)
{
Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
diff --git a/sysdeps/ia64/dl-machine.h b/sysdeps/ia64/dl-machine.h
index 4403e7767a..46e2d26406 100644
--- a/sysdeps/ia64/dl-machine.h
+++ b/sysdeps/ia64/dl-machine.h
@@ -493,7 +493,7 @@ auto inline void
__attribute ((always_inline))
elf_machine_lazy_rel (struct link_map *map,
Elf64_Addr l_addr, const Elf64_Rela *reloc,
- int skip_ifunc)
+ int profile, int skip_ifunc)
{
Elf64_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
const unsigned long int r_type = ELF64_R_TYPE (reloc->r_info);
diff --git a/sysdeps/m68k/dl-machine.h b/sysdeps/m68k/dl-machine.h
index 86a8c67e2a..e0acf2d2d6 100644
--- a/sysdeps/m68k/dl-machine.h
+++ b/sysdeps/m68k/dl-machine.h
@@ -314,7 +314,7 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
auto inline void __attribute__ ((unused, always_inline))
elf_machine_lazy_rel (struct link_map *map,
Elf32_Addr l_addr, const Elf32_Rela *reloc,
- int skip_ifunc)
+ int profile, int skip_ifunc)
{
Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
if (ELF32_R_TYPE (reloc->r_info) == R_68K_JMP_SLOT)
diff --git a/sysdeps/microblaze/dl-machine.h b/sysdeps/microblaze/dl-machine.h
index e460f6f195..aa69de35f3 100644
--- a/sysdeps/microblaze/dl-machine.h
+++ b/sysdeps/microblaze/dl-machine.h
@@ -288,7 +288,7 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
auto inline void
elf_machine_lazy_rel (struct link_map *map,
Elf32_Addr l_addr, const Elf32_Rela *reloc,
- int skip_ifunc)
+ int profile, int skip_ifunc)
{
Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
if (ELF32_R_TYPE (reloc->r_info) == R_MICROBLAZE_JUMP_SLOT)
diff --git a/sysdeps/mips/dl-machine.h b/sysdeps/mips/dl-machine.h
index b74d427d64..2efe07d046 100644
--- a/sysdeps/mips/dl-machine.h
+++ b/sysdeps/mips/dl-machine.h
@@ -728,7 +728,7 @@ auto inline void
__attribute__((always_inline))
elf_machine_lazy_rel (struct link_map *map,
ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
- int skip_ifunc)
+ int profile, int skip_ifunc)
{
ElfW(Addr) *const reloc_addr = (void *) (l_addr + reloc->r_offset);
const unsigned int r_type = ELFW(R_TYPE) (reloc->r_info);
diff --git a/sysdeps/nios2/dl-machine.h b/sysdeps/nios2/dl-machine.h
index e000cd081f..b1338e93dd 100644
--- a/sysdeps/nios2/dl-machine.h
+++ b/sysdeps/nios2/dl-machine.h
@@ -325,7 +325,7 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
auto inline void __attribute__((always_inline))
elf_machine_lazy_rel (struct link_map *map,
ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
- int skip_ifunc)
+ int profile, int skip_ifunc)
{
Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
if (ELF32_R_TYPE (reloc->r_info) == R_NIOS2_JUMP_SLOT)
diff --git a/sysdeps/powerpc/powerpc32/dl-machine.h b/sysdeps/powerpc/powerpc32/dl-machine.h
index ced3a7b659..116c0ac6c5 100644
--- a/sysdeps/powerpc/powerpc32/dl-machine.h
+++ b/sysdeps/powerpc/powerpc32/dl-machine.h
@@ -452,7 +452,7 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
auto inline void __attribute__ ((always_inline))
elf_machine_lazy_rel (struct link_map *map,
Elf32_Addr l_addr, const Elf32_Rela *reloc,
- int skip_ifunc)
+ int profile, int skip_ifunc)
{
/* elf_machine_runtime_setup handles this. */
}
diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h
index b90f407119..56fc9a264d 100644
--- a/sysdeps/powerpc/powerpc64/dl-machine.h
+++ b/sysdeps/powerpc/powerpc64/dl-machine.h
@@ -1040,7 +1040,7 @@ elf_machine_rela (struct link_map *map,
auto inline void __attribute__ ((always_inline))
elf_machine_lazy_rel (struct link_map *map,
Elf64_Addr l_addr, const Elf64_Rela *reloc,
- int skip_ifunc)
+ int profile, int skip_ifunc)
{
/* elf_machine_runtime_setup handles this. */
}
diff --git a/sysdeps/riscv/dl-machine.h b/sysdeps/riscv/dl-machine.h
index 5b0746175c..66c0b95b29 100644
--- a/sysdeps/riscv/dl-machine.h
+++ b/sysdeps/riscv/dl-machine.h
@@ -290,7 +290,7 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
auto inline void
__attribute__ ((always_inline))
elf_machine_lazy_rel (struct link_map *map, ElfW(Addr) l_addr,
- const ElfW(Rela) *reloc, int skip_ifunc)
+ const ElfW(Rela) *reloc, int profile, int skip_ifunc)
{
ElfW(Addr) *const reloc_addr = (void *) (l_addr + reloc->r_offset);
const unsigned int r_type = ELFW (R_TYPE) (reloc->r_info);
diff --git a/sysdeps/s390/s390-32/dl-machine.h b/sysdeps/s390/s390-32/dl-machine.h
index 73cc007e34..65e5e2da2f 100644
--- a/sysdeps/s390/s390-32/dl-machine.h
+++ b/sysdeps/s390/s390-32/dl-machine.h
@@ -496,7 +496,7 @@ auto inline void
__attribute__ ((always_inline))
elf_machine_lazy_rel (struct link_map *map,
Elf32_Addr l_addr, const Elf32_Rela *reloc,
- int skip_ifunc)
+ int profile, int skip_ifunc)
{
Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
diff --git a/sysdeps/s390/s390-64/dl-machine.h b/sysdeps/s390/s390-64/dl-machine.h
index aa9d524bac..28af87d8f3 100644
--- a/sysdeps/s390/s390-64/dl-machine.h
+++ b/sysdeps/s390/s390-64/dl-machine.h
@@ -450,7 +450,7 @@ auto inline void
__attribute__ ((always_inline))
elf_machine_lazy_rel (struct link_map *map,
Elf64_Addr l_addr, const Elf64_Rela *reloc,
- int skip_ifunc)
+ int profile, int skip_ifunc)
{
Elf64_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
const unsigned int r_type = ELF64_R_TYPE (reloc->r_info);
diff --git a/sysdeps/sh/dl-machine.h b/sysdeps/sh/dl-machine.h
index 122b417a17..18fb2cb138 100644
--- a/sysdeps/sh/dl-machine.h
+++ b/sysdeps/sh/dl-machine.h
@@ -447,7 +447,7 @@ auto inline void
__attribute__ ((always_inline))
elf_machine_lazy_rel (struct link_map *map,
Elf32_Addr l_addr, const Elf32_Rela *reloc,
- int skip_ifunc)
+ int profile, int skip_ifunc)
{
Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
/* Check for unexpected PLT reloc type. */
diff --git a/sysdeps/sparc/sparc32/dl-machine.h b/sysdeps/sparc/sparc32/dl-machine.h
index 0269e458ea..796d8dbfa4 100644
--- a/sysdeps/sparc/sparc32/dl-machine.h
+++ b/sysdeps/sparc/sparc32/dl-machine.h
@@ -549,7 +549,7 @@ auto inline void
__attribute__ ((always_inline))
elf_machine_lazy_rel (struct link_map *map,
Elf32_Addr l_addr, const Elf32_Rela *reloc,
- int skip_ifunc)
+ int profile, int skip_ifunc)
{
Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h
index bbd4566d8a..7568a7d6a6 100644
--- a/sysdeps/sparc/sparc64/dl-machine.h
+++ b/sysdeps/sparc/sparc64/dl-machine.h
@@ -659,7 +659,7 @@ auto inline void
__attribute__ ((always_inline))
elf_machine_lazy_rel (struct link_map *map,
Elf64_Addr l_addr, const Elf64_Rela *reloc,
- int skip_ifunc)
+ int profile, int skip_ifunc)
{
Elf64_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
const unsigned int r_type = ELF64_R_TYPE (reloc->r_info);
diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
index b3ed4dd467..ac8f1eb732 100644
--- a/sysdeps/x86_64/dl-machine.h
+++ b/sysdeps/x86_64/dl-machine.h
@@ -540,7 +540,7 @@ auto inline void
__attribute ((always_inline))
elf_machine_lazy_rel (struct link_map *map,
ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
- int skip_ifunc)
+ int profile, int skip_ifunc)
{
ElfW(Addr) *const reloc_addr = (void *) (l_addr + reloc->r_offset);
const unsigned long int r_type = ELFW(R_TYPE) (reloc->r_info);