This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
PATCH: Account for alignment relocs when relaxing mn10300 jump instructions
- From: Nick Clifton <nickc at redhat dot com>
- To: binutils at sourceware dot org
- Date: Wed, 21 Nov 2007 12:05:16 +0000
- Subject: PATCH: Account for alignment relocs when relaxing mn10300 jump instructions
Hi Guys,
I am checking in the attached patch to add code to the mn10300's
linker relaxation code to allow for alignment relocs when deciding
if 16-bit branch and jump instructions can be relaxed. The patch
also adds a linker testcase to check the code.
Cheers
Nick
bfd/ChangeLog
2007-11-21 Nick Clifton <nickc@redhat.com>
* elf-m10300.c (mn10300_elf_relax_section): Allow for alignment
relocs when computing whether instructions can be relaxed.
ld/testsuite/ChangeLog
2007-11-21 Nick Clifton <nickc@redhat.com>
* ld-mn10300/i135409-4.s: New test case. Check for relaxation to
a 16-bit jump instruction.
* ld-mn10300/i135409-4.t: Linker script for the new test.
* ld-mn10300/i135409-4.d: Expected disassembly of new test.
* ld-mn10300/mn10300.exp: Run the new test.
Index: bfd/elf-m10300.c
===================================================================
RCS file: /cvs/src/src/bfd/elf-m10300.c,v
retrieving revision 1.91
diff -c -3 -p -r1.91 elf-m10300.c
*** bfd/elf-m10300.c 16 Nov 2007 09:48:05 -0000 1.91
--- bfd/elf-m10300.c 21 Nov 2007 11:58:22 -0000
*************** mn10300_elf_relax_section (bfd *abfd,
*** 2105,2110 ****
--- 2105,2111 ----
Elf_Internal_Sym *isymbuf = NULL;
struct elf32_mn10300_link_hash_table *hash_table;
asection *section = sec;
+ bfd_vma align_gap_adjustment;
/* Assume nothing changes. */
*again = FALSE;
*************** mn10300_elf_relax_section (bfd *abfd,
*** 2718,2723 ****
--- 2719,2751 ----
if (internal_relocs == NULL)
goto error_return;
+ /* Scan for worst case alignment gap changes. Note that this logic
+ is not ideal; what we should do is run this scan for every
+ opcode/address range and adjust accordingly, but that's
+ expensive. Worst case is that for an alignment of N bytes, we
+ move by 2*N-N-1 bytes, assuming we have aligns of 1, 2, 4, 8, etc
+ all before it. Plus, this still doesn't cover cross-section
+ jumps with section alignment. */
+ irelend = internal_relocs + sec->reloc_count;
+ align_gap_adjustment = 0;
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_ALIGN)
+ {
+ bfd_vma adj = 1 << irel->r_addend;
+ bfd_vma aend = irel->r_offset;
+
+ aend = BFD_ALIGN (aend, 1 << irel->r_addend);
+ adj = 2*adj - adj - 1;
+
+ /* Record the biggest adjustmnet. Skip any alignment at the
+ end of our section. */
+ if (align_gap_adjustment < adj
+ && aend < sec->output_section->vma + sec->output_offset + sec->size)
+ align_gap_adjustment = adj;
+ }
+ }
+
/* Walk through them looking for relaxing opportunities. */
irelend = internal_relocs + sec->reloc_count;
for (irel = internal_relocs; irel < irelend; irel++)
*************** mn10300_elf_relax_section (bfd *abfd,
*** 2933,2939 ****
/* See if the value will fit in 16 bits, note the high value is
0x7fff + 2 as the target will be two bytes closer if we are
able to relax. */
! if ((long) value < 0x8001 && (long) value > -0x8000)
{
unsigned char code;
--- 2961,2970 ----
/* See if the value will fit in 16 bits, note the high value is
0x7fff + 2 as the target will be two bytes closer if we are
able to relax. */
! /* Account for jumps across alignment boundaries using
! align_gap_adjustment. */
! if (value < 0x8001 - align_gap_adjustment
! && ((bfd_signed_vma) value > -0x8000 + (bfd_signed_vma) align_gap_adjustment))
{
unsigned char code;
Index: ld/testsuite/ld-mn10300/mn10300.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-mn10300/mn10300.exp,v
retrieving revision 1.4
diff -c -3 -p -r1.4 mn10300.exp
*** ld/testsuite/ld-mn10300/mn10300.exp 16 Nov 2007 09:48:04 -0000 1.4
--- ld/testsuite/ld-mn10300/mn10300.exp 21 Nov 2007 12:00:03 -0000
*************** set mn10300_tests {
*** 79,84 ****
--- 79,92 ----
{ {objdump -d i135409-3.d} }
"i135409-3.x"
}
+ {
+ "adjusting a 16 bit branch"
+ "-Ti135409-4.t -relax"
+ ""
+ { "i135409-4.s" }
+ { {objdump -d i135409-4.d} }
+ "i135409-4.x"
+ }
}
run_ld_link_tests $mn10300_tests
*** /dev/null 2007-11-21 09:54:40.711827624 +0000
--- ld/testsuite/ld-mn10300/i135409-4.s 2007-11-21 10:24:20.000000000 +0000
***************
*** 0 ****
--- 1,8 ----
+ .text
+ .global _start
+ _start:
+ jmp L001
+
+ .section .text1
+ L001:
+ nop
*** /dev/null 2007-11-21 09:54:40.711827624 +0000
--- ld/testsuite/ld-mn10300/i135409-4.t 2007-11-21 10:24:20.000000000 +0000
***************
*** 0 ****
--- 1,23 ----
+ SECTIONS
+ {
+ . = 0x0;
+ .text :
+ {
+ *(.text)
+ }
+
+ . = 0x700;
+ .text1 :
+ {
+ *(.text1)
+ }
+ . = 0x8100;
+ .bss :
+ {
+ *(.bss)
+ }
+ .data :
+ {
+ *(.data)
+ }
+ }
*** /dev/null 2007-11-21 09:54:40.711827624 +0000
--- ld/testsuite/ld-mn10300/i135409-4.d 2007-11-21 10:24:20.000000000 +0000
***************
*** 0 ****
--- 1,7 ----
+
+ tmpdir/i135409-4.x: file format elf32-.*
+
+ Disassembly of section .text:
+
+ 0+0 <_start>:
+ 0:[ ]+cc 00 07[ ]+jmp[ ]+700 \<L001\>