diff options
Diffstat (limited to 'trunk/src/conflict.c')
-rw-r--r-- | trunk/src/conflict.c | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/trunk/src/conflict.c b/trunk/src/conflict.c index 9c936ce..a1fb1ec 100644 --- a/trunk/src/conflict.c +++ b/trunk/src/conflict.c @@ -1,5 +1,7 @@ /* Copyright (C) 2001, 2002, 2003, 2004, 2007, 2009 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, @@ -143,7 +146,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) { @@ -199,7 +202,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; } @@ -228,7 +231,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) { @@ -257,15 +260,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; @@ -330,7 +336,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; @@ -414,7 +420,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; @@ -605,7 +611,8 @@ 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) @@ -737,11 +744,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; @@ -790,13 +797,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; |