/* Do relocations for ELF dynamic linking.
- Copyright (C) 1995-2003, 2004, 2011 Free Software Foundation, Inc.
+ Copyright (C) 1995-2022 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
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
+ <https://www.gnu.org/licenses/>. */
+
+#include <ldsodefs.h>
/* This file may be included twice, to define both
`elf_dynamic_do_rel' and `elf_dynamic_do_rela'. */
relocations; they should be set up to call _dl_runtime_resolve, rather
than fully resolved now. */
-auto inline void __attribute__ ((always_inline))
-elf_dynamic_do_Rel (struct link_map *map,
+static inline void __attribute__ ((always_inline))
+elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
ElfW(Addr) reladdr, ElfW(Addr) relsize,
__typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative,
int lazy, int skip_ifunc)
}
else
# endif
- elf_machine_lazy_rel (map, l_addr, r, skip_ifunc);
+ elf_machine_lazy_rel (map, scope, l_addr, r, 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, scope, l_addr, r2, skip_ifunc);
# endif
}
else
relocations or rela relocations if they are computed as
memory_loc += l_addr... */
if (l_addr != 0)
-# else
- /* ...or we know the object has been prelinked. */
- if (l_addr != 0 || ! map->l_info[VALIDX(DT_GNU_PRELINKED)])
# endif
#endif
for (; relative < r; ++relative)
for (; r < end; ++r)
{
+ ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff;
+ const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (r->r_info)];
+ void *const r_addr_arg = (void *) (l_addr + r->r_offset);
+ const struct r_found_version *rversion = &map->l_versions[ndx];
#if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP
if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE)
{
}
#endif
- ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff;
- elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)],
- &map->l_versions[ndx],
- (void *) (l_addr + r->r_offset), skip_ifunc);
+ elf_machine_rel (map, scope, r, sym, rversion, r_addr_arg,
+ skip_ifunc);
+#if defined SHARED && !defined RTLD_BOOTSTRAP
+ if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_JMP_SLOT
+ && GLRO(dl_naudit) > 0)
+ {
+ struct link_map *sym_map
+ = RESOLVE_MAP (map, scope, &sym, rversion,
+ ELF_MACHINE_JMP_SLOT);
+ if (sym != NULL)
+ _dl_audit_symbind (map, NULL, sym, r_addr_arg, sym_map);
+ }
+#endif
}
#if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP
{
ElfW(Half) ndx
= version[ELFW(R_SYM) (r2->r_info)] & 0x7fff;
- elf_machine_rel (map, r2,
+ elf_machine_rel (map, scope, r2,
&symtab[ELFW(R_SYM) (r2->r_info)],
&map->l_versions[ndx],
(void *) (l_addr + r2->r_offset),
else
{
for (; r < end; ++r)
+ {
+ const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (r->r_info)];
+ void *const r_addr_arg = (void *) (l_addr + r->r_offset);
# ifdef ELF_MACHINE_IRELATIVE
- if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE)
- {
- if (r2 == NULL)
- r2 = r;
- end2 = r;
- }
- else
+ if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE)
+ {
+ if (r2 == NULL)
+ r2 = r;
+ end2 = r;
+ continue;
+ }
# endif
- elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
- (void *) (l_addr + r->r_offset), skip_ifunc);
+ elf_machine_rel (map, scope, r, sym, NULL, r_addr_arg,
+ skip_ifunc);
+# if defined SHARED && !defined RTLD_BOOTSTRAP
+ if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_JMP_SLOT
+ && GLRO(dl_naudit) > 0)
+ {
+ struct link_map *sym_map
+ = RESOLVE_MAP (map, scope, &sym,
+ (struct r_found_version *) NULL,
+ ELF_MACHINE_JMP_SLOT);
+ if (sym != NULL)
+ _dl_audit_symbind (map, NULL , sym,r_addr_arg, sym_map);
+ }
+# endif
+ }
# ifdef ELF_MACHINE_IRELATIVE
if (r2 != NULL)
for (; r2 <= end2; ++r2)
if (ELFW(R_TYPE) (r2->r_info) == ELF_MACHINE_IRELATIVE)
- elf_machine_rel (map, r2, &symtab[ELFW(R_SYM) (r2->r_info)],
+ elf_machine_rel (map, scope, r2, &symtab[ELFW(R_SYM) (r2->r_info)],
NULL, (void *) (l_addr + r2->r_offset),
skip_ifunc);
# endif