summaryrefslogtreecommitdiffstats
path: root/trunk/src/conflict.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/conflict.c')
-rw-r--r--trunk/src/conflict.c34
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;