/* Machine-dependent ELF dynamic relocation inline functions. SH version.
- Copyright (C) 1999-2013 Free Software Foundation, Inc.
+ Copyright (C) 1999-2024 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/>. */
#ifndef dl_machine_h
#define dl_machine_h
#include <sys/param.h>
#include <sysdep.h>
#include <assert.h>
+#include <dl-static-tls.h>
+#include <dl-machine-rel.h>
/* Return nonzero iff ELF header is compatible with the running host. */
static inline int __attribute__ ((unused))
entries will jump to the on-demand fixup code in dl-runtime.c. */
static inline int __attribute__ ((unused, always_inline))
-elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
+elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
+ int lazy, int profile)
{
Elf32_Addr *got;
extern void _dl_runtime_resolve (Elf32_Word);
to intercept the calls to collect information. In this case we
don't store the address in the GOT so that all future calls also
end in this function. */
+#ifdef SHARED
if (profile)
{
got[2] = (Elf32_Addr) &_dl_runtime_profile;
GL(dl_profile_map) = l;
}
else
+#endif
/* This function will get called to fix up the GOT entry indicated by
the offset on the stack, and then jump to the resolved address. */
got[2] = (Elf32_Addr) &_dl_runtime_resolve;
add r0,r12\n\
.align 2\n\
1: .long _GLOBAL_OFFSET_TABLE_\n\
-2: ! See if we were run as a command with the executable file\n\
- ! name as an extra leading argument.\n\
- mov.l .L_dl_skip_args,r0\n\
- mov.l @(r0,r12),r0\n\
- mov.l @r0,r0\n\
- ! Get the original argument count.\n\
+2: ! Get the original argument count.\n\
mov.l @r15,r5\n\
- ! Subtract _dl_skip_args from it.\n\
- sub r0,r5\n\
- ! Adjust the stack pointer to skip _dl_skip_args words.\n\
- shll2 r0\n\
- add r0,r15\n\
- ! Store back the modified argument count.\n\
- mov.l r5,@r15\n\
! Compute argv address and envp.\n\
mov r15,r6\n\
add #4,r6\n\
.align 2\n\
.L_dl_start:\n\
.long _dl_start@PLT\n\
-.L_dl_skip_args:\n\
- .long _dl_skip_args@GOT\n\
.L_dl_init:\n\
- .long _dl_init_internal@PLT\n\
+ .long _dl_init@PLT\n\
.L_dl_loaded:\n\
.long _rtld_local@GOT\n\
.L_dl_fini:\n\
/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or
TLS variable, so undefined references should not be allowed to
define the value.
- ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
+ ELF_RTYPE_CLASS_COPY iff TYPE should not be allowed to resolve to one
of the main executable's symbols, as for a COPY reloc. */
#define elf_machine_type_class(type) \
((((type) == R_SH_JMP_SLOT || (type) == R_SH_TLS_DTPMOD32 \
static inline Elf32_Addr
elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+ const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
const Elf32_Rela *reloc,
Elf32_Addr *reloc_addr, Elf32_Addr value)
{
#endif /* !dl_machine_h */
-/* SH never uses Elf32_Rel relocations. */
-#define ELF_MACHINE_NO_REL 1
-
#ifdef RESOLVE_MAP
/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
MAP is the object containing the reloc. */
-auto inline void
+static inline void
__attribute ((always_inline))
-elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
- const Elf32_Sym *sym, const struct r_found_version *version,
+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+ const Elf32_Rela *reloc, const Elf32_Sym *sym,
+ const struct r_found_version *version,
void *const reloc_addr_arg, int skip_ifunc)
{
Elf32_Addr *const reloc_addr = reloc_addr_arg;
} \
}
- if (__builtin_expect (r_type == R_SH_RELATIVE, 0))
+ if (__glibc_unlikely (r_type == R_SH_RELATIVE))
{
#ifndef RTLD_BOOTSTRAP
if (map != &GL(dl_rtld_map)) /* Already done in rtld itself. */
}
}
#ifndef RTLD_BOOTSTRAP
- else if (__builtin_expect (r_type == R_SH_NONE, 0))
+ else if (__glibc_unlikely (r_type == R_SH_NONE))
return;
#endif
else
{
const Elf32_Sym *const refsym = sym;
- struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+ struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
+ r_type);
- value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value;
+ value = SYMBOL_ADDRESS (sym_map, sym, true);
value += reloc->r_addend;
switch (r_type)
strtab = (const char *) D_PTR (map, l_info[DT_STRTAB]);
_dl_error_printf ("\
%s: Symbol `%s' has different size in shared object, consider re-linking\n",
- rtld_progname ?: "<program name unknown>",
- strtab + refsym->st_name);
+ RTLD_PROGNAME, strtab + refsym->st_name);
}
memcpy (reloc_addr_arg, (void *) value,
MIN (sym->st_size, refsym->st_size));
break;
case R_SH_DIR32:
{
-#ifndef RTLD_BOOTSTRAP
+#if !defined RTLD_BOOTSTRAP
/* This is defined in rtld.c, but nowhere in the static
libc.a; make the reference weak so static programs can
still link. This declaration cannot be done when
binding found in the user program or a loaded library
rather than the dynamic linker's built-in definitions
used while loading those libraries. */
- value -= map->l_addr + refsym->st_value + reloc->r_addend;
+ value -= SYMBOL_ADDRESS (map, refsym, true) + reloc->r_addend;
#endif
COPY_UNALIGNED_WORD (&value, reloc_addr_arg,
(int) reloc_addr_arg & 3);
}
}
-auto inline void
+static inline void
__attribute__ ((always_inline))
elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
void *const reloc_addr_arg)
#undef COPY_UNALIGNED_WORD
}
-auto inline void
+static inline void
__attribute__ ((always_inline))
-elf_machine_lazy_rel (struct link_map *map,
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
Elf32_Addr l_addr, const Elf32_Rela *reloc,
int skip_ifunc)
{