* [committed 0/4] MIPS/BFD: LA25 stub generation fixes
@ 2016-08-10 21:33 Maciej W. Rozycki
2016-08-10 21:34 ` [committed 1/4] MIPS/BFD: Set the ISA bit in microMIPS LA25 stub references Maciej W. Rozycki
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Maciej W. Rozycki @ 2016-08-10 21:33 UTC (permalink / raw)
To: binutils; +Cc: Faraz Shahbazker
Hi,
A recent change to the MIPS/ELF BFD linker backend, commit 9d862524f6ae
("MIPS: Verify the ISA mode and alignment of branch and jump targets") has
caused a build regression in microMIPS glibc where the `zdump' tool fails
to link:
.../timezone/zdump.o: In function `yeartot':
.../timezone/zdump.c:758:(.text+0x62): Jump to a non-instruction-aligned address
.../timezone/zdump.c:758:(.text+0x76): Jump to a non-instruction-aligned address
.../timezone/zdump.c:768:(.text+0x112): Jump to a non-instruction-aligned address
.../timezone/zdump.c:774:(.text+0x1b8): Jump to a non-instruction-aligned address
.../timezone/zdump.c:774:(.text+0x1cc): Jump to a non-instruction-aligned address
collect2: error: ld returned 1 exit status
make[2]: *** [.../timezone/zdump] Error 1
This has been reported by Faraz and has been missed in the development of
the commit referred as we lack a test case for LA25 stub generation in
microMIPS code.
I have therefore adapted one of the existing test cases aimed at LA25
stubs in regular MIPS code. That test case triggered further 3 bugs, of
which 2 -- for the total of 3 -- are addressed in this small patch series.
The test case then follows as a separate 4th patch only as otherwise it
would initially have to fail, or alternatively accept incorrect output and
then get adjusted with each of the following fixes.
The 4th bug seems very complex to fix and is a missed optimisation rather
than a correctness issue, and then for a corner case only. I have
therefore decided not to address it at this time and filed PR ld/20453
instead, recording a KFAIL in the test suite.
See individual patch descriptions for the details of the problems
addressed.
Maciej
^ permalink raw reply [flat|nested] 5+ messages in thread
* [committed 1/4] MIPS/BFD: Set the ISA bit in microMIPS LA25 stub references
2016-08-10 21:33 [committed 0/4] MIPS/BFD: LA25 stub generation fixes Maciej W. Rozycki
@ 2016-08-10 21:34 ` Maciej W. Rozycki
2016-08-10 21:35 ` [committed 2/4] MIPS/BFD: Add microMIPS annotation to LA25 stub symbols Maciej W. Rozycki
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Maciej W. Rozycki @ 2016-08-10 21:34 UTC (permalink / raw)
To: binutils; +Cc: Faraz Shahbazker
Fix a linker regression introduced with commit 9d862524f6ae ("MIPS:
Verify the ISA mode and alignment of branch and jump targets") causing a
build failure in microMIPS glibc where the `zdump' tool fails to link:
.../timezone/zdump.o: In function `yeartot':
.../timezone/zdump.c:758:(.text+0x62): Jump to a non-instruction-aligned address
.../timezone/zdump.c:758:(.text+0x76): Jump to a non-instruction-aligned address
.../timezone/zdump.c:768:(.text+0x112): Jump to a non-instruction-aligned address
.../timezone/zdump.c:774:(.text+0x1b8): Jump to a non-instruction-aligned address
.../timezone/zdump.c:774:(.text+0x1cc): Jump to a non-instruction-aligned address
collect2: error: ld returned 1 exit status
make[2]: *** [.../timezone/zdump] Error 1
The cause of the failure is the stricter check introduced with the said
change for jump and branch targets tripping on the address of microMIPS
LA25 stubs. Despite being microMIPS code these stubs do not have the
ISA bit set throughout the relocation calculation process, because they
have their address set to the memory offset into the stub section they
are placed in.
The `mips_elf_la25_stub' structure does not carry ISA mode information,
but there is no need to extend it, because the ISA mode can be inferred
from the original symbol, which will have STO_MICROMIPS annotation, so
use that instead to set the ISA bit appropriately. Also only LA25 stubs
associated with microMIPS symbols need to have the ISA bit set, because
other LA25 stubs are made with regular MIPS code, even if associated
with a MIPS16 symbol (in which case they are needed by a call thunk only
rather than the MIPS16 function proper).
bfd/
* elfxx-mips.c (mips_elf_calculate_relocation): Set the ISA bit
in microMIPS LA25 stub references.
---
binutils-umips-bfd-la25-isa-bit.diff
Index: binutils/bfd/elfxx-mips.c
===================================================================
--- binutils.orig/bfd/elfxx-mips.c 2016-08-08 16:50:32.668787260 +0100
+++ binutils/bfd/elfxx-mips.c 2016-08-08 17:31:58.912513411 +0100
@@ -5577,9 +5580,13 @@ mips_elf_calculate_relocation (bfd *abfd
else if (h != NULL && h->la25_stub
&& mips_elf_relocation_needs_la25_stub (input_bfd, r_type,
target_is_16_bit_code_p))
- symbol = (h->la25_stub->stub_section->output_section->vma
- + h->la25_stub->stub_section->output_offset
- + h->la25_stub->offset);
+ {
+ symbol = (h->la25_stub->stub_section->output_section->vma
+ + h->la25_stub->stub_section->output_offset
+ + h->la25_stub->offset);
+ if (ELF_ST_IS_MICROMIPS (h->root.other))
+ symbol |= 1;
+ }
/* For direct MIPS16 and microMIPS calls make sure the compressed PLT
entry is used if a standard PLT entry has also been made. In this
case the symbol will have been set by mips_elf_set_plt_sym_value
^ permalink raw reply [flat|nested] 5+ messages in thread
* [committed 2/4] MIPS/BFD: Add microMIPS annotation to LA25 stub symbols
2016-08-10 21:33 [committed 0/4] MIPS/BFD: LA25 stub generation fixes Maciej W. Rozycki
2016-08-10 21:34 ` [committed 1/4] MIPS/BFD: Set the ISA bit in microMIPS LA25 stub references Maciej W. Rozycki
@ 2016-08-10 21:35 ` Maciej W. Rozycki
2016-08-10 21:36 ` [committed 4/4] MIPS/LD/testsuite: Verify microMIPS LA25 stub generation Maciej W. Rozycki
2016-08-10 21:36 ` [committed 3/4] MIPS/BFD: Actually produce short microMIPS LA25 stubs Maciej W. Rozycki
3 siblings, 0 replies; 5+ messages in thread
From: Maciej W. Rozycki @ 2016-08-10 21:35 UTC (permalink / raw)
To: binutils; +Cc: Faraz Shahbazker
Fix a problem with missing microMIPS symbol annotation with microMIPS
LA25 stub symbols. The consequence of the issue is these symbols appear
in the symbol table as regular MIPS symbols with the ISA bit set, as
shown with the example below:
$ 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
$ readelf -s la25
Symbol table '.symtab' contains 18 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00400098 0 SECTION LOCAL DEFAULT 1
2: 004000b0 0 SECTION LOCAL DEFAULT 2
3: 004000d0 0 SECTION LOCAL DEFAULT 3
4: 00000000 0 SECTION LOCAL DEFAULT 4
5: 00000000 0 SECTION LOCAL DEFAULT 5
6: 00418110 0 NOTYPE LOCAL DEFAULT 3 _gp
7: 004000e1 16 FUNC LOCAL DEFAULT 3 .pic.f1
8: 004000d1 16 FUNC LOCAL DEFAULT 3 .pic.f2
9: 00410120 0 NOTYPE GLOBAL DEFAULT 3 _fdata
10: 00400110 16 FUNC GLOBAL DEFAULT [MICROMIPS] 3 __start
11: 00400106 2 FUNC GLOBAL DEFAULT [MICROMIPS] 3 f2
12: 004000d0 0 NOTYPE GLOBAL DEFAULT 3 _ftext
13: 00410120 0 NOTYPE GLOBAL DEFAULT 3 __bss_start
14: 004000f0 22 FUNC GLOBAL DEFAULT [MICROMIPS] 3 f1
15: 00410120 0 NOTYPE GLOBAL DEFAULT 3 _edata
16: 00410120 0 NOTYPE GLOBAL DEFAULT 3 _end
17: 00410120 0 NOTYPE GLOBAL DEFAULT 3 _fbss
$
where microMIPS annotation is missing for `.pic.f1' and `.pic.f2' even
though these stubs are associated with microMIPS functions `f1' and `f2'
respectively.
Add the missing annotation then, by copying it from the function symbol
an LA25 stub is associated with, correcting the example above:
$ readelf -s la25
Symbol table '.symtab' contains 18 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00400098 0 SECTION LOCAL DEFAULT 1
2: 004000b0 0 SECTION LOCAL DEFAULT 2
3: 004000d0 0 SECTION LOCAL DEFAULT 3
4: 00000000 0 SECTION LOCAL DEFAULT 4
5: 00000000 0 SECTION LOCAL DEFAULT 5
6: 00418110 0 NOTYPE LOCAL DEFAULT 3 _gp
7: 004000e0 16 FUNC LOCAL DEFAULT [MICROMIPS] 3 .pic.f1
8: 004000d0 16 FUNC LOCAL DEFAULT [MICROMIPS] 3 .pic.f2
9: 00410120 0 NOTYPE GLOBAL DEFAULT 3 _fdata
10: 00400110 16 FUNC GLOBAL DEFAULT [MICROMIPS] 3 __start
11: 00400106 2 FUNC GLOBAL DEFAULT [MICROMIPS] 3 f2
12: 004000d0 0 NOTYPE GLOBAL DEFAULT 3 _ftext
13: 00410120 0 NOTYPE GLOBAL DEFAULT 3 __bss_start
14: 004000f0 22 FUNC GLOBAL DEFAULT [MICROMIPS] 3 f1
15: 00410120 0 NOTYPE GLOBAL DEFAULT 3 _edata
16: 00410120 0 NOTYPE GLOBAL DEFAULT 3 _end
17: 00410120 0 NOTYPE GLOBAL DEFAULT 3 _fbss
$
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_create_stub_symbol): For a microMIPS
stub also add STO_MICROMIPS annotation.
---
binutils-umips-bfd-la25-st-other.diff
Index: binutils/bfd/elfxx-mips.c
===================================================================
--- binutils.orig/bfd/elfxx-mips.c 2016-08-08 16:50:32.668787260 +0100
+++ binutils/bfd/elfxx-mips.c 2016-08-08 17:31:58.912513411 +0100
@@ -1578,12 +1578,13 @@ mips_elf_create_stub_symbol (struct bfd_
const char *prefix, asection *s, bfd_vma value,
bfd_vma size)
{
+ bfd_boolean micromips_p = ELF_ST_IS_MICROMIPS (h->root.other);
struct bfd_link_hash_entry *bh;
struct elf_link_hash_entry *elfh;
char *name;
bfd_boolean res;
- if (ELF_ST_IS_MICROMIPS (h->root.other))
+ if (micromips_p)
value |= 1;
/* Create a new symbol. */
@@ -1601,6 +1602,8 @@ mips_elf_create_stub_symbol (struct bfd_
elfh->type = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
elfh->size = size;
elfh->forced_local = 1;
+ if (micromips_p)
+ elfh->other = ELF_ST_SET_MICROMIPS (elfh->other);
return TRUE;
}
^ permalink raw reply [flat|nested] 5+ messages in thread
* [committed 4/4] MIPS/LD/testsuite: Verify microMIPS LA25 stub generation
2016-08-10 21:33 [committed 0/4] MIPS/BFD: LA25 stub generation fixes Maciej W. Rozycki
2016-08-10 21:34 ` [committed 1/4] MIPS/BFD: Set the ISA bit in microMIPS LA25 stub references Maciej W. Rozycki
2016-08-10 21:35 ` [committed 2/4] MIPS/BFD: Add microMIPS annotation to LA25 stub symbols Maciej W. Rozycki
@ 2016-08-10 21:36 ` Maciej W. Rozycki
2016-08-10 21:36 ` [committed 3/4] MIPS/BFD: Actually produce short microMIPS LA25 stubs Maciej W. Rozycki
3 siblings, 0 replies; 5+ messages in thread
From: Maciej W. Rozycki @ 2016-08-10 21:36 UTC (permalink / raw)
To: binutils; +Cc: Faraz Shahbazker
Repeat `PIC and non-PIC test 1' checks for microMIPS LA25 stubs,
covering code generation and stub symbol annotation.
ld/
* testsuite/ld-mips-elf/pic-and-nonpic-1-micromips-rel.dd: New
test.
* testsuite/ld-mips-elf/pic-and-nonpic-1-micromips-rel.nd: New
test.
* testsuite/ld-mips-elf/pic-and-nonpic-1-micromips.dd: New test.
* testsuite/ld-mips-elf/pic-and-nonpic-1-micromips.nd: New test.
* testsuite/ld-mips-elf/pic-and-nonpic-1a-micromips.s: New test
source.
* testsuite/ld-mips-elf/pic-and-nonpic-1b-micromips.s: New test
source.
* testsuite/ld-mips-elf/mips-elf.exp: Run the new tests.
---
binutils-mips-cross-mode-la25-test.diff
Index: binutils/ld/testsuite/ld-mips-elf/mips-elf.exp
===================================================================
--- binutils.orig/ld/testsuite/ld-mips-elf/mips-elf.exp 2016-08-10 12:48:18.558855684 +0100
+++ binutils/ld/testsuite/ld-mips-elf/mips-elf.exp 2016-08-10 21:41:34.633794932 +0100
@@ -357,6 +357,8 @@ if { $linux_gnu } {
#
# The third test checks that we do the same when linking the
# result of the first link (with no other source files).
+ #
+ # We then repeat the same three tests for microMIPS stubs.
run_ld_link_tests {
{"PIC and non-PIC test 1 (relocatable)" "-r -melf32btsmip" ""
"-32 -EB -mips2" {pic-and-nonpic-1a.s pic-and-nonpic-1b.s}
@@ -375,6 +377,42 @@ if { $linux_gnu } {
{{objdump -dr pic-and-nonpic-1.dd}
{readelf --symbols pic-and-nonpic-1.nd}}
"pic-and-nonpic-1-static2.o"}
+ {"PIC and non-PIC test 1, microMIPS (relocatable)"
+ "-r -melf32btsmip" ""
+ "-32 -EB -mips2"
+ {pic-and-nonpic-1a-micromips.s pic-and-nonpic-1b-micromips.s}
+ {{objdump -dr pic-and-nonpic-1-micromips-rel.dd}
+ {readelf --symbols pic-and-nonpic-1-micromips-rel.nd}}
+ "pic-and-nonpic-1-micromips-rel.o"}
+ {"PIC and non-PIC test 1, microMIPS (static 1)"
+ "-melf32btsmip -Tpic-and-nonpic-1.ld" ""
+ "-32 -EB -mips2"
+ {pic-and-nonpic-1a-micromips.s pic-and-nonpic-1b-micromips.s}
+ {{objdump -dr pic-and-nonpic-1-micromips.dd}
+ {readelf --symbols pic-and-nonpic-1-micromips.nd}}
+ "pic-and-nonpic-1-micromips-static1.o"}
+ }
+ # The final executable produced with the following test is supposed
+ # to be the same as one produced with the preceding test, however
+ # as noted in PR ld/20453 it is not. Consequently output from
+ # `objdump -dr' is not the same either. Expect:
+ #
+ # regexp_diff match failure
+ # regexp "^ 4103c: f001 0415 jalx 41054 <f3>$"
+ # line " 4103c: f001 0400 jalx 41000 <.pic.f3>"
+ #
+ # from the test below due to this problem.
+ setup_kfail "mips*-*-*" "ld/20453"
+ # The final check below should be folded into the `run_ld_link_tests'
+ # call above once `setup_kfail' has been removed.
+ run_ld_link_tests {
+ {"PIC and non-PIC test 1, microMIPS (static 2)"
+ "-melf32btsmip -Tpic-and-nonpic-1.ld \
+ tmpdir/pic-and-nonpic-1-micromips-rel.o" ""
+ "" {}
+ {{objdump -dr pic-and-nonpic-1-micromips.dd}
+ {readelf --symbols pic-and-nonpic-1-micromips.nd}}
+ "pic-and-nonpic-1-micromips-static2.o"}
}
run_dump_test "pic-and-nonpic-2"
run_ld_link_tests {
Index: binutils/ld/testsuite/ld-mips-elf/pic-and-nonpic-1-micromips-rel.dd
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/pic-and-nonpic-1-micromips-rel.dd 2016-08-10 20:45:05.600801556 +0100
@@ -0,0 +1,42 @@
+
+.*
+
+Disassembly of section \.text:
+
+00000000 <f1>:
+ 0: 41bc 0000 lui gp,0x0
+ 0: R_MICROMIPS_HI16 _gp_disp
+ 4: 339c 0000 addiu gp,gp,0
+ 4: R_MICROMIPS_LO16 _gp_disp
+ 8: 033c e150 addu gp,gp,t9
+ c: f400 0000 jal 0 .*
+ c: R_MICROMIPS_26_S1 f3
+ 10: 0000 0000 nop
+ 14: 45bf jrc ra
+
+00000016 <f2>:
+ 16: 41bc 0000 lui gp,0x0
+ 16: R_MICROMIPS_HI16 _gp_disp
+ 1a: 339c 0000 addiu gp,gp,0
+ 1a: R_MICROMIPS_LO16 _gp_disp
+ 1e: 033c e150 addu gp,gp,t9
+ 22: 45bf jrc ra
+
+00000024 <f3>:
+ 24: 3c1c0000 lui gp,0x0
+ 24: R_MIPS_HI16 _gp_disp
+ 28: 279c0000 addiu gp,gp,0
+ 28: R_MIPS_LO16 _gp_disp
+ 2c: 0399e021 addu gp,gp,t9
+
+00000030 <__start>:
+ 30: f400 0000 jal 0 .*
+ 30: R_MICROMIPS_26_S1 f1
+ 34: 0000 0000 nop
+ 38: f400 0000 jal 0 .*
+ 38: R_MICROMIPS_26_S1 f2
+ 3c: 0000 0000 nop
+ 40: f400 0000 jal 0 .*
+ 40: R_MICROMIPS_26_S1 f3
+ 44: 0000 0000 nop
+ \.\.\.
Index: binutils/ld/testsuite/ld-mips-elf/pic-and-nonpic-1-micromips-rel.nd
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/pic-and-nonpic-1-micromips-rel.nd 2016-08-10 20:45:05.614008484 +0100
@@ -0,0 +1,5 @@
+#...
+.*: 00000024 +12 +FUNC +GLOBAL +DEFAULT +\[MIPS PIC\] .* f3
+.*: 00000030 +24 +FUNC +GLOBAL +DEFAULT +\[MICROMIPS\] .* __start
+.*: 00000016 +14 +FUNC +GLOBAL +DEFAULT +\[MICROMIPS, MIPS PIC\] .* f2
+.*: 00000000 +22 +FUNC +GLOBAL +DEFAULT +\[MICROMIPS, MIPS PIC\] .* f1
Index: binutils/ld/testsuite/ld-mips-elf/pic-and-nonpic-1-micromips.dd
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/pic-and-nonpic-1-micromips.dd 2016-08-10 20:45:05.633226287 +0100
@@ -0,0 +1,48 @@
+
+.*
+
+Disassembly of section \.text:
+
+00041000 <\.pic\.f3>:
+ 41000: 3c190004 lui t9,0x4
+ 41004: 08010415 j 41054 <f3>
+ 41008: 27391054 addiu t9,t9,4180
+ 4100c: 00000000 nop
+
+00041010 <\.pic\.f2>:
+ 41010: 41b9 0004 lui t9,0x4
+ 41014: d402 0823 j 41046 <f2>
+ 41018: 3339 1047 addiu t9,t9,4167
+ \.\.\.
+
+00041028 <\.pic\.f1>:
+ 41028: 41b9 0004 lui t9,0x4
+ 4102c: 3339 1031 addiu t9,t9,4145
+
+00041030 <f1>:
+ 41030: 41bc 0002 lui gp,0x2
+ 41034: 339c 6fcf addiu gp,gp,28623
+ 41038: 033c e150 addu gp,gp,t9
+ 4103c: f001 0415 jalx 41054 <f3>
+ 41040: 0000 0000 nop
+ 41044: 45bf jrc ra
+
+00041046 <f2>:
+ 41046: 41bc 0002 lui gp,0x2
+ 4104a: 339c 6fb9 addiu gp,gp,28601
+ 4104e: 033c e150 addu gp,gp,t9
+ 41052: 45bf jrc ra
+
+00041054 <f3>:
+ 41054: 3c1c0002 lui gp,0x2
+ 41058: 279c6fac addiu gp,gp,28588
+ 4105c: 0399e021 addu gp,gp,t9
+
+00041060 <__start>:
+ 41060: f402 0814 jal 41028 <\.pic\.f1>
+ 41064: 0000 0000 nop
+ 41068: f402 0808 jal 41010 <\.pic\.f2>
+ 4106c: 0000 0000 nop
+ 41070: f001 0400 jalx 41000 <\.pic\.f3>
+ 41074: 0000 0000 nop
+ \.\.\.
Index: binutils/ld/testsuite/ld-mips-elf/pic-and-nonpic-1-micromips.nd
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/pic-and-nonpic-1-micromips.nd 2016-08-10 20:45:05.656425528 +0100
@@ -0,0 +1,8 @@
+#...
+.*: 00068000 +0 +NOTYPE +LOCAL +DEFAULT +ABS _gp
+.*: 00041028 +8 +FUNC +LOCAL +DEFAULT +\[MICROMIPS\] .* .pic.f1
+.*: 00041010 +16 +FUNC +LOCAL +DEFAULT +\[MICROMIPS\] .* .pic.f2
+.*: 00041054 +12 +FUNC +GLOBAL +DEFAULT .* f3
+.*: 00041060 +24 +FUNC +GLOBAL +DEFAULT +\[MICROMIPS\] .* __start
+.*: 00041046 +14 +FUNC +GLOBAL +DEFAULT +\[MICROMIPS\] .* f2
+.*: 00041030 +22 +FUNC +GLOBAL +DEFAULT +\[MICROMIPS\] .* f1
Index: binutils/ld/testsuite/ld-mips-elf/pic-and-nonpic-1a-micromips.s
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/pic-and-nonpic-1a-micromips.s 2016-08-10 20:45:05.682724773 +0100
@@ -0,0 +1,31 @@
+ .abicalls
+ .global f1
+ .global f2
+ .global f3
+ .set micromips
+ .ent f1
+f1:
+ .set noreorder
+ .cpload $25
+ .set reorder
+ .option pic0
+ jal f3
+ .option pic2
+ jr $31
+ .end f1
+
+ .ent f2
+f2:
+ .set noreorder
+ .cpload $25
+ .set reorder
+ jr $31
+ .end f2
+
+ .set nomicromips
+ .ent f3
+f3:
+ .set noreorder
+ .cpload $25
+ .set reorder
+ .end f3
Index: binutils/ld/testsuite/ld-mips-elf/pic-and-nonpic-1b-micromips.s
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/pic-and-nonpic-1b-micromips.s 2016-08-10 20:45:05.699949948 +0100
@@ -0,0 +1,10 @@
+ .abicalls
+ .option pic0
+ .global __start
+ .set micromips
+ .ent __start
+__start:
+ jal f1
+ jal f2
+ jal f3
+ .end __start
^ permalink raw reply [flat|nested] 5+ messages in thread
* [committed 3/4] MIPS/BFD: Actually produce short microMIPS LA25 stubs
2016-08-10 21:33 [committed 0/4] MIPS/BFD: LA25 stub generation fixes Maciej W. Rozycki
` (2 preceding siblings ...)
2016-08-10 21:36 ` [committed 4/4] MIPS/LD/testsuite: Verify microMIPS LA25 stub generation Maciej W. Rozycki
@ 2016-08-10 21:36 ` Maciej W. Rozycki
3 siblings, 0 replies; 5+ messages in thread
From: Maciej W. Rozycki @ 2016-08-10 21:36 UTC (permalink / raw)
To: binutils; +Cc: Faraz Shahbazker
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.
---
binutils-umips-bfd-la25-intro.diff
Index: binutils/bfd/elfxx-mips.c
===================================================================
--- binutils.orig/bfd/elfxx-mips.c 2016-08-08 18:30:42.104494144 +0100
+++ binutils/bfd/elfxx-mips.c 2016-08-08 18:30:45.076850724 +0100
@@ -1964,6 +1964,8 @@ mips_elf_add_la25_stub (struct bfd_link_
/* 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;
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2016-08-10 21:36 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-10 21:33 [committed 0/4] MIPS/BFD: LA25 stub generation fixes Maciej W. Rozycki
2016-08-10 21:34 ` [committed 1/4] MIPS/BFD: Set the ISA bit in microMIPS LA25 stub references Maciej W. Rozycki
2016-08-10 21:35 ` [committed 2/4] MIPS/BFD: Add microMIPS annotation to LA25 stub symbols Maciej W. Rozycki
2016-08-10 21:36 ` [committed 4/4] MIPS/LD/testsuite: Verify microMIPS LA25 stub generation Maciej W. Rozycki
2016-08-10 21:36 ` [committed 3/4] MIPS/BFD: Actually produce short microMIPS LA25 stubs Maciej W. Rozycki
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).