ia64 psABI update
Richard Henderson
rth@redhat.com
Thu Nov 16 14:47:00 GMT 2000
R_IA64_IPLTLSB type relocs, in addition to implementing .plt
entries, are also used to put function descriptors anywhere
the programmer would like.
GCC does not do this yet, but the C++ ABI for IA-64 sez that
we use descriptors in vtables instead of pointers to descriptors
as would be normal for a C-level function pointer. The Intel
compiler already emits these relocations.
Also, several weird (and unhandled) relocations were removed.
r~
* 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.
Index: elfxx-ia64.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-ia64.c,v
retrieving revision 1.2
diff -c -p -d -r1.2 elfxx-ia64.c
*** elfxx-ia64.c 2000/11/08 07:54:31 1.2
--- elfxx-ia64.c 2000/11/16 22:43:33
*************** static reloc_howto_type ia64_howto_table
*** 353,359 ****
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),
--- 353,358 ----
*************** static reloc_howto_type ia64_howto_table
*** 380,387 ****
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),
--- 379,384 ----
*************** elfNN_ia64_reloc_type_lookup (abfd, bfd_
*** 476,482 ****
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;
--- 473,478 ----
*************** elfNN_ia64_reloc_type_lookup (abfd, bfd_
*** 499,506 ****
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;
--- 495,500 ----
*************** elfNN_ia64_check_relocs (abfd, info, sec
*** 1864,1869 ****
--- 1858,1871 ----
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:
*************** allocate_dynrel_entries (dyn_i, data)
*** 2184,2189 ****
--- 2186,2193 ----
for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
{
+ int count = rent->count;
+
switch (rent->type)
{
case R_IA64_FPTR64LSB:
*************** allocate_dynrel_entries (dyn_i, data)
*** 2201,2208 ****
if (!dynamic_symbol && !shared)
continue;
break;
}
! rent->srel->_raw_size += sizeof (ElfNN_External_Rela) * rent->count;
}
/* Take care of the GOT and PLT relocations. */
--- 2205,2222 ----
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) * count;
}
/* Take care of the GOT and PLT relocations. */
*************** elfNN_ia64_install_value (abfd, hit_addr
*** 2639,2663 ****
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;
}
--- 2653,2658 ----
*************** set_pltoff_entry (abfd, info, dyn_i, val
*** 2937,2946 ****
if ((! dyn_i->want_plt || is_plt)
&& !dyn_i->pltoff_done)
{
/* 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);
/* Install dynamic relocations if needed. */
if (!is_plt && info->shared)
--- 2932,2942 ----
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, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
/* Install dynamic relocations if needed. */
if (!is_plt && info->shared)
*************** set_pltoff_entry (abfd, info, dyn_i, val
*** 2955,2965 ****
elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
ia64_info->rel_pltoff_sec,
dyn_i->pltoff_offset,
! dyn_r_type, 0, 0);
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_i->pltoff_done = 1;
--- 2951,2961 ----
elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
ia64_info->rel_pltoff_sec,
dyn_i->pltoff_offset,
! 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, gp);
}
dyn_i->pltoff_done = 1;
*************** elfNN_ia64_relocate_section (output_bfd,
*** 3366,3371 ****
--- 3362,3368 ----
{
unsigned int dyn_r_type;
long dynindx;
+ bfd_vma addend;
BFD_ASSERT (srel != NULL);
*************** elfNN_ia64_relocate_section (output_bfd,
*** 3373,3379 ****
matching RELATIVE relocation. */
dyn_r_type = r_type;
if (dynamic_symbol_p)
! dynindx = h->dynindx;
else
{
switch (r_type)
--- 3370,3380 ----
matching RELATIVE relocation. */
dyn_r_type = r_type;
if (dynamic_symbol_p)
! {
! dynindx = h->dynindx;
! addend = rel->r_addend;
! value = 0;
! }
else
{
switch (r_type)
*************** elfNN_ia64_relocate_section (output_bfd,
*** 3405,3415 ****
continue;
}
dynindx = 0;
}
elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
srel, rel->r_offset, dyn_r_type,
! dynindx, rel->r_addend);
}
/* FALLTHRU */
--- 3406,3417 ----
continue;
}
dynindx = 0;
+ addend = value;
}
elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
srel, rel->r_offset, dyn_r_type,
! dynindx, addend);
}
/* FALLTHRU */
*************** elfNN_ia64_relocate_section (output_bfd,
*** 3678,3700 ****
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:
! case R_IA64_TPREL22:
! case R_IA64_TPREL64MSB:
! case R_IA64_TPREL64LSB:
! case R_IA64_LTOFF_TP22:
default:
r = bfd_reloc_notsupported;
break;
--- 3680,3730 ----
r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
break;
case R_IA64_IPLTMSB:
case R_IA64_IPLTLSB:
! /* 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;
!
default:
r = bfd_reloc_notsupported;
break;
Index: reloc.c
===================================================================
RCS file: /cvs/src/src/bfd/reloc.c,v
retrieving revision 1.30
diff -c -p -d -r1.30 reloc.c
*** reloc.c 2000/09/03 02:57:52 1.30
--- reloc.c 2000/11/16 22:43:34
*************** ENUMX
*** 2834,2841 ****
ENUMX
BFD_RELOC_IA64_LTOFF_FPTR64LSB
ENUMX
- BFD_RELOC_IA64_SEGBASE
- ENUMX
BFD_RELOC_IA64_SEGREL32MSB
ENUMX
BFD_RELOC_IA64_SEGREL32LSB
--- 2834,2839 ----
*************** ENUMX
*** 2871,2880 ****
BFD_RELOC_IA64_IPLTMSB
ENUMX
BFD_RELOC_IA64_IPLTLSB
- ENUMX
- BFD_RELOC_IA64_EPLTMSB
- ENUMX
- BFD_RELOC_IA64_EPLTLSB
ENUMX
BFD_RELOC_IA64_COPY
ENUMX
--- 2869,2874 ----
More information about the Binutils
mailing list