aboutsummaryrefslogtreecommitdiff
path: root/bfd/elfxx-ia64.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2000-11-16 22:44:07 +0000
committerRichard Henderson <rth@redhat.com>2000-11-16 22:44:07 +0000
commit18b27f179ea729ce6031181ff03e78f07d087166 (patch)
tree451e11ff126a18adcf15be0ebd3856e03a032182 /bfd/elfxx-ia64.c
parent77e913df42910e83339ef3d70b8bed39fa4842ea (diff)
downloadfsf-binutils-gdb-18b27f179ea729ce6031181ff03e78f07d087166.zip
fsf-binutils-gdb-18b27f179ea729ce6031181ff03e78f07d087166.tar.gz
fsf-binutils-gdb-18b27f179ea729ce6031181ff03e78f07d087166.tar.bz2
* elfxx-ia64.c (elfNN_ia64_check_relocs): Handle IPLT relocs.
(allocate_dynrel_entries): Likewise. (elfNN_ia64_relocate_section): Likewise. Set REL addends correctly. (set_pltoff_entry): Likewise. (ia64_howto_table): Remove R_IA64_SEGBASE, and R_IA64_EPLT[ML]SB (elfNN_ia64_reloc_type_lookup): Likewise. (elfNN_ia64_install_value): Likewise. (elfNN_ia64_relocate_section): Likewise. * reloc.c (BFD_RELOC_IA64_SEGBASE): Remove. (BFD_RELOC_IA64_EPLTMSB, BFD_RELOC_IA64_EPLTLSB): Remove.
Diffstat (limited to 'bfd/elfxx-ia64.c')
-rw-r--r--bfd/elfxx-ia64.c122
1 files changed, 76 insertions, 46 deletions
diff --git a/bfd/elfxx-ia64.c b/bfd/elfxx-ia64.c
index d5c5f02..a20077d 100644
--- a/bfd/elfxx-ia64.c
+++ b/bfd/elfxx-ia64.c
@@ -353,7 +353,6 @@ static reloc_howto_type ia64_howto_table[] =
IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB, "LTOFF_FPTR64MSB", 4, false, true),
IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB, "LTOFF_FPTR64LSB", 4, false, true),
- IA64_HOWTO (R_IA64_SEGBASE, "SEGBASE", 4, false, true),
IA64_HOWTO (R_IA64_SEGREL32MSB, "SEGREL32MSB", 2, false, true),
IA64_HOWTO (R_IA64_SEGREL32LSB, "SEGREL32LSB", 2, false, true),
IA64_HOWTO (R_IA64_SEGREL64MSB, "SEGREL64MSB", 4, false, true),
@@ -380,8 +379,6 @@ static reloc_howto_type ia64_howto_table[] =
IA64_HOWTO (R_IA64_IPLTMSB, "IPLTMSB", 4, false, true),
IA64_HOWTO (R_IA64_IPLTLSB, "IPLTLSB", 4, false, true),
- IA64_HOWTO (R_IA64_EPLTMSB, "EPLTMSB", 4, false, true),
- IA64_HOWTO (R_IA64_EPLTLSB, "EPLTLSB", 4, false, true),
IA64_HOWTO (R_IA64_COPY, "COPY", 4, false, true),
IA64_HOWTO (R_IA64_LTOFF22X, "LTOFF22X", 0, false, true),
IA64_HOWTO (R_IA64_LDXMOV, "LDXMOV", 0, false, true),
@@ -476,7 +473,6 @@ elfNN_ia64_reloc_type_lookup (abfd, bfd_code)
case BFD_RELOC_IA64_LTOFF_FPTR64MSB: rtype = R_IA64_LTOFF_FPTR64MSB; break;
case BFD_RELOC_IA64_LTOFF_FPTR64LSB: rtype = R_IA64_LTOFF_FPTR64LSB; break;
- case BFD_RELOC_IA64_SEGBASE: rtype = R_IA64_SEGBASE; break;
case BFD_RELOC_IA64_SEGREL32MSB: rtype = R_IA64_SEGREL32MSB; break;
case BFD_RELOC_IA64_SEGREL32LSB: rtype = R_IA64_SEGREL32LSB; break;
case BFD_RELOC_IA64_SEGREL64MSB: rtype = R_IA64_SEGREL64MSB; break;
@@ -499,8 +495,6 @@ elfNN_ia64_reloc_type_lookup (abfd, bfd_code)
case BFD_RELOC_IA64_IPLTMSB: rtype = R_IA64_IPLTMSB; break;
case BFD_RELOC_IA64_IPLTLSB: rtype = R_IA64_IPLTLSB; break;
- case BFD_RELOC_IA64_EPLTMSB: rtype = R_IA64_EPLTMSB; break;
- case BFD_RELOC_IA64_EPLTLSB: rtype = R_IA64_EPLTLSB; break;
case BFD_RELOC_IA64_COPY: rtype = R_IA64_COPY; break;
case BFD_RELOC_IA64_LTOFF22X: rtype = R_IA64_LTOFF22X; break;
case BFD_RELOC_IA64_LDXMOV: rtype = R_IA64_LDXMOV; break;
@@ -1864,6 +1858,14 @@ elfNN_ia64_check_relocs (abfd, info, sec, relocs)
dynrel_type = R_IA64_DIR64LSB;
break;
+ case R_IA64_IPLTMSB:
+ case R_IA64_IPLTLSB:
+ /* Shared objects will always need at least a REL relocation. */
+ if (info->shared || maybe_dynamic)
+ need_entry = NEED_DYNREL;
+ dynrel_type = R_IA64_IPLTLSB;
+ break;
+
case R_IA64_PCREL22:
case R_IA64_PCREL64I:
case R_IA64_PCREL32MSB:
@@ -2184,6 +2186,8 @@ allocate_dynrel_entries (dyn_i, data)
for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
{
+ int count = rent->count;
+
switch (rent->type)
{
case R_IA64_FPTR64LSB:
@@ -2201,8 +2205,18 @@ allocate_dynrel_entries (dyn_i, data)
if (!dynamic_symbol && !shared)
continue;
break;
+ case R_IA64_IPLTLSB:
+ if (!dynamic_symbol && !shared)
+ continue;
+ /* Use two REL relocations for IPLT relocations
+ against local symbols. */
+ if (!dynamic_symbol)
+ count *= 2;
+ break;
+ default:
+ abort ();
}
- rent->srel->_raw_size += sizeof (ElfNN_External_Rela) * rent->count;
+ rent->srel->_raw_size += sizeof (ElfNN_External_Rela) * count;
}
/* Take care of the GOT and PLT relocations. */
@@ -2639,25 +2653,6 @@ elfNN_ia64_install_value (abfd, hit_addr, val, r_type)
break;
/* Unsupported / Dynamic relocations. */
-
- case R_IA64_REL32MSB:
- case R_IA64_REL32LSB:
- case R_IA64_REL64MSB:
- case R_IA64_REL64LSB:
-
- case R_IA64_IPLTMSB:
- case R_IA64_IPLTLSB:
- case R_IA64_EPLTMSB:
- case R_IA64_EPLTLSB:
- case R_IA64_COPY:
-
- case R_IA64_SEGBASE:
-
- case R_IA64_TPREL22:
- case R_IA64_TPREL64MSB:
- case R_IA64_TPREL64LSB:
- case R_IA64_LTOFF_TP22:
-
default:
return bfd_reloc_notsupported;
}
@@ -2937,10 +2932,11 @@ set_pltoff_entry (abfd, info, dyn_i, value, is_plt)
if ((! dyn_i->want_plt || is_plt)
&& !dyn_i->pltoff_done)
{
+ bfd_vma gp = _bfd_get_gp_value (abfd);
+
/* Fill in the function descriptor. */
bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
- bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
- pltoff_sec->contents + dyn_i->pltoff_offset + 8);
+ bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
/* Install dynamic relocations if needed. */
if (!is_plt && info->shared)
@@ -2955,11 +2951,11 @@ set_pltoff_entry (abfd, info, dyn_i, value, is_plt)
elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
ia64_info->rel_pltoff_sec,
dyn_i->pltoff_offset,
- dyn_r_type, 0, 0);
+ dyn_r_type, 0, value);
elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
ia64_info->rel_pltoff_sec,
dyn_i->pltoff_offset + 8,
- dyn_r_type, 0, 0);
+ dyn_r_type, 0, gp);
}
dyn_i->pltoff_done = 1;
@@ -3366,6 +3362,7 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
{
unsigned int dyn_r_type;
long dynindx;
+ bfd_vma addend;
BFD_ASSERT (srel != NULL);
@@ -3373,7 +3370,11 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
matching RELATIVE relocation. */
dyn_r_type = r_type;
if (dynamic_symbol_p)
- dynindx = h->dynindx;
+ {
+ dynindx = h->dynindx;
+ addend = rel->r_addend;
+ value = 0;
+ }
else
{
switch (r_type)
@@ -3405,11 +3406,12 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
continue;
}
dynindx = 0;
+ addend = value;
}
elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
srel, rel->r_offset, dyn_r_type,
- dynindx, rel->r_addend);
+ dynindx, addend);
}
/* FALLTHRU */
@@ -3678,23 +3680,51 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
break;
- case R_IA64_SEGBASE:
-
- case R_IA64_REL32MSB:
- case R_IA64_REL32LSB:
- case R_IA64_REL64MSB:
- case R_IA64_REL64LSB:
-
case R_IA64_IPLTMSB:
case R_IA64_IPLTLSB:
- case R_IA64_EPLTMSB:
- case R_IA64_EPLTLSB:
- case R_IA64_COPY:
+ /* Install a dynamic relocation for this reloc. */
+ if ((dynamic_symbol_p || info->shared)
+ && (input_section->flags & SEC_ALLOC) != 0)
+ {
+ long dynindx;
+
+ BFD_ASSERT (srel != NULL);
+
+ /* If we don't need dynamic symbol lookup, install two
+ RELATIVE relocations. */
+ if (! dynamic_symbol_p)
+ {
+ unsigned int dyn_r_type;
+
+ if (r_type == R_IA64_IPLTMSB)
+ dyn_r_type = R_IA64_REL64MSB;
+ else
+ dyn_r_type = R_IA64_REL64LSB;
+
+ elfNN_ia64_install_dyn_reloc (output_bfd, info,
+ input_section,
+ srel, rel->r_offset,
+ dyn_r_type, 0, value);
+ elfNN_ia64_install_dyn_reloc (output_bfd, info,
+ input_section,
+ srel, rel->r_offset + 8,
+ dyn_r_type, 0, gp_val);
+ }
+ else
+ elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
+ srel, rel->r_offset, r_type,
+ h->dynindx, rel->r_addend);
+ }
+
+ if (r_type == R_IA64_IPLTMSB)
+ r_type = R_IA64_DIR64MSB;
+ else
+ r_type = R_IA64_DIR64LSB;
+ elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
+ r = elfNN_ia64_install_value (output_bfd, hit_addr + 8, gp_val,
+ r_type);
+ break;
- case R_IA64_TPREL22:
- case R_IA64_TPREL64MSB:
- case R_IA64_TPREL64LSB:
- case R_IA64_LTOFF_TP22:
default:
r = bfd_reloc_notsupported;
break;