summaryrefslogtreecommitdiffstats
path: root/trunk/src/arch-ppc64.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/arch-ppc64.c')
-rw-r--r--trunk/src/arch-ppc64.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/trunk/src/arch-ppc64.c b/trunk/src/arch-ppc64.c
index ec28ee8..6f9f644 100644
--- a/trunk/src/arch-ppc64.c
+++ b/trunk/src/arch-ppc64.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Red Hat, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2009 Red Hat, Inc.
Written by Jakub Jelinek <jakub@redhat.com>, 2002.
This program is free software; you can redistribute it and/or modify
@@ -60,7 +60,7 @@ ppc64_adjust_section (DSO *dso, int n, GElf_Addr start, GElf_Addr adjust)
static int
ppc64_adjust_dyn (DSO *dso, int n, GElf_Dyn *dyn, GElf_Addr start,
- GElf_Addr adjust)
+ GElf_Addr adjust)
{
if (dyn->d_tag == DT_PPC64_GLINK && dyn->d_un.d_ptr >= start)
{
@@ -73,7 +73,7 @@ ppc64_adjust_dyn (DSO *dso, int n, GElf_Dyn *dyn, GElf_Addr start,
static int
ppc64_adjust_rel (DSO *dso, GElf_Rel *rel, GElf_Addr start,
- GElf_Addr adjust)
+ GElf_Addr adjust)
{
error (0, 0, "%s: PowerPC64 doesn't support REL relocs", dso->filename);
return 1;
@@ -81,7 +81,7 @@ ppc64_adjust_rel (DSO *dso, GElf_Rel *rel, GElf_Addr start,
static int
ppc64_adjust_rela (DSO *dso, GElf_Rela *rela, GElf_Addr start,
- GElf_Addr adjust)
+ GElf_Addr adjust)
{
if (GELF_R_TYPE (rela->r_info) == R_PPC64_RELATIVE)
{
@@ -306,7 +306,7 @@ ppc64_prelink_rela (struct prelink_info *info, GElf_Rela *rela,
static int
ppc64_apply_conflict_rela (struct prelink_info *info, GElf_Rela *rela,
- char *buf)
+ char *buf, GElf_Addr dest_addr)
{
switch (GELF_R_TYPE (rela->r_info))
{
@@ -439,7 +439,8 @@ ppc64_prelink_conflict_rela (DSO *dso, struct prelink_info *info,
int r_type;
if (GELF_R_TYPE (rela->r_info) == R_PPC64_RELATIVE
- || GELF_R_TYPE (rela->r_info) == R_PPC64_NONE)
+ || GELF_R_TYPE (rela->r_info) == R_PPC64_NONE
+ || info->dso == dso)
/* Fast path: nothing to do. */
return 0;
conflict = prelink_conflict (info, GELF_R_SYM (rela->r_info),
@@ -463,6 +464,12 @@ ppc64_prelink_conflict_rela (DSO *dso, struct prelink_info *info,
}
value = 0;
}
+ else if (conflict->ifunc)
+ {
+ error (0, 0, "%s: STT_GNU_IFUNC not handled on PowerPC64 yet",
+ dso->filename);
+ return 1;
+ }
else
{
/* DTPREL wants to see only real conflicts, not lookups
@@ -771,13 +778,12 @@ ppc64_reloc_class (int reloc_type)
{
switch (reloc_type)
{
- case R_PPC64_COPY: return RTYPE_CLASS_COPY;
- case R_PPC64_ADDR24: return RTYPE_CLASS_PLT;
+ case R_PPC64_COPY: return RTYPE_CLASS_COPY | RTYPE_CLASS_PLT;
default:
if (reloc_type >= R_PPC64_DTPMOD64
&& reloc_type <= R_PPC64_TPREL16_HIGHESTA)
return RTYPE_CLASS_TLS;
- return RTYPE_CLASS_VALID;
+ return RTYPE_CLASS_PLT;
}
}
@@ -824,6 +830,7 @@ PL_ARCH(ppc64) = {
.R_JMP_SLOT = R_PPC64_JMP_SLOT,
.R_COPY = R_PPC64_COPY,
.R_RELATIVE = R_PPC64_RELATIVE,
+ .rtype_class_valid = RTYPE_CLASS_PLT,
.dynamic_linker = "/lib64/ld64.so.1",
.adjust_section = ppc64_adjust_section,
.adjust_dyn = ppc64_adjust_dyn,