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 skip_ifunc
+#ifndef NESTING
+ , struct link_map *boot_map
+#endif
+ )
{
const ElfW(Rel) *r = (const void *) reladdr;
const ElfW(Rel) *end = (const void *) (reladdr + relsize);
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);
+ (void *) (l_addr + r->r_offset), skip_ifunc
+#ifndef NESTING
+ , boot_map
+#endif
+ );
}
#if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP
&symtab[ELFW(R_SYM) (r2->r_info)],
&map->l_versions[ndx],
(void *) (l_addr + r2->r_offset),
- skip_ifunc);
+ skip_ifunc
+#ifndef NESTING
+ , boot_map
+#endif
+ );
}
#endif
}
else
# endif
elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
- (void *) (l_addr + r->r_offset), skip_ifunc);
+ (void *) (l_addr + r->r_offset), skip_ifunc
+#ifndef NESTING
+ , boot_map
+#endif
+ );
# ifdef ELF_MACHINE_IRELATIVE
if (r2 != NULL)
if (ELFW(R_TYPE) (r2->r_info) == ELF_MACHINE_IRELATIVE)
elf_machine_rel (map, r2, &symtab[ELFW(R_SYM) (r2->r_info)],
NULL, (void *) (l_addr + r2->r_offset),
- skip_ifunc);
+ skip_ifunc
+#ifndef NESTING
+ , boot_map
+#endif
+ );
# endif
}
#endif
auto inline void __attribute__((always_inline))
elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
const ElfW(Sym) *sym, const struct r_found_version *version,
- void *const reloc_addr, int skip_ifunc);
+ void *const reloc_addr, int skip_ifunc
+#ifndef NESTING
+ , struct link_map *boot_map
+#endif
+ );
auto inline void __attribute__((always_inline))
elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
void *const reloc_addr);
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. */
+#ifndef NESTING
+# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, skip_ifunc, test_rel, boot_map) \
+ do { \
+ struct { ElfW(Addr) start, size; \
+ __typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative; int lazy; } \
+ ranges[2] = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }; \
+ \
+ if ((map)->l_info[DT_##RELOC]) \
+ { \
+ ranges[0].start = D_PTR ((map), l_info[DT_##RELOC]); \
+ ranges[0].size = (map)->l_info[DT_##RELOC##SZ]->d_un.d_val; \
+ if (map->l_info[VERSYMIDX (DT_##RELOC##COUNT)] != NULL) \
+ ranges[0].nrelative \
+ = map->l_info[VERSYMIDX (DT_##RELOC##COUNT)]->d_un.d_val; \
+ } \
+ if ((map)->l_info[DT_PLTREL] \
+ && (!test_rel || (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC)) \
+ { \
+ ElfW(Addr) start = D_PTR ((map), l_info[DT_JMPREL]); \
+ ElfW(Addr) size = (map)->l_info[DT_PLTRELSZ]->d_un.d_val; \
+ \
+ if (ranges[0].start + ranges[0].size == (start + size)) \
+ ranges[0].size -= size; \
+ if (ELF_DURING_STARTUP \
+ || (!(do_lazy) \
+ && (ranges[0].start + ranges[0].size) == start)) \
+ { \
+ /* Combine processing the sections. */ \
+ ranges[0].size += size; \
+ } \
+ else \
+ { \
+ ranges[1].start = start; \
+ ranges[1].size = size; \
+ ranges[1].lazy = (do_lazy); \
+ } \
+ } \
+ \
+ if (ELF_DURING_STARTUP) \
+ elf_dynamic_do_##reloc ((map), ranges[0].start, ranges[0].size, \
+ ranges[0].nrelative, 0, skip_ifunc, boot_map); \
+ else \
+ { \
+ int ranges_index; \
+ for (ranges_index = 0; ranges_index < 2; ++ranges_index) \
+ elf_dynamic_do_##reloc ((map), \
+ ranges[ranges_index].start, \
+ ranges[ranges_index].size, \
+ ranges[ranges_index].nrelative, \
+ ranges[ranges_index].lazy, \
+ skip_ifunc, boot_map); \
+ } \
+ } while (0)
+#else /* NESTING */
# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, skip_ifunc, test_rel) \
do { \
struct { ElfW(Addr) start, size; \
skip_ifunc); \
} \
} while (0)
+#endif /* NESTING */
# if ELF_MACHINE_NO_REL || ELF_MACHINE_NO_RELA
# define _ELF_CHECK_REL 0
# define _ELF_CHECK_REL 1
# endif
+#ifndef NESTING
+# if ! ELF_MACHINE_NO_REL
+# include "do-rel.h"
+# define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc, boot_map) \
+ _ELF_DYNAMIC_DO_RELOC (REL, Rel, map, lazy, skip_ifunc, _ELF_CHECK_REL, boot_map)
+# else
+# define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc, boot_map) /* 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, boot_map) \
+ _ELF_DYNAMIC_DO_RELOC (RELA, Rela, map, lazy, skip_ifunc, _ELF_CHECK_REL, boot_map)
+# else
+# define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc, boot_map) /* Nothing to do. */
+# endif
+
+/* This can't just be an inline function because GCC is too dumb
+ to inline functions containing inlines themselves. */
+# define ELF_DYNAMIC_RELOCATE(map, lazy, consider_profile, skip_ifunc, boot_map) \
+ do { \
+ int edr_lazy = elf_machine_runtime_setup ((map), (lazy), \
+ (consider_profile)); \
+ ELF_DYNAMIC_DO_REL ((map), edr_lazy, skip_ifunc, boot_map); \
+ ELF_DYNAMIC_DO_RELA ((map), edr_lazy, skip_ifunc, boot_map); \
+ } while (0)
+#else /* NESTING */
# if ! ELF_MACHINE_NO_REL
# include "do-rel.h"
# define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc) \
ELF_DYNAMIC_DO_REL ((map), edr_lazy, skip_ifunc); \
ELF_DYNAMIC_DO_RELA ((map), edr_lazy, skip_ifunc); \
} while (0)
+#endif /* NESTING */
#endif