From d7dd44133f53e8bcc81e18c11694bee985cd86d0 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 10 Apr 2012 12:57:48 -0700 Subject: Fix ld.so regression. [BZ #13967] * elf/dynamic-link.h (_ELF_DYNAMIC_DO_RELOC): Handle the case where the is a gap between DT_REL(A) and DT_JMPREL. --- elf/dynamic-link.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'elf/dynamic-link.h') diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h index ef01c61f3e..44f53b3c70 100644 --- a/elf/dynamic-link.h +++ b/elf/dynamic-link.h @@ -252,9 +252,10 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp) /* On some machines, notably SPARC, DT_REL* includes DT_JMPREL in its range. Note that according to the ELF spec, this is completely legal! - We are guarenteed that we have one of two situations. Either DT_JMPREL + We are guarenteed that we have one of three situations. Either DT_JMPREL comes immediately after DT_REL*, or there is overlap and DT_JMPREL - consumes precisely the very end of the DT_REL*. */ + 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) \ do { \ @@ -275,19 +276,20 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp) && (!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 (__builtin_expect (ranges[0].size, 1)) \ - ranges[0].size = (start - ranges[0].start); \ + if (ranges[0].start + ranges[0].size == (start + size)) \ + ranges[0].size -= size; \ if (! ELF_DURING_STARTUP && ((do_lazy) || ranges[0].size == 0)) \ { \ ranges[1].start = start; \ - ranges[1].size = (map)->l_info[DT_PLTRELSZ]->d_un.d_val; \ + ranges[1].size = size; \ ranges[1].lazy = (do_lazy); \ } \ else \ { \ /* Combine processing the sections. */ \ - ranges[0].size += (map)->l_info[DT_PLTRELSZ]->d_un.d_val; \ + ranges[0].size += size; \ } \ } \ \ -- cgit 1.4.1