From 4c10bbaa0912742322f10d9d5bb630ba4e15dfa7 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Tue, 15 Mar 2016 11:07:06 -0700 Subject: [PATCH] Add -z noreloc-overflow option to x86-64 ld Add -z noreloc-overflow command-line option to the x86-64 ELF linker to disable relocation overflow check. This can be used to avoid relocation overflow check if there will be no dynamic relocation overflow at run-time. bfd/ PR ld/19807 * elf64-x86-64.c (elf_x86_64_relocate_section): Check no_reloc_overflow_check to diable R_X86_64_32/R_X86_64_32S relocation overflow check. include/ PR ld/19807 * bfdlink.h (bfd_link_info): Add no_reloc_overflow_check. ld/ PR ld/19807 * Makefile.am (ELF_X86_DEPS): Add $(srcdir)/emulparams/reloc_overflow.sh. * Makefile.in: Regenerated. * NEWS: Mention -z noreloc-overflow. * ld.texinfo: Document -z noreloc-overflow. * emulparams/elf32_x86_64.sh: Source ${srcdir}/emulparams/reloc_overflow.sh. * emulparams/elf_x86_64.sh: Likewise. * emulparams/reloc_overflow.sh: New file. * testsuite/ld-x86-64/pr19807-1.s: New file. * testsuite/ld-x86-64/pr19807-1a.d: Likewise. * testsuite/ld-x86-64/pr19807-1b.d: Likewise. * testsuite/ld-x86-64/pr19807-2.s: Likewise. * testsuite/ld-x86-64/pr19807-2a.d: Likewise. * testsuite/ld-x86-64/pr19807-2b.d: Likewise. * testsuite/ld-x86-64/pr19807-2c.d: Likewise. * testsuite/ld-x86-64/pr19807-2d.d: Likewise. * testsuite/ld-x86-64/pr19807-2e.d: Likewise. * testsuite/ld-x86-64/x86-64.exp: Run PR ld/19807 tests. --- bfd/ChangeLog | 7 +++++++ bfd/elf64-x86-64.c | 14 ++++++++++---- include/ChangeLog | 5 +++++ include/bfdlink.h | 3 +++ ld/ChangeLog | 23 +++++++++++++++++++++++ ld/Makefile.am | 1 + ld/Makefile.in | 1 + ld/NEWS | 3 +++ ld/emulparams/elf32_x86_64.sh | 1 + ld/emulparams/elf_x86_64.sh | 1 + ld/emulparams/reloc_overflow.sh | 11 +++++++++++ ld/ld.texinfo | 5 +++++ ld/testsuite/ld-x86-64/pr19807-1.s | 8 ++++++++ ld/testsuite/ld-x86-64/pr19807-1a.d | 13 +++++++++++++ ld/testsuite/ld-x86-64/pr19807-1b.d | 13 +++++++++++++ ld/testsuite/ld-x86-64/pr19807-2.s | 8 ++++++++ ld/testsuite/ld-x86-64/pr19807-2a.d | 4 ++++ ld/testsuite/ld-x86-64/pr19807-2b.d | 8 ++++++++ ld/testsuite/ld-x86-64/pr19807-2c.d | 13 +++++++++++++ ld/testsuite/ld-x86-64/pr19807-2d.d | 8 ++++++++ ld/testsuite/ld-x86-64/pr19807-2e.d | 13 +++++++++++++ ld/testsuite/ld-x86-64/x86-64.exp | 7 +++++++ 22 files changed, 166 insertions(+), 4 deletions(-) create mode 100644 ld/emulparams/reloc_overflow.sh create mode 100644 ld/testsuite/ld-x86-64/pr19807-1.s create mode 100644 ld/testsuite/ld-x86-64/pr19807-1a.d create mode 100644 ld/testsuite/ld-x86-64/pr19807-1b.d create mode 100644 ld/testsuite/ld-x86-64/pr19807-2.s create mode 100644 ld/testsuite/ld-x86-64/pr19807-2a.d create mode 100644 ld/testsuite/ld-x86-64/pr19807-2b.d create mode 100644 ld/testsuite/ld-x86-64/pr19807-2c.d create mode 100644 ld/testsuite/ld-x86-64/pr19807-2d.d create mode 100644 ld/testsuite/ld-x86-64/pr19807-2e.d diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 89180cb256..2bb0cc1ea6 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2016-03-15 H.J. Lu + + PR ld/19807 + * elf64-x86-64.c (elf_x86_64_relocate_section): Check + no_reloc_overflow_check to diable R_X86_64_32/R_X86_64_32S + relocation overflow check. + 2016-03-14 H.J. Lu * bfd-in2.h: Regenerated. diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 380376d93c..31b1f87d0b 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -1973,8 +1973,10 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, /* Let's help debug shared library creation. These relocs cannot be used in shared libs. Don't error out for sections we don't care about, such as debug sections or - non-constant sections. */ - if (bfd_link_pic (info) + non-constant sections, or when relocation overflow check + is disabled. */ + if (!info->no_reloc_overflow_check + && bfd_link_pic (info) && (sec->flags & SEC_ALLOC) != 0 && (sec->flags & SEC_READONLY) != 0) { @@ -4842,8 +4844,12 @@ direct: } else { - /* This symbol is local, or marked to become local. */ - if (r_type == htab->pointer_r_type) + /* This symbol is local, or marked to become local. + When relocation overflow check is disabled, we + convert R_X86_64_32 to dynamic R_X86_64_RELATIVE. */ + if (r_type == htab->pointer_r_type + || (r_type == R_X86_64_32 + && info->no_reloc_overflow_check)) { relocate = TRUE; outrel.r_info = htab->r_info (0, R_X86_64_RELATIVE); diff --git a/include/ChangeLog b/include/ChangeLog index 7e01b279bd..3523a27ede 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,8 @@ +2016-03-15 H.J. Lu + + PR ld/19807 + * bfdlink.h (bfd_link_info): Add no_reloc_overflow_check. + 2016-03-08 Cupertino Miranda Andrew Burgess diff --git a/include/bfdlink.h b/include/bfdlink.h index eeea6ef7a9..a285f6dc5e 100644 --- a/include/bfdlink.h +++ b/include/bfdlink.h @@ -446,6 +446,9 @@ struct bfd_link_info /* TRUE if generation of .interp/PT_INTERP should be suppressed. */ unsigned int nointerp: 1; + /* TRUE if we shouldn't check relocation overflow. */ + unsigned int no_reloc_overflow_check: 1; + /* TRUE if generate a 1-byte NOP as suffix for x86 call instruction. */ unsigned int call_nop_as_suffix : 1; diff --git a/ld/ChangeLog b/ld/ChangeLog index 1dfe830421..d3172dcb0a 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,26 @@ +2016-03-15 H.J. Lu + + PR ld/19807 + * Makefile.am (ELF_X86_DEPS): Add + $(srcdir)/emulparams/reloc_overflow.sh. + * Makefile.in: Regenerated. + * NEWS: Mention -z noreloc-overflow. + * ld.texinfo: Document -z noreloc-overflow. + * emulparams/elf32_x86_64.sh: Source + ${srcdir}/emulparams/reloc_overflow.sh. + * emulparams/elf_x86_64.sh: Likewise. + * emulparams/reloc_overflow.sh: New file. + * testsuite/ld-x86-64/pr19807-1.s: New file. + * testsuite/ld-x86-64/pr19807-1a.d: Likewise. + * testsuite/ld-x86-64/pr19807-1b.d: Likewise. + * testsuite/ld-x86-64/pr19807-2.s: Likewise. + * testsuite/ld-x86-64/pr19807-2a.d: Likewise. + * testsuite/ld-x86-64/pr19807-2b.d: Likewise. + * testsuite/ld-x86-64/pr19807-2c.d: Likewise. + * testsuite/ld-x86-64/pr19807-2d.d: Likewise. + * testsuite/ld-x86-64/pr19807-2e.d: Likewise. + * testsuite/ld-x86-64/x86-64.exp: Run PR ld/19807 tests. + 2016-03-13 H.J. Lu PR ld/19539 diff --git a/ld/Makefile.am b/ld/Makefile.am index 4a8c0b6e87..d14e769b14 100644 --- a/ld/Makefile.am +++ b/ld/Makefile.am @@ -672,6 +672,7 @@ ELF_GEN_DEPS = $(srcdir)/emultempl/generic.em $(srcdir)/emultempl/elf-generic.em ELF_X86_DEPS = $(ELF_DEPS) $(srcdir)/emulparams/plt_unwind.sh \ $(srcdir)/emulparams/extern_protected_data.sh \ $(srcdir)/emulparams/dynamic_undefined_weak.sh \ + $(srcdir)/emulparams/reloc_overflow.sh \ $(srcdir)/emulparams/call_nop.sh @TDIRS@ diff --git a/ld/Makefile.in b/ld/Makefile.in index 45388d7bac..8c692282db 100644 --- a/ld/Makefile.in +++ b/ld/Makefile.in @@ -888,6 +888,7 @@ ELF_GEN_DEPS = $(srcdir)/emultempl/generic.em $(srcdir)/emultempl/elf-generic.em ELF_X86_DEPS = $(ELF_DEPS) $(srcdir)/emulparams/plt_unwind.sh \ $(srcdir)/emulparams/extern_protected_data.sh \ $(srcdir)/emulparams/dynamic_undefined_weak.sh \ + $(srcdir)/emulparams/reloc_overflow.sh \ $(srcdir)/emulparams/call_nop.sh diff --git a/ld/NEWS b/ld/NEWS index 4bf8091e52..b88da5cbb0 100644 --- a/ld/NEWS +++ b/ld/NEWS @@ -1,5 +1,8 @@ -*- text -*- +* Support for -z noreloc-overflow in the x86-64 ELF linker to disable + relocation overflow check. + * Add -z common/-z nocommon options for ELF targets to control whether to convert common symbols to the STT_COMMON type during a relocatable link. diff --git a/ld/emulparams/elf32_x86_64.sh b/ld/emulparams/elf32_x86_64.sh index 1b285c559a..967c1b45cd 100644 --- a/ld/emulparams/elf32_x86_64.sh +++ b/ld/emulparams/elf32_x86_64.sh @@ -1,6 +1,7 @@ . ${srcdir}/emulparams/plt_unwind.sh . ${srcdir}/emulparams/extern_protected_data.sh . ${srcdir}/emulparams/dynamic_undefined_weak.sh +. ${srcdir}/emulparams/reloc_overflow.sh . ${srcdir}/emulparams/call_nop.sh SCRIPT_NAME=elf ELFSIZE=32 diff --git a/ld/emulparams/elf_x86_64.sh b/ld/emulparams/elf_x86_64.sh index 0159a6ca44..e935f90d7e 100644 --- a/ld/emulparams/elf_x86_64.sh +++ b/ld/emulparams/elf_x86_64.sh @@ -1,6 +1,7 @@ . ${srcdir}/emulparams/plt_unwind.sh . ${srcdir}/emulparams/extern_protected_data.sh . ${srcdir}/emulparams/dynamic_undefined_weak.sh +. ${srcdir}/emulparams/reloc_overflow.sh . ${srcdir}/emulparams/call_nop.sh SCRIPT_NAME=elf ELFSIZE=64 diff --git a/ld/emulparams/reloc_overflow.sh b/ld/emulparams/reloc_overflow.sh new file mode 100644 index 0000000000..7ba0ee50d8 --- /dev/null +++ b/ld/emulparams/reloc_overflow.sh @@ -0,0 +1,11 @@ +PARSE_AND_LIST_OPTIONS_RELOC_OVERFLOW=' + fprintf (file, _("\ + -z noreloc-overflow Disable relocation overflow check\n")); +' +PARSE_AND_LIST_ARGS_CASE_Z_RELOC_OVERFLOW=' + else if (strcmp (optarg, "noreloc-overflow") == 0) + link_info.no_reloc_overflow_check = TRUE; +' + +PARSE_AND_LIST_OPTIONS="$PARSE_AND_LIST_OPTIONS $PARSE_AND_LIST_OPTIONS_RELOC_OVERFLOW" +PARSE_AND_LIST_ARGS_CASE_Z="$PARSE_AND_LIST_ARGS_CASE_Z $PARSE_AND_LIST_ARGS_CASE_Z_RELOC_OVERFLOW" diff --git a/ld/ld.texinfo b/ld/ld.texinfo index b2b99ab660..d3d8dc608a 100644 --- a/ld/ld.texinfo +++ b/ld/ld.texinfo @@ -1213,6 +1213,11 @@ This option overrides linker backend default. It can be used to avoid dynamic relocations against undefined weak symbols in executable. Supported for i386 and x86-64. +@item noreloc-overflow +Disable relocation overflow check. This can be used to disable +relocation overflow check if there will be no dynamic relocation +overflow at run-time. Supported for x86_64. + @item call-nop=prefix-addr @itemx call-nop=prefix-nop @itemx call-nop=suffix-nop diff --git a/ld/testsuite/ld-x86-64/pr19807-1.s b/ld/testsuite/ld-x86-64/pr19807-1.s new file mode 100644 index 0000000000..0870f6ade0 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19807-1.s @@ -0,0 +1,8 @@ + .globl _start + .type _start, @function +_start: + movq $foo, %rax + .size _start, .-_start + .data +foo: + .quad 0 diff --git a/ld/testsuite/ld-x86-64/pr19807-1a.d b/ld/testsuite/ld-x86-64/pr19807-1a.d new file mode 100644 index 0000000000..f3c5390b28 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19807-1a.d @@ -0,0 +1,13 @@ +#source: pr19807-1.s +#as: --64 +#ld: -pie -melf_x86_64 -z noreloc-overflow +#objdump: -dw + +.*: +file format .* + + +Disassembly of section .text: + +[a-f0-9]+ <_start>: +[ ]*[a-f0-9]+: 48 c7 c0 ([0-9a-f]{2} ){4} mov \$0x[a-f0-9]+,%rax +#pass diff --git a/ld/testsuite/ld-x86-64/pr19807-1b.d b/ld/testsuite/ld-x86-64/pr19807-1b.d new file mode 100644 index 0000000000..6af4985463 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19807-1b.d @@ -0,0 +1,13 @@ +#source: pr19807-1.s +#as: --x32 +#ld: -pie -melf32_x86_64 -z noreloc-overflow +#objdump: -dw + +.*: +file format .* + + +Disassembly of section .text: + +[a-f0-9]+ <_start>: +[ ]*[a-f0-9]+: 48 c7 c0 ([0-9a-f]{2} ){4} mov \$0x[a-f0-9]+,%rax +#pass diff --git a/ld/testsuite/ld-x86-64/pr19807-2.s b/ld/testsuite/ld-x86-64/pr19807-2.s new file mode 100644 index 0000000000..2b309f2411 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19807-2.s @@ -0,0 +1,8 @@ + .globl _start + .type _start, @function +_start: + movl $foo, %eax + .size _start, .-_start + .data +foo: + .quad 0 diff --git a/ld/testsuite/ld-x86-64/pr19807-2a.d b/ld/testsuite/ld-x86-64/pr19807-2a.d new file mode 100644 index 0000000000..1357d72f4c --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19807-2a.d @@ -0,0 +1,4 @@ +#source: pr19807-2.s +#as: --64 +#ld: -pie -melf_x86_64 +#error: .*relocation R_X86_64_32 against `.data' can not be used when making a shared object; recompile with -fPIC diff --git a/ld/testsuite/ld-x86-64/pr19807-2b.d b/ld/testsuite/ld-x86-64/pr19807-2b.d new file mode 100644 index 0000000000..a781b30e8f --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19807-2b.d @@ -0,0 +1,8 @@ +#source: pr19807-2.s +#as: --x32 +#ld: -pie -melf32_x86_64 +#readelf: -r --wide + +Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries: + Offset Info Type Sym. Value Symbol's Name \+ Addend +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_RELATIVE +[0-9a-f]+ diff --git a/ld/testsuite/ld-x86-64/pr19807-2c.d b/ld/testsuite/ld-x86-64/pr19807-2c.d new file mode 100644 index 0000000000..83ac641624 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19807-2c.d @@ -0,0 +1,13 @@ +#source: pr19807-2.s +#as: --x32 +#ld: -pie -melf32_x86_64 +#objdump: -dw + +.*: +file format .* + + +Disassembly of section .text: + +[a-f0-9]+ <_start>: +[ ]*[a-f0-9]+: b8 ([0-9a-f]{2} ){4} mov \$0x[a-f0-9]+,%eax +#pass diff --git a/ld/testsuite/ld-x86-64/pr19807-2d.d b/ld/testsuite/ld-x86-64/pr19807-2d.d new file mode 100644 index 0000000000..117128328d --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19807-2d.d @@ -0,0 +1,8 @@ +#source: pr19807-2.s +#as: --64 +#ld: -pie -melf_x86_64 -z noreloc-overflow +#readelf: -r --wide + +Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries: + Offset Info Type Symbol's Value Symbol's Name \+ Addend +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_RELATIVE +[0-9a-f]+ diff --git a/ld/testsuite/ld-x86-64/pr19807-2e.d b/ld/testsuite/ld-x86-64/pr19807-2e.d new file mode 100644 index 0000000000..f26616a20a --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19807-2e.d @@ -0,0 +1,13 @@ +#source: pr19807-2.s +#as: --64 +#ld: -pie -melf_x86_64 -z noreloc-overflow +#objdump: -dw + +.*: +file format .* + + +Disassembly of section .text: + +[a-f0-9]+ <_start>: +[ ]*[a-f0-9]+: b8 ([0-9a-f]{2} ){4} mov \$0x[a-f0-9]+,%eax +#pass diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index 49f9fa3c2c..8f297610ac 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -247,6 +247,13 @@ run_dump_test "largecomm-1e" run_dump_test "largecomm-1f" run_dump_test "pr19539a" run_dump_test "pr19539b" +run_dump_test "pr19807-1a" +run_dump_test "pr19807-1b" +run_dump_test "pr19807-2a" +run_dump_test "pr19807-2b" +run_dump_test "pr19807-2c" +run_dump_test "pr19807-2d" +run_dump_test "pr19807-2e" if { ![istarget "x86_64-*-linux*"] && ![istarget "x86_64-*-nacl*"]} { return -- 2.34.1