x86: Skip __[start|stop]_SECNAME for --gc-sections -z start-stop-gc

Don't convert memory load to immediate load on __start_SECNAME and
__stop_SECNAME for --gc-sections -z start-stop-gc if all SECNAME
sections been garbage collected.

bfd/

	PR ld/27491
	* elf32-i386.c (elf_i386_convert_load_reloc): Skip __start_SECNAME
	and __stop_SECNAME for --gc-sections -z start-stop-gc if the input
	section been garbage collected.
	* elf64-x86-64.c (elf_x86_64_convert_load_reloc): Likewise.
	* elfxx-x86.h (elf_x86_start_stop_gc_p): New function.

ld/
	PR ld/27491
	* testsuite/ld-i386/i386.exp: Run PR ld/27491 tests.
	* testsuite/ld-x86-64/x86-64.exp: Likewise.
	* testsuite/ld-i386/pr27491-1.s: New file.
	* testsuite/ld-i386/pr27491-1a.d: Likewise.
	* testsuite/ld-i386/pr27491-1b.d: Likewise.
	* testsuite/ld-i386/pr27491-1c.d: Likewise.
	* testsuite/ld-i386/pr27491-2.d: Likewise.
	* testsuite/ld-i386/pr27491-2.s: Likewise.
	* testsuite/ld-i386/pr27491-3.d: Likewise.
	* testsuite/ld-i386/pr27491-3.s: Likewise.
	* testsuite/ld-i386/pr27491-4.d: Likewise.
	* testsuite/ld-i386/pr27491-4a.s: Likewise.
	* testsuite/ld-i386/pr27491-4b.s: Likewise.
	* testsuite/ld-x86-64/pr27491-1.s: Likewise.
	* testsuite/ld-x86-64/pr27491-1a.d: Likewise.
	* testsuite/ld-x86-64/pr27491-1b.d: Likewise.
	* testsuite/ld-x86-64/pr27491-1c.d: Likewise.
	* testsuite/ld-x86-64/pr27491-2.d: Likewise.
	* testsuite/ld-x86-64/pr27491-2.s: Likewise.
	* testsuite/ld-x86-64/pr27491-3.d: Likewise.
	* testsuite/ld-x86-64/pr27491-3.s: Likewise.
	* testsuite/ld-x86-64/pr27491-4.d: Likewise.
	* testsuite/ld-x86-64/pr27491-4a.s: Likewise.
	* testsuite/ld-x86-64/pr27491-4b.s: Likewise.
This commit is contained in:
H.J. Lu 2021-12-01 04:55:24 -08:00
parent c808def421
commit 794f2bba0f
27 changed files with 391 additions and 0 deletions

View file

@ -1393,6 +1393,11 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
|| h->root.type == bfd_link_hash_defweak)
&& local_ref))
{
/* Skip __start_SECNAME/__stop_SECNAME when --gc-sections
-z start-stop-gc are used. */
if (elf_x86_start_stop_gc_p (link_info, h))
return true;
convert_load:
if (opcode == 0x8b)
{

View file

@ -1643,6 +1643,11 @@ elf_x86_64_convert_load_reloc (bfd *abfd,
|| h->root.type == bfd_link_hash_defweak)
&& h->root.u.def.section == bfd_und_section_ptr))))
{
/* Skip __start_SECNAME/__stop_SECNAME when --gc-sections
-z start-stop-gc are used. */
if (elf_x86_start_stop_gc_p (link_info, h))
return true;
/* Skip since R_X86_64_32/R_X86_64_32S may overflow. */
if (no_overflow)
return true;

View file

@ -731,3 +731,36 @@ extern void _bfd_x86_elf_link_report_relative_reloc
_bfd_x86_elf_merge_gnu_properties
#define elf_backend_fixup_gnu_properties \
_bfd_x86_elf_link_fixup_gnu_properties
/* Return true if H is a __start_SECNAME/__stop_SECNAME symbol for the
SECNAME section which has been garbage collected by --gc-sections
-z start-stop-gc. */
static inline bool
elf_x86_start_stop_gc_p (struct bfd_link_info *link_info,
struct elf_link_hash_entry *h)
{
if (h->start_stop
&& link_info->gc_sections
&& link_info->start_stop_gc)
{
asection *s = h->root.u.def.section;
do
{
/* Return false if any SECNAME section is kept. */
if (s->gc_mark)
return false;
s = bfd_get_next_section_by_name (s->owner, s);
}
while (s != NULL);
/* Return true only if all SECNAME sections have been garbage
collected. */
return true;
}
/* Return false if H isn't a __start_SECNAME/__stop_SECNAME symbol or
--gc-sections or -z start-stop-gc isn't used. */
return false;
}

View file

@ -493,6 +493,12 @@ run_dump_test "property-x86-isa3"
run_dump_test "property-x86-isa4"
run_dump_test "pr26869"
run_dump_test "code16"
run_dump_test "pr27491-1a"
run_dump_test "pr27491-1b"
run_dump_test "pr27491-1c"
run_dump_test "pr27491-2"
run_dump_test "pr27491-3"
run_dump_test "pr27491-4"
if { !([istarget "i?86-*-linux*"]
|| [istarget "i?86-*-gnu*"]

View file

@ -0,0 +1,14 @@
.weak __start_xx
.weak __stop_xx
.text
.global foo
foo:
movl __start_xx@got(%ebx), %eax
movl __stop_xx@got(%ebx), %eax
.section xx,"a",unique,0
.byte 0
.section xx,"a",unique,1
.byte 1

View file

@ -0,0 +1,14 @@
#source: pr27491-1.s
#as: --32
#ld: --gc-sections -melf_i386 -z start-stop-gc -shared
#objdump: -dw
.*: +file format elf32-i386
Disassembly of section .text:
[a-f0-9]+ <foo>:
+[a-f0-9]+: 8b 83 ([0-9a-f]{2} ){4}[ \t]+mov +-0x[a-f0-9]+\(%ebx\),%eax
+[a-f0-9]+: 8b 83 ([0-9a-f]{2} ){4}[ \t]+mov +-0x[a-f0-9]+\(%ebx\),%eax
#pass

View file

@ -0,0 +1,11 @@
#source: pr27491-1.s
#as: --32
#ld: --gc-sections -melf_i386 -z start-stop-gc -shared
#nm: -n
#failif
#...
[a-f0-9]+ R __start_xx
#...
[a-f0-9]+ R __stop_xx
#...

View file

@ -0,0 +1,14 @@
#source: pr27491-1.s
#as: --32
#ld: --gc-sections -melf_i386 -shared
#objdump: -dw
.*: +file format elf32-i386
Disassembly of section .text:
[a-f0-9]+ <foo>:
+[a-f0-9]+: 8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
+[a-f0-9]+: 8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
#pass

View file

@ -0,0 +1,22 @@
#as: --32
#ld: --gc-sections -melf_i386 -z start-stop-gc -shared
#objdump: --syms -dw
.*: +file format elf32-i386
SYMBOL TABLE:
#...
[a-f0-9]+ g xx [a-f0-9]+ \.protected __stop_xx
#...
[a-f0-9]+ g xx [a-f0-9]+ \.protected __start_xx
#...
Disassembly of section .text:
[a-f0-9]+ <foo>:
+[a-f0-9]+: 8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
+[a-f0-9]+: 8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
+[a-f0-9]+: 8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
#pass

View file

@ -0,0 +1,16 @@
.weak __start_xx
.weak __stop_xx
.text
.global foo
foo:
movl __start_xx@got(%ebx), %eax
movl __stop_xx@got(%ebx), %eax
leal bar1@got(%ebx), %eax
.section xx,"a",unique,0
bar1:
.byte 0
.section xx,"a",unique,1
.byte 1

View file

@ -0,0 +1,21 @@
#as: --32
#ld: --gc-sections -melf_i386 -z start-stop-gc -shared
#objdump: --syms -dw
.*: +file format elf32-i386
SYMBOL TABLE:
#...
[a-f0-9]+ g xx [a-f0-9]+ \.protected __stop_xx
#...
[a-f0-9]+ g xx [a-f0-9]+ \.protected __start_xx
#...
Disassembly of section .text:
[a-f0-9]+ <foo>:
+[a-f0-9]+: 8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
+[a-f0-9]+: 8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
#pass

View file

@ -0,0 +1,14 @@
.weak __start_xx
.weak __stop_xx
.text
.global foo
foo:
movl __start_xx@got(%ebx), %eax
movl __stop_xx@got(%ebx), %eax
.section xx,"a",unique,0
.byte 0
.section xx,"aR",unique,1
.byte 1

View file

@ -0,0 +1,23 @@
#source: pr27491-4a.s
#source: pr27491-4b.s
#as: --32
#ld: --gc-sections -melf_i386 -z start-stop-gc -shared
#objdump: --syms -dw
.*: +file format elf32-i386
SYMBOL TABLE:
#...
[a-f0-9]+ g xx [a-f0-9]+ \.protected __stop_xx
#...
[a-f0-9]+ g xx [a-f0-9]+ \.protected __start_xx
#...
Disassembly of section .text:
[a-f0-9]+ <foo>:
+[a-f0-9]+: 8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
+[a-f0-9]+: 8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
#pass

View file

@ -0,0 +1,11 @@
.weak __start_xx
.weak __stop_xx
.text
.global foo
foo:
movl __start_xx@got(%ebx), %eax
movl __stop_xx@got(%ebx), %eax
.section xx,"a",unique,0
.byte 0

View file

@ -0,0 +1,2 @@
.section xx,"aR",unique,1
.byte 1

View file

@ -0,0 +1,14 @@
.weak __start_xx
.weak __stop_xx
.text
.global foo
foo:
movq __start_xx@gotpcrel(%rip), %rax
movq __stop_xx@gotpcrel(%rip), %rax
.section xx,"a",unique,0
.byte 0
.section xx,"a",unique,1
.byte 1

View file

@ -0,0 +1,14 @@
#source: pr27491-1.s
#as: --64
#ld: --gc-sections -melf_x86_64 -z start-stop-gc -shared
#objdump: -dw
.*: +file format elf64-x86-64
Disassembly of section .text:
[a-f0-9]+ <foo>:
+[a-f0-9]+: 48 8b 05 ([0-9a-f]{2} ){4}[ \t]+mov +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <_DYNAMIC\+0x[a-f0-9]+>
+[a-f0-9]+: 48 8b 05 ([0-9a-f]{2} ){4}[ \t]+mov +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <_DYNAMIC\+0x[a-f0-9]+>
#pass

View file

@ -0,0 +1,11 @@
#source: pr27491-1.s
#as: --64
#ld: --gc-sections -melf_x86_64 -z start-stop-gc -shared
#nm: -n
#failif
#...
[a-f0-9]+ R __start_xx
#...
[a-f0-9]+ R __stop_xx
#...

View file

@ -0,0 +1,21 @@
#source: pr27491-1.s
#as: --64
#ld: --gc-sections -melf_x86_64 -shared
#objdump: --syms -dw
.*: +file format elf64-x86-64
SYMBOL TABLE:
#...
[a-f0-9]+ g xx [a-f0-9]+ \.protected __stop_xx
#...
[a-f0-9]+ g xx [a-f0-9]+ \.protected __start_xx
#...
Disassembly of section .text:
[a-f0-9]+ <foo>:
+[a-f0-9]+: 48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__start_xx>
+[a-f0-9]+: 48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__stop_xx>
#pass

View file

@ -0,0 +1,23 @@
#as: --64
#ld: --gc-sections -melf_x86_64 -z start-stop-gc -shared
#objdump: --syms -dw
.*: +file format elf64-x86-64
SYMBOL TABLE:
#...
[a-f0-9]+ g xx [a-f0-9]+ \.protected __stop_xx
#...
[a-f0-9]+ g xx [a-f0-9]+ \.protected __start_xx
#...
Disassembly of section .text:
[a-f0-9]+ <foo>:
+[a-f0-9]+: 48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__start_xx>
+[a-f0-9]+: 48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__stop_xx>
+[a-f0-9]+: 48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <bar1>
+[a-f0-9]+: 48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <bar2>
#pass

View file

@ -0,0 +1,20 @@
.weak __start_xx
.weak __stop_xx
.text
.global foo
foo:
movq __start_xx@gotpcrel(%rip), %rax
movq __stop_xx@gotpcrel(%rip), %rax
leaq bar1(%rip), %rax
leaq bar2(%rip), %rax
.section xx,"a",unique,0
.byte 0
bar1:
.byte 0
bar2:
.byte 0
.section xx,"a",unique,1
.byte 1

View file

@ -0,0 +1,21 @@
#as: --64
#ld: --gc-sections -melf_x86_64 -z start-stop-gc -shared
#objdump: --syms -dw
.*: +file format elf64-x86-64
SYMBOL TABLE:
#...
[a-f0-9]+ g xx [a-f0-9]+ \.protected __stop_xx
#...
[a-f0-9]+ g xx [a-f0-9]+ \.protected __start_xx
#...
Disassembly of section .text:
[a-f0-9]+ <foo>:
+[a-f0-9]+: 48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__start_xx>
+[a-f0-9]+: 48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__stop_xx>
#pass

View file

@ -0,0 +1,14 @@
.weak __start_xx
.weak __stop_xx
.text
.global foo
foo:
movq __start_xx@gotpcrel(%rip), %rax
movq __stop_xx@gotpcrel(%rip), %rax
.section xx,"a",unique,1
.byte 0
.section xx,"aR",unique,0
.byte 1

View file

@ -0,0 +1,23 @@
#source: pr27491-4a.s
#source: pr27491-4b.s
#as: --64
#ld: --gc-sections -melf_x86_64 -z start-stop-gc -shared
#objdump: --syms -dw
.*: +file format elf64-x86-64
SYMBOL TABLE:
#...
[a-f0-9]+ g xx [a-f0-9]+ \.protected __stop_xx
#...
[a-f0-9]+ g xx [a-f0-9]+ \.protected __start_xx
#...
Disassembly of section .text:
[a-f0-9]+ <foo>:
+[a-f0-9]+: 48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__start_xx>
+[a-f0-9]+: 48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__stop_xx>
#pass

View file

@ -0,0 +1,11 @@
.weak __start_xx
.weak __stop_xx
.text
.global foo
foo:
movq __start_xx@gotpcrel(%rip), %rax
movq __stop_xx@gotpcrel(%rip), %rax
.section xx,"a",unique,1
.byte 0

View file

@ -0,0 +1,2 @@
.section xx,"aR",unique,0
.byte 1

View file

@ -480,6 +480,12 @@ run_dump_test "property-x86-isa3-x32"
run_dump_test "property-x86-isa4"
run_dump_test "property-x86-isa4-x32"
run_dump_test "code16"
run_dump_test "pr27491-1a"
run_dump_test "pr27491-1b"
run_dump_test "pr27491-1c"
run_dump_test "pr27491-2"
run_dump_test "pr27491-3"
run_dump_test "pr27491-4"
if ![istarget "x86_64-*-linux*"] {
return