[binutils-gdb] MIPS/BFD: Actually produce short microMIPS LA25 stubs

Maciej W.Rozycki macro@sourceware.org
Wed Aug 10 21:30:00 GMT 2016


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=fe152e64f65de9cfb6f2059b76be98712baa7b56

commit fe152e64f65de9cfb6f2059b76be98712baa7b56
Author: Maciej W. Rozycki <macro@imgtec.com>
Date:   Wed Aug 10 20:44:03 2016 +0100

    MIPS/BFD: Actually produce short microMIPS LA25 stubs
    
    For the case where a function which requires an LA25 stub is at the
    beginning of a section we use a short sequence comprised of a LUI/ADDIU
    instruction pair only and prepended to the associated function rather
    than using a trailing jump to reach the function.  This works by
    checking for the offset into section of the function symbol being 0.
    
    This is however never the case for microMIPS function symbols, which
    have the ISA bit set.  Consequently the short LA25 sequence is never
    produced for microMIPS functions, like with the following example:
    
    $ cat la25a.s
    	.abicalls
    
    	.global	f1
    	.ent	f1
    f1:
    	.set	noreorder
    	.cpload	$25
    	.set	reorder
    	.option	pic0
    	jal	f2
    	.option	pic2
    	jr	$31
    	.end	f1
    
    	.global	f2
    	.ent	f2
    f2:
    	jr	$31
    	.end	f2
    $ cat la25b.s
    	.abicalls
    	.option	pic0
    
    	.global	__start
    	.ent	__start
    __start:
    	jal	f1
    	jal	f2
    	.end	__start
    $ as -mmicromips -32 -EB -o la25a.o la25a.s
    $ as -mmicromips -32 -EB -o la25b.o la25b.s
    $ ld -melf32btsmip -o la25 la25a.o la25b.o
    $ objdump -d la25
    
    la25:     file format elf32-tradbigmips
    
    Disassembly of section .text:
    
    004000d0 <.pic.f2>:
      4000d0:	41b9 0040 	lui	t9,0x40
      4000d4:	d420 0083 	j	400106 <f2>
      4000d8:	3339 0107 	addiu	t9,t9,263
      4000dc:	0000 0000 	nop
    
    004000e0 <.pic.f1>:
      4000e0:	41b9 0040 	lui	t9,0x40
      4000e4:	d420 0078 	j	4000f0 <f1>
      4000e8:	3339 00f1 	addiu	t9,t9,241
      4000ec:	0000 0000 	nop
    
    004000f0 <f1>:
      4000f0:	41bc 0002 	lui	gp,0x2
      4000f4:	339c 801f 	addiu	gp,gp,-32737
      4000f8:	033c e150 	addu	gp,gp,t9
      4000fc:	f420 0083 	jal	400106 <f2>
      400100:	0000 0000 	nop
      400104:	45bf      	jrc	ra
    
    00400106 <f2>:
      400106:	45bf      	jrc	ra
    	...
    
    00400110 <__start>:
      400110:	f420 0070 	jal	4000e0 <.pic.f1>
      400114:	0000 0000 	nop
      400118:	f420 0068 	jal	4000d0 <.pic.f2>
      40011c:	0000 0000 	nop
    $
    
    where `.pic.f1' could omit the trailing jump and the filler NOP and just
    fall through to `f1'.
    
    Correct the problem by masking out the ISA bit from microMIPS functions,
    which fixes the earlier example:
    
    $ objdump -d la25
    
    la25:     file format elf32-tradbigmips
    
    Disassembly of section .text:
    
    004000d0 <.pic.f2>:
      4000d0:	41b9 0040 	lui	t9,0x40
      4000d4:	d420 0083 	j	400106 <f2>
      4000d8:	3339 0107 	addiu	t9,t9,263
    	...
    
    004000e8 <.pic.f1>:
      4000e8:	41b9 0040 	lui	t9,0x40
      4000ec:	3339 00f1 	addiu	t9,t9,241
    
    004000f0 <f1>:
      4000f0:	41bc 0002 	lui	gp,0x2
      4000f4:	339c 801f 	addiu	gp,gp,-32737
      4000f8:	033c e150 	addu	gp,gp,t9
      4000fc:	f420 0083 	jal	400106 <f2>
      400100:	0000 0000 	nop
      400104:	45bf      	jrc	ra
    
    00400106 <f2>:
      400106:	45bf      	jrc	ra
    	...
    
    00400110 <__start>:
      400110:	f420 0074 	jal	4000e8 <.pic.f1>
      400114:	0000 0000 	nop
      400118:	f420 0068 	jal	4000d0 <.pic.f2>
      40011c:	0000 0000 	nop
    $
    
    There is no need to do anything for MIPS16 functions, because if any
    LA25 stub has been generated for such a function, then it is only
    required for an associated call thunk only, which is regular MIPS code
    and the address of which, with the ISA bit clear, is returned by
    `mips_elf_get_la25_target'.
    
    This problem has been there since the beginning of microMIPS support:
    
    commit df58fc944dbc6d5efd8d3826241b64b6af22f447
    Author: Richard Sandiford <rdsandiford@googlemail.com>
    Date:   Sun Jul 24 14:20:15 2011 +0000
    
    <https://sourceware.org/ml/binutils/2011-07/msg00198.html>, ("MIPS:
    microMIPS ASE support").
    
    	bfd/
    	* elfxx-mips.c (mips_elf_add_la25_stub): Clear the ISA bit of
    	the stub address retrieved if associated with a microMIPS
    	function.

Diff:
---
 bfd/ChangeLog    | 6 ++++++
 bfd/elfxx-mips.c | 2 ++
 2 files changed, 8 insertions(+)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 3ddafcb..303d97b 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,11 @@
 2016-08-10  Maciej W. Rozycki  <macro@imgtec.com>
 
+	* elfxx-mips.c (mips_elf_add_la25_stub): Clear the ISA bit of
+	the stub address retrieved if associated with a microMIPS
+	function.
+
+2016-08-10  Maciej W. Rozycki  <macro@imgtec.com>
+
 	* elfxx-mips.c (mips_elf_create_stub_symbol): For a microMIPS
 	stub also add STO_MICROMIPS annotation.
 
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index 6690428..ffc524f 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -1964,6 +1964,8 @@ mips_elf_add_la25_stub (struct bfd_link_info *info,
   /* Prefer to use LUI/ADDIU stubs if the function is at the beginning
      of the section and if we would need no more than 2 nops.  */
   value = mips_elf_get_la25_target (stub, &s);
+  if (ELF_ST_IS_MICROMIPS (stub->h->root.other))
+    value &= ~1;
   use_trampoline_p = (value != 0 || s->alignment_power > 4);
 
   h->la25_stub = stub;



More information about the Binutils-cvs mailing list