From 3734320dc054bd9f6632607e9e5c901c57450791 Mon Sep 17 00:00:00 2001 From: Matthew Fortune Date: Mon, 13 May 2019 17:03:19 -0700 Subject: [MIPS] Add generation of PLT entries with compact jumps for MIPS R6 Add a new option to get the linker to emit PLTs that use compact branches instead of delay slot branches. bfd/ * elfxx-mips.c (LA25_BC): New macro. (mips_elf_link_hash_table): New field. (STUB_JALRC): New macro. (mipsr6_o32_exec_plt0_entry_compact): New array. (mipsr6_n32_exec_plt0_entry_compact): Likewise. (mipsr6_n64_exec_plt0_entry_compact): Likewise. (mipsr6_exec_plt_entry_compact): Likewise. (mips_elf_create_la25_stub): Use BC instead of J for stubs when compact_branches is true. (_bfd_mips_elf_finish_dynamic_symbol): Choose the compact PLT for MIPSR6 with compact_branches. Do not reorder the compact branches PLT. Switch the lazy stub for MIPSR6 with compact_branches to use JALRC. (mips_finish_exec_plt): Choose the compact PLT0 for MIPSR6 when compact_branches is true. (_bfd_mips_elf_compact_branches): New function. * elfxx-mips.h (_bfd_mips_elf_compact_branches): New prototype. ld/ * emultempl/mipself.em (compact_branches): New static variable. (mips_create_output_section_statements): Call _bfd_mips_elf_compact_branches. (PARSE_AND_LIST_PROLOGUE): Add OPTION_COMPACT_BRANCHES and OPTION_NO_COMPACT_BRANCHES. (PARSE_AND_LIST_LONGOPTS): Add compact-branches, no-compact-branches. (PARSE_AND_LIST_OPTIONS): Add --compact-branches, --no-compact-branches. (PARSE_AND_LIST_ARGS_CASES): Handle the above. * ld.texinfo: Document --compact-branches, --no-compact-branches. * testsuite/ld-mips-elf/pic-and-nonpic-1-r6.dd: New test. * testsuite/ld-mips-elf/pic-and-nonpic-1-r6.nd: New test. * testsuite/ld-mips-elf/pic-and-nonpic-3a-r6.dd: New test. * testsuite/ld-mips-elf/pic-and-nonpic-3a-r6.gd: New test. * testsuite/ld-mips-elf/pic-and-nonpic-1a-r6.s: New test source. * testsuite/ld-mips-elf/pic-and-nonpic-3a-r6.s: New test source. * testsuite/ld-mips-elf/mips-elf.exp: Run the new tests. --- ld/ChangeLog | 22 +++++++++++ ld/emultempl/mipself.em | 26 +++++++++++- ld/ld.texi | 7 ++++ ld/testsuite/ld-mips-elf/mips-elf.exp | 13 ++++++ ld/testsuite/ld-mips-elf/pic-and-nonpic-1-r6.dd | 50 ++++++++++++++++++++++++ ld/testsuite/ld-mips-elf/pic-and-nonpic-1-r6.nd | 9 +++++ ld/testsuite/ld-mips-elf/pic-and-nonpic-1-r6.s | 0 ld/testsuite/ld-mips-elf/pic-and-nonpic-1a-r6.s | 28 +++++++++++++ ld/testsuite/ld-mips-elf/pic-and-nonpic-3a-r6.dd | 36 +++++++++++++++++ ld/testsuite/ld-mips-elf/pic-and-nonpic-3a-r6.gd | 21 ++++++++++ ld/testsuite/ld-mips-elf/pic-and-nonpic-3a-r6.s | 26 ++++++++++++ 11 files changed, 236 insertions(+), 2 deletions(-) create mode 100644 ld/testsuite/ld-mips-elf/pic-and-nonpic-1-r6.dd create mode 100644 ld/testsuite/ld-mips-elf/pic-and-nonpic-1-r6.nd create mode 100644 ld/testsuite/ld-mips-elf/pic-and-nonpic-1-r6.s create mode 100644 ld/testsuite/ld-mips-elf/pic-and-nonpic-1a-r6.s create mode 100644 ld/testsuite/ld-mips-elf/pic-and-nonpic-3a-r6.dd create mode 100644 ld/testsuite/ld-mips-elf/pic-and-nonpic-3a-r6.gd create mode 100644 ld/testsuite/ld-mips-elf/pic-and-nonpic-3a-r6.s (limited to 'ld') diff --git a/ld/ChangeLog b/ld/ChangeLog index 05af393..6896a72 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,25 @@ +2019-05-21 Matthew Fortune + Faraz Shahbazker + + * emultempl/mipself.em (compact_branches): New static variable. + (mips_create_output_section_statements): Call + _bfd_mips_elf_compact_branches. + (PARSE_AND_LIST_PROLOGUE): Add OPTION_COMPACT_BRANCHES and + OPTION_NO_COMPACT_BRANCHES. + (PARSE_AND_LIST_LONGOPTS): Add compact-branches, + no-compact-branches. + (PARSE_AND_LIST_OPTIONS): Add --compact-branches, + --no-compact-branches. + (PARSE_AND_LIST_ARGS_CASES): Handle the above. + * ld.texinfo: Document --compact-branches, --no-compact-branches. + * testsuite/ld-mips-elf/pic-and-nonpic-1-r6.dd: New test. + * testsuite/ld-mips-elf/pic-and-nonpic-1-r6.nd: New test. + * testsuite/ld-mips-elf/pic-and-nonpic-3a-r6.dd: New test. + * testsuite/ld-mips-elf/pic-and-nonpic-3a-r6.gd: New test. + * testsuite/ld-mips-elf/pic-and-nonpic-1a-r6.s: New test source. + * testsuite/ld-mips-elf/pic-and-nonpic-3a-r6.s: New test source. + * testsuite/ld-mips-elf/mips-elf.exp: Run the new tests. + 2019-05-21 Andre Vieira * testsuite/ld-arm/arm-elf.exp: Add tests diff --git a/ld/emultempl/mipself.em b/ld/emultempl/mipself.em index d9eeef3..ec908d7 100644 --- a/ld/emultempl/mipself.em +++ b/ld/emultempl/mipself.em @@ -44,6 +44,7 @@ static bfd *stub_bfd; static bfd_boolean insn32; static bfd_boolean ignore_branch_isa; +static bfd_boolean compact_branches; static void mips_after_parse (void) @@ -216,7 +217,10 @@ mips_create_output_section_statements (void) ${gnu_target}); if (is_mips_elf (link_info.output_bfd)) - _bfd_mips_elf_init_stubs (&link_info, mips_add_stub_section); + { + _bfd_mips_elf_compact_branches (&link_info, compact_branches); + _bfd_mips_elf_init_stubs (&link_info, mips_add_stub_section); + } } /* This is called after we have merged the private data of the input bfds. */ @@ -269,7 +273,9 @@ enum OPTION_INSN32 = 301, OPTION_NO_INSN32, OPTION_IGNORE_BRANCH_ISA, - OPTION_NO_IGNORE_BRANCH_ISA + OPTION_NO_IGNORE_BRANCH_ISA, + OPTION_COMPACT_BRANCHES, + OPTION_NO_COMPACT_BRANCHES }; ' @@ -278,6 +284,8 @@ PARSE_AND_LIST_LONGOPTS=' { "no-insn32", no_argument, NULL, OPTION_NO_INSN32 }, { "ignore-branch-isa", no_argument, NULL, OPTION_IGNORE_BRANCH_ISA }, { "no-ignore-branch-isa", no_argument, NULL, OPTION_NO_IGNORE_BRANCH_ISA }, + { "compact-branches", no_argument, NULL, OPTION_COMPACT_BRANCHES }, + { "no-compact-branches", no_argument, NULL, OPTION_NO_COMPACT_BRANCHES }, ' PARSE_AND_LIST_OPTIONS=' @@ -295,6 +303,12 @@ PARSE_AND_LIST_OPTIONS=' --no-ignore-branch-isa Reject invalid branch relocations requiring\n\ an ISA mode switch\n" )); + fprintf (file, _("\ + --compact-branches Generate compact branches/jumps for MIPS R6\n" + )); + fprintf (file, _("\ + --no-compact-branches Generate delay slot branches/jumps for MIPS R6\n" + )); ' PARSE_AND_LIST_ARGS_CASES=' @@ -313,6 +327,14 @@ PARSE_AND_LIST_ARGS_CASES=' case OPTION_NO_IGNORE_BRANCH_ISA: ignore_branch_isa = FALSE; break; + + case OPTION_COMPACT_BRANCHES: + compact_branches = TRUE; + break; + + case OPTION_NO_COMPACT_BRANCHES: + compact_branches = FALSE; + break; ' LDEMUL_AFTER_PARSE=mips_after_parse diff --git a/ld/ld.texi b/ld/ld.texi index f47db75..671a2a5 100644 --- a/ld/ld.texi +++ b/ld/ld.texi @@ -3197,6 +3197,13 @@ calculated. By default or if @samp{--no-ignore-branch-isa} is used a check is made causing the loss of an ISA mode transition to produce an error. +@kindex --compact-branches +@item --compact-branches +@kindex --no-compact-branches +@item --compact-branches +These options control the generation of compact instructions by the linker +in the PLT entries for MIPS R6. + @end table @c man end diff --git a/ld/testsuite/ld-mips-elf/mips-elf.exp b/ld/testsuite/ld-mips-elf/mips-elf.exp index e2063e5..cbbd9ad 100644 --- a/ld/testsuite/ld-mips-elf/mips-elf.exp +++ b/ld/testsuite/ld-mips-elf/mips-elf.exp @@ -523,6 +523,12 @@ if { $linux_gnu } { {{objdump -dr pic-and-nonpic-1.dd} {readelf --symbols pic-and-nonpic-1.nd}} "pic-and-nonpic-1-static1.o"} + {"PIC and non-PIC test 1 R6 compact branches (static 1)" + "-melf32btsmip -Tpic-and-nonpic-1.ld --compact-branches" "" + "-32 -EB -mips32r6" {pic-and-nonpic-1a-r6.s pic-and-nonpic-1b.s} + {{objdump -dr pic-and-nonpic-1-r6.dd} + {readelf --symbols pic-and-nonpic-1-r6.nd}} + "pic-and-nonpic-1-r6-static1.o"} {"PIC and non-PIC test 1 (static 2)" "-melf32btsmip -Tpic-and-nonpic-1.ld tmpdir/pic-and-nonpic-1-rel.o" "" "" {} @@ -586,6 +592,13 @@ if { $linux_gnu } { {readelf --symbols pic-and-nonpic-3b.nd} {readelf -d pic-and-nonpic-3b.ad}} "pic-and-nonpic-3b"} + {"PIC and non-PIC test 3 R6 compact branches (shared library)" + "-melf32btsmip -shared --compact-branches -Tpic-and-nonpic-3a.ld" "" + "-32 -EB -mips32r6" {pic-and-nonpic-3a-r6.s} + {{readelf --segments pic-and-nonpic-3a.sd} + {readelf -A pic-and-nonpic-3a-r6.gd} + {objdump -dr pic-and-nonpic-3a-r6.dd}} + "pic-and-nonpic-3a-r6.so"} } run_dump_test_o32 "pic-and-nonpic-3-error" {noarch {as -EB} {ld -EB}} run_ld_link_tests { diff --git a/ld/testsuite/ld-mips-elf/pic-and-nonpic-1-r6.dd b/ld/testsuite/ld-mips-elf/pic-and-nonpic-1-r6.dd new file mode 100644 index 0000000..86ad7a9 --- /dev/null +++ b/ld/testsuite/ld-mips-elf/pic-and-nonpic-1-r6.dd @@ -0,0 +1,50 @@ + +.* + +Disassembly of section \.text: + +00041000 <\.pic\.f3>: + 41000: 3c190004 lui t9,0x4 + 41004: 27391060 addiu t9,t9,4192 + 41008: c8000015 bc 41060 + 4100c: 00000000 nop + +00041010 <\.pic\.f2>: + 41010: 3c190004 lui t9,0x4 + 41014: 2739104c addiu t9,t9,4172 + 41018: c800000c bc 4104c + \.\.\. + +00041028 <\.pic\.f1>: + 41028: 3c190004 lui t9,0x4 + 4102c: 27391030 addiu t9,t9,4144 + +00041030 : + 41030: 3c1c0002 lui gp,0x2 + 41034: 279c6fd0 addiu gp,gp,28624 + 41038: 0399e021 addu gp,gp,t9 + 4103c: 0c010418 jal 41060 + 41040: 00000000 nop + 41044: 03e00009 jr ra + 41048: 00000000 nop + +0004104c : + 4104c: 3c1c0002 lui gp,0x2 + 41050: 279c6fb4 addiu gp,gp,28596 + 41054: 0399e021 addu gp,gp,t9 + 41058: 03e00009 jr ra + 4105c: 00000000 nop + +00041060 : + 41060: 00021400 sll v0,v0,0x10 + 41064: 00431021 addu v0,v0,v1 + \.\.\. + +00041070 <__start>: + 41070: 0c01040a jal 41028 <\.pic\.f1> + 41074: 00000000 nop + 41078: 0c010404 jal 41010 <\.pic\.f2> + 4107c: 00000000 nop + 41080: 0c010400 jal 41000 <\.pic\.f3> + 41084: 00000000 nop + \.\.\. diff --git a/ld/testsuite/ld-mips-elf/pic-and-nonpic-1-r6.nd b/ld/testsuite/ld-mips-elf/pic-and-nonpic-1-r6.nd new file mode 100644 index 0000000..5264505 --- /dev/null +++ b/ld/testsuite/ld-mips-elf/pic-and-nonpic-1-r6.nd @@ -0,0 +1,9 @@ +#... +.*: 00041000 +16 +FUNC +LOCAL +DEFAULT .* \.pic\.f3 +.*: 00068000 +0 +NOTYPE +LOCAL +DEFAULT +ABS _gp +.*: 00041028 +8 +FUNC +LOCAL +DEFAULT .* \.pic\.f1 +.*: 00041010 +16 +FUNC +LOCAL +DEFAULT .* \.pic\.f2 +.*: 00041060 +8 +FUNC +GLOBAL +DEFAULT .* f3 +.*: 00041070 +24 +FUNC +GLOBAL +DEFAULT .* __start +.*: 0004104c +20 +FUNC +GLOBAL +DEFAULT .* f2 +.*: 00041030 +28 +FUNC +GLOBAL +DEFAULT .* f1 diff --git a/ld/testsuite/ld-mips-elf/pic-and-nonpic-1-r6.s b/ld/testsuite/ld-mips-elf/pic-and-nonpic-1-r6.s new file mode 100644 index 0000000..e69de29 diff --git a/ld/testsuite/ld-mips-elf/pic-and-nonpic-1a-r6.s b/ld/testsuite/ld-mips-elf/pic-and-nonpic-1a-r6.s new file mode 100644 index 0000000..340004b --- /dev/null +++ b/ld/testsuite/ld-mips-elf/pic-and-nonpic-1a-r6.s @@ -0,0 +1,28 @@ + .abicalls + .global f1 + .global f2 + .global f3 + .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 + + .ent f3 +f3: + sll $2,16 + addu $2,$2,$3 + .end f3 diff --git a/ld/testsuite/ld-mips-elf/pic-and-nonpic-3a-r6.dd b/ld/testsuite/ld-mips-elf/pic-and-nonpic-3a-r6.dd new file mode 100644 index 0000000..80dac37 --- /dev/null +++ b/ld/testsuite/ld-mips-elf/pic-and-nonpic-3a-r6.dd @@ -0,0 +1,36 @@ +# GOT layout: +# +# -32752: lazy resolution function +# -32748: reserved for module pointer +# -32744: the GOT page entry +# -32740: foo's GOT entry +# -32736: ext's GOT entry + +.* + +Disassembly of section \.text: + +00000800 : + 800: 3c1c0001 lui gp,0x1 + 804: 279c7bf0 addiu gp,gp,31728 + 808: 0399e021 addu gp,gp,t9 + 80c: 8f99801c lw t9,-32740\(gp\) + 810: 8f828018 lw v0,-32744\(gp\) + 814: 24420000 addiu v0,v0,0 + 818: d8190000 jrc t9 + +0000081c : + 81c: 3c1c0001 lui gp,0x1 + 820: 279c7bd4 addiu gp,gp,31700 + 824: 0399e021 addu gp,gp,t9 + 828: 8f998020 lw t9,-32736\(gp\) + 82c: d8190000 jrc t9 +#... +Disassembly of section \.MIPS\.stubs: + +00000c00 <_MIPS_STUBS_>: + c00: 8f998010 lw t9,-32752\(gp\) + c04: 03e07825 move t7,ra + c08: 2418[0-9a-f]+ li t8,[0-9]+ + c0c: f8190000 jalrc t9 + \.\.\. diff --git a/ld/testsuite/ld-mips-elf/pic-and-nonpic-3a-r6.gd b/ld/testsuite/ld-mips-elf/pic-and-nonpic-3a-r6.gd new file mode 100644 index 0000000..af046ee --- /dev/null +++ b/ld/testsuite/ld-mips-elf/pic-and-nonpic-3a-r6.gd @@ -0,0 +1,21 @@ + +Attribute Section: gnu +File Attributes + Tag_GNU_MIPS_ABI_FP: Hard float \(32-bit CPU, 64-bit FPU\) + +Primary GOT: + Canonical gp value: 000183f0 + + Reserved entries: + Address Access Initial Purpose + 00010400 -32752\(gp\) 00000000 Lazy resolver + 00010404 -32748\(gp\) 80000000 Module pointer \(GNU extension\) + + Local entries: + Address Access Initial + 00010408 -32744\(gp\) 00010000 + + Global entries: + Address Access Initial Sym\.Val\. Type Ndx Name + 0001040c -32740\(gp\) 00000800 00000800 FUNC 6 foo + 00010410 -32736\(gp\) 00000c00 00000c00 FUNC UND ext diff --git a/ld/testsuite/ld-mips-elf/pic-and-nonpic-3a-r6.s b/ld/testsuite/ld-mips-elf/pic-and-nonpic-3a-r6.s new file mode 100644 index 0000000..fb8eb81 --- /dev/null +++ b/ld/testsuite/ld-mips-elf/pic-and-nonpic-3a-r6.s @@ -0,0 +1,26 @@ + .abicalls + .set nomips16 + .global foo + .ent foo +foo: + .set noreorder + .cpload $25 + .set reorder + lw $25,%call16(foo)($28) + lw $2,%got(data)($28) + addiu $2,$2,%lo(data) + jrc $25 + .end foo + + .global bar + .ent bar +bar: + .set noreorder + .cpload $25 + .set reorder + lw $25,%call16(ext)($28) + jrc $25 + .end bar + + .data +data: .word 0x12345678 -- cgit v1.1