summaryrefslogtreecommitdiff
path: root/bfd/elfxx-ia64.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl@lucon.org>2003-10-13 15:55:51 +0000
committerH.J. Lu <hjl@lucon.org>2003-10-13 15:55:51 +0000
commita32fc314069f2516af90e2914d2f2bfeb03a1d1a (patch)
tree1dc648e9bc1bcdd52477e09839cea95aef6ae32f /bfd/elfxx-ia64.c
parentb6b2591751f4c6afa1e12c1de9b506dbe8da6765 (diff)
downloadgdb-a32fc314069f2516af90e2914d2f2bfeb03a1d1a.tar.gz
bfd/
2003-10-10 H.J. Lu <hongjiu.lu@intel.com> * bfd-in.h (bfd_elf32_ia64_after_parse): New prototype. (bfd_elf64_ia64_after_parse): Likewise. * bfd-in2.h: Regenerated. * elfxx-ia64.c (oor_ip): New. (oor_branch_size): Likewise. (bfd_elfNN_ia64_after_parse): Likewise. (elfNN_ia64_relax_section): Use oor_ip if oor_branch_size equals sizeof (oor_ip). ld/ 2003-10-10 H.J. Lu <hongjiu.lu@intel.com> * Makefile.am (eelf64_ia64.c): Also depend on $(srcdir)/emultempl/ia64elf.em. * Makefile.in: Regenerated. * emulparams/elf64_ia64.sh (EXTRA_EM_FILE): Set to ia64elf. * emultempl/ia64elf.em: New.
Diffstat (limited to 'bfd/elfxx-ia64.c')
-rw-r--r--bfd/elfxx-ia64.c46
1 files changed, 39 insertions, 7 deletions
diff --git a/bfd/elfxx-ia64.c b/bfd/elfxx-ia64.c
index 15f7c0a126a..ed626bfae39 100644
--- a/bfd/elfxx-ia64.c
+++ b/bfd/elfxx-ia64.c
@@ -656,6 +656,28 @@ static const bfd_byte oor_brl[16] =
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
0x00, 0x00, 0x00, 0xc0
};
+
+static const bfd_byte oor_ip[48] =
+{
+ 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, /* movl r15=0 */
+ 0x01, 0x00, 0x00, 0x60,
+ 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0 */
+ 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, /* mov r16=ip;; */
+ 0xf2, 0x80, 0x00, 0x80, /* add r16=r15,r16;; */
+ 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */
+ 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
+ 0x60, 0x00, 0x80, 0x00 /* br b6;; */
+};
+
+static size_t oor_branch_size = sizeof (oor_brl);
+
+void
+bfd_elfNN_ia64_after_parse (int itanium)
+{
+ oor_branch_size = itanium ? sizeof (oor_ip) : sizeof (oor_brl);
+}
+
/* These functions do relaxation for IA-64 ELF. */
@@ -891,9 +913,7 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
if (tsec == ia64_info->plt_sec)
size = sizeof (plt_full_entry);
else
- {
- size = sizeof (oor_brl);
- }
+ size = oor_branch_size;
/* Resize the current section to make room for the new branch. */
trampoff = (sec->_cooked_size + 15) & (bfd_vma) -16;
@@ -914,10 +934,22 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
}
else
{
- memcpy (contents + trampoff, oor_brl, size);
- irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
- R_IA64_PCREL60B);
- irel->r_offset = trampoff + 2;
+ if (size == sizeof (oor_ip))
+ {
+ memcpy (contents + trampoff, oor_ip, size);
+ irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
+ R_IA64_PCREL64I);
+ irel->r_addend -= 16;
+ irel->r_offset = trampoff + 2;
+ }
+ else
+ {
+ memcpy (contents + trampoff, oor_brl, size);
+ irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
+ R_IA64_PCREL60B);
+ irel->r_offset = trampoff + 2;
+ }
+
}
/* Record the fixup so we don't do it again this section. */