diff options
Diffstat (limited to 'trunk/src/conflict.c')
-rw-r--r-- | trunk/src/conflict.c | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/trunk/src/conflict.c b/trunk/src/conflict.c index db36054..cb0ba80 100644 --- a/trunk/src/conflict.c +++ b/trunk/src/conflict.c @@ -1,5 +1,7 @@ /* Copyright (C) 2001, 2002, 2003, 2004 Red Hat, Inc. + Copyright (C) 2008 CodeSourcery. Written by Jakub Jelinek <jakub@redhat.com>, 2001. + Updated by Maciej W. Rozycki <macro@codesourcery.com>, 2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -25,6 +27,7 @@ #include <unistd.h> #include "prelink.h" #include "reloc.h" +#include "reloc-info.h" struct prelink_conflict * prelink_conflict (struct prelink_info *info, GElf_Word r_sym, @@ -139,7 +142,7 @@ prelink_add_copy_rel (DSO *dso, int n, GElf_Rel *rel, struct copy_relocs *cr) Elf_Scn *scn = dso->scn[symsec]; GElf_Sym sym; size_t entsize = dso->shdr[symsec].sh_entsize; - off_t off = GELF_R_SYM (rel->r_info) * entsize; + off_t off = reloc_r_sym (dso, rel->r_info) * entsize; while ((data = elf_getdata (scn, data)) != NULL) { @@ -195,7 +198,7 @@ prelink_find_copy_rel (DSO *dso, int n, struct copy_relocs *cr) if (sec == -1) continue; - if (GELF_R_TYPE (rel.r_info) == dso->arch->R_COPY + if (reloc_r_type (dso, rel.r_info) == dso->arch->R_COPY && prelink_add_copy_rel (dso, n, &rel, cr)) return 1; } @@ -224,7 +227,7 @@ prelink_find_copy_rela (DSO *dso, int n, struct copy_relocs *cr) if (sec == -1) continue; - if (GELF_R_TYPE (u.rela.r_info) == dso->arch->R_COPY) + if (reloc_r_type (dso, u.rela.r_info) == dso->arch->R_COPY) { if (u.rela.r_addend != 0) { @@ -253,15 +256,18 @@ rela_cmp (const void *A, const void *B) return 0; } +static DSO *conflict_rela_cmp_dso; + static int conflict_rela_cmp (const void *A, const void *B) { + DSO *dso = conflict_rela_cmp_dso; GElf_Rela *a = (GElf_Rela *)A; GElf_Rela *b = (GElf_Rela *)B; - if (GELF_R_SYM (a->r_info) < GELF_R_SYM (b->r_info)) + if (reloc_r_sym (dso, a->r_info) < reloc_r_sym (dso, b->r_info)) return -1; - if (GELF_R_SYM (a->r_info) > GELF_R_SYM (b->r_info)) + if (reloc_r_sym (dso, a->r_info) > reloc_r_sym (dso, b->r_info)) return 1; if (a->r_offset < b->r_offset) return -1; @@ -326,7 +332,7 @@ get_relocated_mem (struct prelink_info *info, DSO *dso, GElf_Addr addr, <= addr) continue; - reloc_type = GELF_R_TYPE (info->conflict_rela[j].r_info); + reloc_type = reloc_r_type (dso, info->conflict_rela[j].r_info); reloc_size = dso->arch->reloc_size (reloc_type); if (info->conflict_rela[j].r_offset + reloc_size <= addr) continue; @@ -406,7 +412,7 @@ get_relocated_mem (struct prelink_info *info, DSO *dso, GElf_Addr addr, if (u.rel.r_offset + dso->arch->max_reloc_size <= addr) continue; - reloc_type = GELF_R_TYPE (u.rel.r_info); + reloc_type = reloc_r_type (dso, u.rel.r_info); reloc_size = dso->arch->reloc_size (reloc_type); if (u.rel.r_offset + reloc_size <= addr) continue; @@ -587,7 +593,9 @@ prelink_build_conflicts (struct prelink_info *info) /* Record library's position in search scope into R_SYM field. */ for (j = first_conflict; j < info->conflict_rela_size; ++j) info->conflict_rela[j].r_info - = GELF_R_INFO (i, GELF_R_TYPE (info->conflict_rela[j].r_info)); + = reloc_r_info (dso, i, + reloc_r_type (dso, + info->conflict_rela[j].r_info)); if (dynamic_info_is_set (dso, DT_TEXTREL) && info->conflict_rela_size > first_conflict) @@ -643,7 +651,7 @@ prelink_build_conflicts (struct prelink_info *info) { for (i = 1; i < cr.count; ++i) if (cr.rela[i].r_offset - > dso->shdr[bss1].sh_addr + dso->shdr[bss1].sh_size) + >= dso->shdr[bss1].sh_addr + dso->shdr[bss1].sh_size) break; if (cr.rela[i].r_offset < dso->shdr[bss2].sh_addr) { @@ -720,11 +728,11 @@ prelink_build_conflicts (struct prelink_info *info) int j, reloc_class; reloc_class - = dso->arch->reloc_class (GELF_R_TYPE (cr.rela[i].r_info)); + = dso->arch->reloc_class (reloc_r_type (dso, cr.rela[i].r_info)); assert (reloc_class != RTYPE_CLASS_TLS); - for (s = & info->symbols[GELF_R_SYM (cr.rela[i].r_info)]; s; + for (s = & info->symbols[reloc_r_sym (dso, cr.rela[i].r_info)]; s; s = s->next) if (s->reloc_class == reloc_class) break; @@ -771,13 +779,15 @@ prelink_build_conflicts (struct prelink_info *info) if (info->conflict_rela_size) { + conflict_rela_cmp_dso = dso; qsort (info->conflict_rela, info->conflict_rela_size, sizeof (GElf_Rela), conflict_rela_cmp); /* Now make sure all conflict RELA's are against absolute 0 symbol. */ for (i = 0; i < info->conflict_rela_size; ++i) info->conflict_rela[i].r_info - = GELF_R_INFO (0, GELF_R_TYPE (info->conflict_rela[i].r_info)); + = reloc_r_info (dso, 0, + reloc_r_type (dso, info->conflict_rela[i].r_info)); if (enable_cxx_optimizations && remove_redundant_cxx_conflicts (info)) goto error_out; |