From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jakub Jelinek To: binutils@sources.redhat.com Subject: [PATCH] Fix -z combreloc Date: Fri, 24 Aug 2001 04:26:00 -0000 Message-id: <20010824132945.K5765@sunsite.ms.mff.cuni.cz> X-SW-Source: 2001-08/msg00554.html Hi! I've just commited the following patch before more people start using -z combreloc. RELATIVE records counted in DT_REL{,A}COUNT should be sorted first, not last (that makes much more sense), ie. ld.so can count that relocs from DT_REL{,A} up to DT_REL{,A} + (DT_REL{,A}COUNT - 1) * DT_REL{,A}ENT inclusive are RELATIVE relocs. I was confused by seeing Solaris 8 /usr/lib/libc.so.1 with DT_RELACOUNT set and RELATIVE records sorted last, but it seems /usr/lib/sparcv9/libc.so.1 got it already right and for newly created libraries using Sun ld with -z combreloc RELATIVE records come first even on sparc32. If you disagree, I can back this patch out, but I wanted to avoid too many libs with bad DT_REL*COUNT hanging out there. 2001-08-24 Jakub Jelinek * elflink.h (elf_link_sort_cmp1): Sort RELATIVE relocs first, not last. (elf_link_sort_relocs): Adjust accordingly. --- bfd/elflink.h.jj Thu Aug 23 17:30:38 2001 +++ bfd/elflink.h Fri Aug 24 13:01:20 2001 @@ -4300,9 +4300,9 @@ elf_link_sort_cmp1 (A, B) relativeb = b->type == reloc_class_relative; if (relativea < relativeb) - return -1; - if (relativea > relativeb) return 1; + if (relativea > relativeb) + return -1; if (ELF_R_SYM (a->u.rel.r_info) < ELF_R_SYM (b->u.rel.r_info)) return -1; if (ELF_R_SYM (a->u.rel.r_info) > ELF_R_SYM (b->u.rel.r_info)) @@ -4429,14 +4429,15 @@ elf_link_sort_relocs (abfd, info, psec) } qsort (rela, count, sizeof (*rela), elf_link_sort_cmp1); - for (i = 0, j = 0; i < count && rela[i].type != reloc_class_relative; i++) + for (ret = 0; ret < count && rela[ret].type == reloc_class_relative; ret++) + ; + for (i = ret, j = ret; i < count; i++) { if (ELF_R_SYM (rela[i].u.rel.r_info) != ELF_R_SYM (rela[j].u.rel.r_info)) j = i; rela[i].offset = rela[j].u.rel.r_offset; } - ret = count - i; - qsort (rela, i, sizeof (*rela), elf_link_sort_cmp2); + qsort (rela + ret, count - ret, sizeof (*rela), elf_link_sort_cmp2); for (o = dynobj->sections; o != NULL; o = o->next) if ((o->flags & (SEC_HAS_CONTENTS|SEC_LINKER_CREATED)) Jakub