From 80d873266deca488bd8059e32780e8ce3ef6191d Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 31 Aug 2012 04:26:17 +0000 Subject: [PATCH] Convert mov to lea for loading local function address bfd/ * elf32-i386.c (elf_i386_relocate_section): Convert "mov foo@GOT(%reg), %reg" to "lea foo@GOTOFF(%reg), %reg" for local symbols. * elf64-x86-64.c (elf_x86_64_relocate_section): Convert "mov foo@GOTPCREL(%rip), %reg" to "lea foo(%rip), %reg" for local symbols. ld/testsuite/ * ld-i386/i386.exp: Run lea1a, lea1b, lea1c. * ld-x86-64/x86-64.exp: Run lea1a, lea1b, lea1c, lea1d, lea1e, lea1f. * ld-i386/lea1.s: New file. * ld-i386/lea1a.d: Likewise. * ld-i386/lea1b.d: Likewise. * ld-i386/lea1c.d: Likewise. * ld-x86-64/lea1.s: Likewise. * ld-x86-64/lea1a.d: Likewise. * ld-x86-64/lea1b.d: Likewise. * ld-x86-64/lea1c.d: Likewise. * ld-x86-64/lea1d.d: Likewise. * ld-x86-64/lea1e.d: Likewise. * ld-x86-64/lea1f.d: Likewise. --- bfd/ChangeLog | 10 ++++++++++ bfd/elf32-i386.c | 18 ++++++++++++++++++ bfd/elf64-x86-64.c | 16 ++++++++++++++++ ld/testsuite/ChangeLog | 18 ++++++++++++++++++ ld/testsuite/ld-i386/i386.exp | 3 +++ ld/testsuite/ld-i386/lea1.s | 11 +++++++++++ ld/testsuite/ld-i386/lea1a.d | 13 +++++++++++++ ld/testsuite/ld-i386/lea1b.d | 13 +++++++++++++ ld/testsuite/ld-i386/lea1c.d | 13 +++++++++++++ ld/testsuite/ld-x86-64/lea1.s | 11 +++++++++++ ld/testsuite/ld-x86-64/lea1a.d | 13 +++++++++++++ ld/testsuite/ld-x86-64/lea1b.d | 13 +++++++++++++ ld/testsuite/ld-x86-64/lea1c.d | 13 +++++++++++++ ld/testsuite/ld-x86-64/lea1d.d | 13 +++++++++++++ ld/testsuite/ld-x86-64/lea1e.d | 13 +++++++++++++ ld/testsuite/ld-x86-64/lea1f.d | 13 +++++++++++++ ld/testsuite/ld-x86-64/x86-64.exp | 6 ++++++ 17 files changed, 210 insertions(+) create mode 100644 ld/testsuite/ld-i386/lea1.s create mode 100644 ld/testsuite/ld-i386/lea1a.d create mode 100644 ld/testsuite/ld-i386/lea1b.d create mode 100644 ld/testsuite/ld-i386/lea1c.d create mode 100644 ld/testsuite/ld-x86-64/lea1.s create mode 100644 ld/testsuite/ld-x86-64/lea1a.d create mode 100644 ld/testsuite/ld-x86-64/lea1b.d create mode 100644 ld/testsuite/ld-x86-64/lea1c.d create mode 100644 ld/testsuite/ld-x86-64/lea1d.d create mode 100644 ld/testsuite/ld-x86-64/lea1e.d create mode 100644 ld/testsuite/ld-x86-64/lea1f.d diff --git a/bfd/ChangeLog b/bfd/ChangeLog index a26977d83d..c6f424afca 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +2012-08-30 H.J. Lu + + * elf32-i386.c (elf_i386_relocate_section): Convert + "mov foo@GOT(%reg), %reg" to "lea foo@GOTOFF(%reg), %reg" + for local symbols. + + * elf64-x86-64.c (elf_x86_64_relocate_section): Convert + "mov foo@GOTPCREL(%rip), %reg" to "lea foo(%rip), %reg" + for local symbols. + 2012-08-31 Alan Modra PR ld/14464 diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 7d3652d81c..e67879f133 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -3470,6 +3470,24 @@ elf_i386_relocate_section (bfd *output_bfd, if (off >= (bfd_vma) -2) abort (); + if (h != NULL + && h->def_regular + && SYMBOL_REFERENCES_LOCAL (info, h) + && bfd_get_8 (input_bfd, + contents + rel->r_offset - 2) == 0x8b) + { + /* Convert + mov foo@GOT(%reg), %reg + to + lea foo@GOTOFF(%reg), %reg + */ + bfd_put_8 (output_bfd, 0x8d, + contents + rel->r_offset - 2); + relocation -= (htab->elf.sgotplt->output_section->vma + + htab->elf.sgotplt->output_offset); + break; + } + relocation = htab->elf.sgot->output_section->vma + htab->elf.sgot->output_offset + off - htab->elf.sgotplt->output_section->vma diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index a29ba8a324..cc40404d7d 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -3460,6 +3460,22 @@ elf_x86_64_relocate_section (bfd *output_bfd, if (off >= (bfd_vma) -2) abort (); + if (r_type == R_X86_64_GOTPCREL + && h->def_regular + && SYMBOL_REFERENCES_LOCAL (info, h) + && bfd_get_8 (input_bfd, + contents + rel->r_offset - 2) == 0x8b) + { + /* Convert + mov foo@GOTPCREL(%rip), %reg + to + lea foo(%rip), %reg + */ + bfd_put_8 (output_bfd, 0x8d, + contents + rel->r_offset - 2); + break; + } + relocation = base_got->output_section->vma + base_got->output_offset + off; if (r_type != R_X86_64_GOTPCREL && r_type != R_X86_64_GOTPCREL64) diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 5537d0a15b..bab65e4662 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,21 @@ +2012-08-30 H.J. Lu + + * ld-i386/i386.exp: Run lea1a, lea1b, lea1c. + * ld-x86-64/x86-64.exp: Run lea1a, lea1b, lea1c, lea1d, lea1e, + lea1f. + + * ld-i386/lea1.s: New file. + * ld-i386/lea1a.d: Likewise. + * ld-i386/lea1b.d: Likewise. + * ld-i386/lea1c.d: Likewise. + * ld-x86-64/lea1.s: Likewise. + * ld-x86-64/lea1a.d: Likewise. + * ld-x86-64/lea1b.d: Likewise. + * ld-x86-64/lea1c.d: Likewise. + * ld-x86-64/lea1d.d: Likewise. + * ld-x86-64/lea1e.d: Likewise. + * ld-x86-64/lea1f.d: Likewise. + 2012-08-30 H.J. Lu PR ld/14525 diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp index 03367ca129..b7e8042571 100644 --- a/ld/testsuite/ld-i386/i386.exp +++ b/ld/testsuite/ld-i386/i386.exp @@ -233,6 +233,9 @@ run_dump_test "pr12718" run_dump_test "pr12921" run_dump_test "pr12570a" run_dump_test "pr12570b" +run_dump_test "lea1a" +run_dump_test "lea1b" +run_dump_test "lea1c" if { !([istarget "i?86-*-linux*"] || [istarget "i?86-*-gnu*"] diff --git a/ld/testsuite/ld-i386/lea1.s b/ld/testsuite/ld-i386/lea1.s new file mode 100644 index 0000000000..6afad884d1 --- /dev/null +++ b/ld/testsuite/ld-i386/lea1.s @@ -0,0 +1,11 @@ + .text + .globl foo + .type foo, @function +foo: + ret + .size foo, .-foo + .globl _start + .type _start, @function +_start: + movl foo@GOT(%ecx), %eax + .size _start, .-_start diff --git a/ld/testsuite/ld-i386/lea1a.d b/ld/testsuite/ld-i386/lea1a.d new file mode 100644 index 0000000000..45b4965a94 --- /dev/null +++ b/ld/testsuite/ld-i386/lea1a.d @@ -0,0 +1,13 @@ +#source: lea1.s +#as: --32 +#ld: -Bsymbolic -shared -melf_i386 +#objdump: -dw + +.*: +file format .* + + +Disassembly of section .text: + +#... +[ ]*[a-f0-9]+: 8d 81 ([0-9a-f]{2} ){4} * lea -0x[a-f0-9]+\(%ecx\),%eax +#pass diff --git a/ld/testsuite/ld-i386/lea1b.d b/ld/testsuite/ld-i386/lea1b.d new file mode 100644 index 0000000000..9ad4464ff3 --- /dev/null +++ b/ld/testsuite/ld-i386/lea1b.d @@ -0,0 +1,13 @@ +#source: lea1.s +#as: --32 +#ld: -pie -melf_i386 +#objdump: -dw + +.*: +file format .* + + +Disassembly of section .text: + +#... +[ ]*[a-f0-9]+: 8d 81 ([0-9a-f]{2} ){4} * lea -0x[a-f0-9]+\(%ecx\),%eax +#pass diff --git a/ld/testsuite/ld-i386/lea1c.d b/ld/testsuite/ld-i386/lea1c.d new file mode 100644 index 0000000000..5ba8275324 --- /dev/null +++ b/ld/testsuite/ld-i386/lea1c.d @@ -0,0 +1,13 @@ +#source: lea1.s +#as: --32 +#ld: -melf_i386 +#objdump: -dw + +.*: +file format .* + + +Disassembly of section .text: + +#... +[ ]*[a-f0-9]+: 8d 81 ([0-9a-f]{2} ){4} * lea -0x[a-f0-9]+\(%ecx\),%eax +#pass diff --git a/ld/testsuite/ld-x86-64/lea1.s b/ld/testsuite/ld-x86-64/lea1.s new file mode 100644 index 0000000000..4dce487c3f --- /dev/null +++ b/ld/testsuite/ld-x86-64/lea1.s @@ -0,0 +1,11 @@ + .text + .globl foo + .type foo, @function +foo: + ret + .size foo, .-foo + .globl _start + .type _start, @function +_start: + movq foo@GOTPCREL(%rip), %rax + .size _start, .-_start diff --git a/ld/testsuite/ld-x86-64/lea1a.d b/ld/testsuite/ld-x86-64/lea1a.d new file mode 100644 index 0000000000..b48f253d0f --- /dev/null +++ b/ld/testsuite/ld-x86-64/lea1a.d @@ -0,0 +1,13 @@ +#source: lea1.s +#as: --64 +#ld: -Bsymbolic -shared -melf_x86_64 +#objdump: -dw + +.*: +file format .* + + +Disassembly of section .text: + +#... +[ ]*[a-f0-9]+: 48 8d 05 ([0-9a-f]{2} ){4} * lea -0x[a-f0-9]+\(%rip\),%rax # [a-f0-9]+ +#pass diff --git a/ld/testsuite/ld-x86-64/lea1b.d b/ld/testsuite/ld-x86-64/lea1b.d new file mode 100644 index 0000000000..9ee7220a49 --- /dev/null +++ b/ld/testsuite/ld-x86-64/lea1b.d @@ -0,0 +1,13 @@ +#source: lea1.s +#as: --64 +#ld: -pie -melf_x86_64 +#objdump: -dw + +.*: +file format .* + + +Disassembly of section .text: + +#... +[ ]*[a-f0-9]+: 48 8d 05 ([0-9a-f]{2} ){4} * lea -0x[a-f0-9]+\(%rip\),%rax # [a-f0-9]+ +#pass diff --git a/ld/testsuite/ld-x86-64/lea1c.d b/ld/testsuite/ld-x86-64/lea1c.d new file mode 100644 index 0000000000..6ff1618135 --- /dev/null +++ b/ld/testsuite/ld-x86-64/lea1c.d @@ -0,0 +1,13 @@ +#source: lea1.s +#as: --64 +#ld: -melf_x86_64 +#objdump: -dw + +.*: +file format .* + + +Disassembly of section .text: + +#... +[ ]*[a-f0-9]+: 48 8d 05 ([0-9a-f]{2} ){4} * lea -0x[a-f0-9]+\(%rip\),%rax # [a-f0-9]+ +#pass diff --git a/ld/testsuite/ld-x86-64/lea1d.d b/ld/testsuite/ld-x86-64/lea1d.d new file mode 100644 index 0000000000..d117f6b690 --- /dev/null +++ b/ld/testsuite/ld-x86-64/lea1d.d @@ -0,0 +1,13 @@ +#source: lea1.s +#as: --x32 +#ld: -Bsymbolic -shared -melf32_x86_64 +#objdump: -dw + +.*: +file format .* + + +Disassembly of section .text: + +#... +[ ]*[a-f0-9]+: 48 8d 05 ([0-9a-f]{2} ){4} * lea -0x[a-f0-9]+\(%rip\),%rax # [a-f0-9]+ +#pass diff --git a/ld/testsuite/ld-x86-64/lea1e.d b/ld/testsuite/ld-x86-64/lea1e.d new file mode 100644 index 0000000000..bde3e6f694 --- /dev/null +++ b/ld/testsuite/ld-x86-64/lea1e.d @@ -0,0 +1,13 @@ +#source: lea1.s +#as: --x32 +#ld: -pie -melf32_x86_64 +#objdump: -dw + +.*: +file format .* + + +Disassembly of section .text: + +#... +[ ]*[a-f0-9]+: 48 8d 05 ([0-9a-f]{2} ){4} * lea -0x[a-f0-9]+\(%rip\),%rax # [a-f0-9]+ +#pass diff --git a/ld/testsuite/ld-x86-64/lea1f.d b/ld/testsuite/ld-x86-64/lea1f.d new file mode 100644 index 0000000000..568143a294 --- /dev/null +++ b/ld/testsuite/ld-x86-64/lea1f.d @@ -0,0 +1,13 @@ +#source: lea1.s +#as: --x32 +#ld: -melf32_x86_64 +#objdump: -dw + +.*: +file format .* + + +Disassembly of section .text: + +#... +[ ]*[a-f0-9]+: 48 8d 05 ([0-9a-f]{2} ){4} * lea -0x[a-f0-9]+\(%rip\),%rax # [a-f0-9]+ +#pass diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index 1eb1b1c64c..1db81c83cc 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -276,6 +276,12 @@ run_dump_test "pr13082-5a" run_dump_test "pr13082-5b" run_dump_test "pr13082-6a" run_dump_test "pr13082-6b" +run_dump_test "lea1a" +run_dump_test "lea1b" +run_dump_test "lea1c" +run_dump_test "lea1d" +run_dump_test "lea1e" +run_dump_test "lea1f" # Must be native with the C compiler if { [isnative] && [which $CC] != 0 } { -- 2.34.1