This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[PATCH] Fix bug in ia64 trampoline
- From: Jakub Jelinek <jakub at redhat dot com>
- To: "H. J. Lu" <hjl at lucon dot org>, rth at redhat dot com
- Cc: binutils at sources dot redhat dot com
- Date: Mon, 17 Mar 2003 19:27:22 +0100
- Subject: [PATCH] Fix bug in ia64 trampoline
- References: <20030303223018.A19105@lucon.org>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Mon, Mar 03, 2003 at 10:30:18PM -0800, H. J. Lu wrote:
> While looking at elfNN_ia64_relax_section, I don't see how it can reuse the
> trampoline without checking r_addend. The relaxation code creates a trampoline
> and reuse the old relocation by modifying r_info and r_offset
>
> irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
> R_IA64_PCREL60B);
> irel->r_offset = trampoff + 2;
>
> A relocation will be applied at the trampoline with r_addend. When it cherks a
> trampoline can be reuse, it doesn't check r_addend at all. Did I miss
> something?
I agree the code has to take r_addend into account and verified it
on a testcase. The IA-64 backend enforces r_addend == 0 in case of a
branch to PLT with assert elsewhere, so I've just added it
into relax_section too.
cat > test.s <<EOF
.text
.align 16
.global test#
.proc test#
test:
br.call.sptk.many b0 = foo#;;
br.call.sptk.many b0 = bar#;;
br.call.sptk.many b0 = foo# + 16;;
br.call.sptk.many b0 = bar# + 16;;
.endp test#
.section .text.a,"ax",@progbits
.fill 0x1000000, 1, 32
.section .text.b,"ax",@progbits
.align 16
.global foo#
.hidden foo
.proc foo#
foo:
br.ret.sptk.many b0
.endp foo#
.align 16
.global bar#
.hidden bar
.proc bar#
bar:
br.ret.sptk.many b0;;
br.ret.sptk.many b0
.endp bar#
EOF
as -x -o test.o test.s
ld -shared -o test.so test.o
Ok to commit?
2003-03-17 Jakub Jelinek <jakub at redhat dot com>
* elfxx-ia64.c (elfNN_ia64_relax_section): Take r_addend into
account when creating trampolines.
--- bfd/elfxx-ia64.c.jj 2003-03-17 07:02:18.000000000 -0500
+++ bfd/elfxx-ia64.c 2003-03-17 12:57:52.000000000 -0500
@@ -790,7 +790,7 @@ elfNN_ia64_relax_section (abfd, sec, lin
else
tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
- toff = isym->st_value;
+ toff = isym->st_value + irel->r_addend;
dyn_i = get_dyn_sym_info (ia64_info, NULL, abfd, irel, FALSE);
}
else
@@ -819,6 +819,7 @@ elfNN_ia64_relax_section (abfd, sec, lin
tsec = ia64_info->plt_sec;
toff = dyn_i->plt2_offset;
+ BFD_ASSERT (irel->r_addend == 0);
}
/* Can't do anything else with dynamic symbols. */
@@ -833,14 +834,13 @@ elfNN_ia64_relax_section (abfd, sec, lin
continue;
tsec = h->root.u.def.section;
- toff = h->root.u.def.value;
+ toff = h->root.u.def.value + irel->r_addend;
}
}
symaddr = (tsec->output_section->vma
+ tsec->output_offset
- + toff
- + irel->r_addend);
+ + toff);
roff = irel->r_offset;
Jakub