diff options
Diffstat (limited to 'elf')
-rw-r--r-- | elf/do-rel.h | 7 | ||||
-rw-r--r-- | elf/dynamic-link.h | 43 |
2 files changed, 36 insertions, 14 deletions
diff --git a/elf/do-rel.h b/elf/do-rel.h index 3968937093..5f07544369 100644 --- a/elf/do-rel.h +++ b/elf/do-rel.h @@ -98,7 +98,12 @@ elf_dynamic_do_rel (struct link_map *map, elf_machine_rel_relative (l_addr, relative, (void *) (l_addr + relative->r_offset)); +#ifdef RTLD_BOOTSTRAP + /* The dynamic linker always uses versioning. */ + assert (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL); +#else if (map->l_info[VERSYMIDX (DT_VERSYM)]) +#endif { const ElfW(Half) *const version = (const void *) D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]); @@ -111,10 +116,12 @@ elf_dynamic_do_rel (struct link_map *map, (void *) (l_addr + r->r_offset)); } } +#ifndef RTLD_BOOTSTRAP else for (; r < end; ++r) elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL, (void *) (l_addr + r->r_offset)); +#endif } } diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h index b0baa901fd..f3529970a1 100644 --- a/elf/dynamic-link.h +++ b/elf/dynamic-link.h @@ -141,6 +141,12 @@ elf_get_dynamic_info (struct link_map *l) #ifdef RESOLVE +# ifdef RTLD_BOOTSTRAP +# define ELF_DURING_STARTUP (1) +# else +# define ELF_DURING_STARTUP (0) +# endif + /* Get the definitions of `elf_dynamic_do_rel' and `elf_dynamic_do_rela'. These functions are almost identical, so we use cpp magic to avoid duplicating their code. It cannot be done in a more general function @@ -167,7 +173,7 @@ elf_get_dynamic_info (struct link_map *l) ranges[0].size = (map)->l_info[DT_##RELOC##SZ]->d_un.d_val; \ } \ \ - if ((do_lazy) \ + if ((do_lazy) \ && (map)->l_info[DT_PLTREL] \ && (!test_rel || (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC)) \ { \ @@ -188,7 +194,6 @@ elf_get_dynamic_info (struct link_map *l) # define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, test_rel) \ do { \ struct { ElfW(Addr) start, size; int lazy; } ranges[2]; \ - int ranges_index; \ ranges[0].lazy = 0; \ ranges[0].size = ranges[1].size = 0; \ ranges[0].start = 0; \ @@ -203,26 +208,36 @@ elf_get_dynamic_info (struct link_map *l) { \ ElfW(Addr) start = D_PTR ((map), l_info[DT_JMPREL]); \ \ - if ((do_lazy) \ - /* This test does not only detect whether the relocation \ - sections are in the right order, it also checks whether \ - there is a DT_REL/DT_RELA section. */ \ - || ranges[0].start + ranges[0].size != start) \ + if (! ELF_DURING_STARTUP \ + && ((do_lazy) \ + /* This test does not only detect whether the relocation \ + sections are in the right order, it also checks whether \ + there is a DT_REL/DT_RELA section. */ \ + || ranges[0].start + ranges[0].size != start)) \ { \ ranges[1].start = start; \ ranges[1].size = (map)->l_info[DT_PLTRELSZ]->d_un.d_val; \ ranges[1].lazy = (do_lazy); \ } \ else \ - /* Combine processing the sections. */ \ - ranges[0].size += (map)->l_info[DT_PLTRELSZ]->d_un.d_val; \ + { \ + /* Combine processing the sections. */ \ + assert (ranges[0].start + ranges[0].size == start); \ + ranges[0].size += (map)->l_info[DT_PLTRELSZ]->d_un.d_val; \ + } \ } \ \ - 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].lazy); \ + if (ELF_DURING_STARTUP) \ + elf_dynamic_do_##reloc ((map), ranges[0].start, ranges[0].size, 0); \ + 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].lazy); \ + } \ } while (0) # endif |