Commit Graph

5 Commits

Author SHA1 Message Date
H.J. Lu
cbd0eecf26 Always define referenced __start_SECNAME/__stop_SECNAME
Currently, linker will define __start_SECNAME and __stop_SECNAME symbols
only for orphaned sections.

However, during garbage collection, ELF linker marks all sections with
references to __start_SECNAME and __stop_SECNAME symbols as used even
when section SECNAME isn't an orphaned section and linker won't define
__start_SECNAME nor __stop_SECNAME.  And ELF linker stores the first
input section whose name matches __start_SECNAME or __stop_SECNAME in
u.undef.section for garbage collection.  If these symbols are provided
in linker script, u.undef.section is set to the section where they will
defined by linker script, which leads to the incorrect output.

This patch changes linker to always define referenced __start_SECNAME and
__stop_SECNAME if the input section name is the same as the output section
name, which is always true for orphaned sections, and SECNAME is a C
identifier.  Also __start_SECNAME and __stop_SECNAME symbols are marked
as hidden by ELF linker so that __start_SECNAME and __stop_SECNAME symbols
for section SECNAME in different modules are unique.  For garbage
collection, ELF linker stores the first matched input section in the
unused vtable field.

bfd/

	PR ld/20022
	PR ld/21557
	PR ld/21562
	PR ld/21571
	* elf-bfd.h (elf_link_hash_entry): Add start_stop.  Change the
	vtable field to a union.
	(_bfd_elf_is_start_stop): Removed.
	* elf32-i386.c (elf_i386_convert_load_reloc): Also check for
	__start_SECNAME and __stop_SECNAME symbols.
	* elf64-x86-64.c (elf_x86_64_convert_load_reloc): Likewise.
	* elflink.c (_bfd_elf_is_start_stop): Removed.
	(_bfd_elf_gc_mark_rsec): Check start_stop instead of calling
	_bfd_elf_is_start_stop.
	(elf_gc_propagate_vtable_entries_used): Skip __start_SECNAME and
	__stop_SECNAME symbols.  Updated.
	(elf_gc_smash_unused_vtentry_relocs): Likewise.
	(bfd_elf_gc_record_vtinherit): Likewise.
	(bfd_elf_gc_record_vtentry): Likewise.

ld/

	PR ld/20022
	PR ld/21557
	PR ld/21562
	PR ld/21571
	* ld.texinfo: Update __start_SECNAME/__stop_SECNAME symbols.
	* ldlang.c (lang_insert_orphan): Move handling of __start_SECNAME
	and __stop_SECNAME symbols to ...
	(lang_set_startof): Here.  Also define __start_SECNAME and
	__stop_SECNAME for -Ur.
	* emultempl/elf32.em (gld${EMULATION_NAME}_after_open): Mark
	referenced __start_SECNAME and __stop_SECNAME symbols as hidden
	and set start_stop for garbage collection.
	* testsuite/ld-elf/pr21562a.d: New file.
	* testsuite/ld-elf/pr21562a.s: Likewise.
	* testsuite/ld-elf/pr21562a.t: Likewise.
	* testsuite/ld-elf/pr21562b.d: Likewise.
	* testsuite/ld-elf/pr21562b.s: Likewise.
	* testsuite/ld-elf/pr21562b.t: Likewise.
	* testsuite/ld-elf/pr21562c.d: Likewise.
	* testsuite/ld-elf/pr21562c.t: Likewise.
	* testsuite/ld-elf/pr21562d.d: Likewise.
	* testsuite/ld-elf/pr21562d.t: Likewise.
	* testsuite/ld-elf/pr21562e.d: Likewise.
	* testsuite/ld-elf/pr21562f.d: Likewise.
	* testsuite/ld-elf/pr21562g.d: Likewise.
	* testsuite/ld-elf/pr21562h.d: Likewise.
	* testsuite/ld-elf/pr21562i.d: Likewise.
	* testsuite/ld-elf/pr21562j.d: Likewise.
	* testsuite/ld-elf/pr21562k.d: Likewise.
	* testsuite/ld-elf/pr21562l.d: Likewise.
	* testsuite/ld-elf/pr21562m.d: Likewise.
	* testsuite/ld-elf/pr21562n.d: Likewise.
	* testsuite/ld-gc/pr20022.d: Likewise.
	* testsuite/ld-gc/pr20022a.s: Likewise.
	* testsuite/ld-gc/pr20022b.s: Likewise.
	* testsuite/ld-gc/gc.exp: Run PR ld/20022 tests.
	* testsuite/ld-gc/pr19161.d: Also accept local __start_SECNAME
	symbol.
	* testsuite/ld-gc/start.d: Likewise.
	* testsuite/ld-x86-64/lea1a.d: Updated.
	* testsuite/ld-x86-64/lea1b.d: Updated.
	* testsuite/ld-x86-64/lea1d.d: Updated.
	* testsuite/ld-x86-64/lea1e.d: Likewise.
2017-06-13 08:53:22 -07:00
H.J. Lu
bae420ef26 Optimize x86 GOT32X/GOTPCRELX relocations
R_386_GOT32X, R_X86_64_GOTPCRELX and R_X86_64_REX_GOTPCRELX relocations
retrieve the symbol address via its GOT slot.  If the symbol address is
known at the link-time, we can use it directly by changing instruction
encoding.  Indirect branch can only be converted to PC relative direct
branch.  MOV can be changed to LEA or encoded differently with signed
address.  The subset of binary operations can be encoded only with
signed address.

If undefined weak symbol is resolved to zero link-time, we can use it
as address.  Zero addresss can't used with PC relative direct branch
when PIC is true since the current PC is unknown.  In 64-bit, 32-bit
relocation for PC relatiave direct branch to zero may also overflow.

If this optimization causes relocation overflow, --no-relax can be used
to work around it.

bfd/

	PR ld/19609
	* elf32-i386.c (elf_i386_convert_load): Convert to R_386_32 for
	load with locally bound symbols if PIC is false or there is no
	base register.  Optimize branch to 0 if PIC is false.
	(elf_i386_relocate_section): Don't generate dynamic relocations
	against undefined weak symbols if PIC is false.
	* elf64-x86-64.c (elf_x86_64_convert_load): Disable optimization
	if we can't estimate relocation overflow with --no-relax.
	Convert to R_X86_64_32S/R_X86_64_32 for load with locally bound
	symbols if PIC is false.  Optimize branch to 0 if PIC is false.
	(elf_x86_64_relocate_section): Don't generate dynamic relocations
	against undefined weak symbols if PIC is false.

ld/

	PR ld/19609
	* testsuite/ld-i386/got1.dd: Updated.
	* testsuite/ld-i386/lea1c.d: Likewise.
	* testsuite/ld-i386/load1-nacl.d: Likewise.
	* testsuite/ld-i386/load1.d: Likewise.
	* testsuite/ld-i386/load4b.d: Likewise.
	* testsuite/ld-i386/load5b.d: Likewise.
	* testsuite/ld-i386/mov1b.d: Likewise.
	* testsuite/ld-x86-64/mov1b.d: Likewise.
	* testsuite/ld-x86-64/mov1d.d: Likewise.
	* testsuite/ld-ifunc/ifunc-21-i386.d: Likewise.
	* testsuite/ld-ifunc/ifunc-21-x86-64.d: Likewise.
	* testsuite/ld-ifunc/ifunc-22-i386.d: Likewise.
	* testsuite/ld-ifunc/ifunc-22-x86-64.d: Likewise.
	* testsuite/ld-x86-64/gotpcrel1.dd: Likewise.
	* testsuite/ld-x86-64/lea1a.d: Likewise.
	* testsuite/ld-x86-64/lea1b.d: Likewise.
	* testsuite/ld-x86-64/lea1c.d: Likewise.
	* testsuite/ld-x86-64/lea1d.d: Likewise.
	* testsuite/ld-x86-64/lea1e.d: Likewise.
	* testsuite/ld-x86-64/lea1f.d: Likewise.
	* testsuite/ld-x86-64/mov1b.d: Likewise.
	* testsuite/ld-x86-64/mov1d.d: Likewise.
	* testsuite/ld-x86-64/pr13082-3b.d: Likewise.
	* testsuite/ld-x86-64/pr13082-4b.d: Likewise.
	* testsuite/ld-x86-64/lea1.s: Add tests for 32-bit registers.
	* testsuite/ld-i386/pr19609-1.s: New file.
	* testsuite/ld-i386/pr19609-1a.d: Likewise.
	* testsuite/ld-i386/pr19609-1b.d: Likewise.
	* testsuite/ld-i386/pr19609-1c.d: Likewise.
	* testsuite/ld-i386/pr19609-1d.d: Likewise.
	* testsuite/ld-i386/pr19609-1e.d: Likewise.
	* testsuite/ld-i386/pr19609-1f.d: Likewise.
	* testsuite/ld-i386/pr19609-1g.d: Likewise.
	* testsuite/ld-i386/pr19609-1h.d: Likewise.
	* testsuite/ld-i386/pr19609-1i.d: Likewise.
	* testsuite/ld-i386/pr19609-2.s: Likewise.
	* testsuite/ld-i386/pr19609-2a.d: Likewise.
	* testsuite/ld-i386/pr19609-2b.d: Likewise.
	* testsuite/ld-i386/pr19609-2c.d: Likewise.
	* testsuite/ld-i386/undefweak.s: Likewise.
	* testsuite/ld-i386/undefweaka.d: Likewise.
	* testsuite/ld-i386/undefweakb.d: Likewise.
	* testsuite/ld-x86-64/pr13082-3c.d: Likewise.
	* testsuite/ld-x86-64/pr13082-3d.d: Likewise.
	* testsuite/ld-x86-64/pr19609-1.s: Likewise.
	* testsuite/ld-x86-64/pr19609-1a.d: Likewise.
	* testsuite/ld-x86-64/pr19609-1b.d: Likewise.
	* testsuite/ld-x86-64/pr19609-1c.d: Likewise.
	* testsuite/ld-x86-64/pr19609-1d.d: Likewise.
	* testsuite/ld-x86-64/pr19609-1e.d: Likewise.
	* testsuite/ld-x86-64/pr19609-1f.d: Likewise.
	* testsuite/ld-x86-64/pr19609-1g.d: Likewise.
	* testsuite/ld-x86-64/pr19609-1h.d: Likewise.
	* testsuite/ld-x86-64/pr19609-1i.d: Likewise.
	* testsuite/ld-x86-64/pr19609-1j.d: Likewise.
	* testsuite/ld-x86-64/pr19609-1k.d: Likewise.
	* testsuite/ld-x86-64/pr19609-1l.d: Likewise.
	* testsuite/ld-x86-64/pr19609-1m.d: Likewise.
	* testsuite/ld-x86-64/pr19609-2.s: Likewise.
	* testsuite/ld-x86-64/pr19609-2a.d: Likewise.
	* testsuite/ld-x86-64/pr19609-2b.d: Likewise.
	* testsuite/ld-x86-64/pr19609-2c.d: Likewise.
	* testsuite/ld-x86-64/pr19609-2d.d: Likewise.
	* testsuite/ld-x86-64/pr19609-3.s: Likewise.
	* testsuite/ld-x86-64/pr19609-3a.d: Likewise.
	* testsuite/ld-x86-64/pr19609-3b.d: Likewise.
	* testsuite/ld-x86-64/pr19609-4.s: Likewise.
	* testsuite/ld-x86-64/pr19609-4a.d: Likewise.
	* testsuite/ld-x86-64/pr19609-4b.d: Likewise.
	* testsuite/ld-x86-64/pr19609-4c.d: Likewise.
	* testsuite/ld-x86-64/pr19609-4d.d: Likewise.
	* testsuite/ld-x86-64/pr19609-4e.d: Likewise.
	* testsuite/ld-x86-64/pr19609-5.s: Likewise.
	* testsuite/ld-x86-64/pr19609-5a.d: Likewise.
	* testsuite/ld-x86-64/pr19609-5b.d: Likewise.
	* testsuite/ld-x86-64/pr19609-5c.d: Likewise.
	* testsuite/ld-x86-64/pr19609-5d.d: Likewise.
	* testsuite/ld-x86-64/pr19609-5e.d: Likewise.
	* testsuite/ld-x86-64/pr19609-6.s: Likewise.
	* testsuite/ld-x86-64/pr19609-6a.d: Likewise.
	* testsuite/ld-x86-64/pr19609-6b.d: Likewise.
	* testsuite/ld-x86-64/pr19609-6c.d: Likewise.
	* testsuite/ld-x86-64/pr19609-6d.d: Likewise.
	* testsuite/ld-x86-64/pr19609-7.s: Likewise.
	* testsuite/ld-x86-64/pr19609-7a.d: Likewise.
	* testsuite/ld-x86-64/pr19609-7b.d: Likewise.
	* testsuite/ld-x86-64/pr19609-7c.d: Likewise.
	* testsuite/ld-x86-64/pr19609-7d.d: Likewise.
	* testsuite/ld-i386/i386.exp: Run undefweak tests and tests for
	PR ld/19609.
	* testsuite/ld-x86-64/x86-64.exp: Run pr13082-3c, pr13082-3d
	and tests for PR ld/19609.
2016-02-26 09:39:24 -08:00
H.J. Lu
a6af384b19 Properly convert address load of __start_XXX/__stop_XXX
Since __start_XXX and __stop_XXX symbols aren't defined when address
load is being converted, we need to check if there is an XXX output
section to get their section and value.  This patch adds a new function,
bfd_link_get_defined_symbol, to search for the XXX output section to
check if __start_XXX and __stop_XXX symbols are defined.

bfd/

	PR ld/19171
	* elf32-i386.c (elf_i386_convert_load): Call
	bfd_link_get_defined_symbol to check if a symbol is defined.
	* elf64-x86-64.c (elf_x86_64_convert_load): Call
	bfd_link_get_defined_symbol to get defined symbol section and
	value.
	* linker.c (bfd_link_get_defined_symbol): New function.
	* bfd-in2.h: Regenerated.

ld/testsuite/

	PR ld/19171
	* ld-i386/lea1.s: Add tests for address load of __start_XXX
	and __stop_XXX.
	* ld-i386/mov1.s: Likewise.
	* ld-x86-64/lea1.s: Likewise.
	* ld-x86-64/mov1.s: Likewise.
	* ld-i386/lea1a.d: Updated.
	* ld-i386/lea1b.d: Likewise.
	* ld-i386/lea1c.d: Likewise.
	* ld-i386/mov1a.d: Likewise.
	* ld-i386/mov1b.d: 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.
	* ld-x86-64/mov1a.d: Likewise.
	* ld-x86-64/mov1b.d: Likewise.
	* ld-x86-64/mov1c.d: Likewise.
	* ld-x86-64/mov1d.d: Likewise.
2015-10-26 08:11:55 -07:00
H.J. Lu
b31bcacc48 Convert mov to lea for loading address of local common symbol
There is no need to check def_regular when converting mov to lea for
loading address of local symbols since def_regular may be false for
common symbols and SYMBOL_REFERENCES_LOCAL is sufficient.

bfd/

	* elf32-i386.c (elf_i386_convert_mov_to_lea): Don't check
	def_regular.
	* elf64-x86-64.c (elf_x86_64_convert_mov_to_lea): Likewise.

ld/testsuite/

	* ld-i386/lea1.s: Add a test for loading address of local common
	symbol.
	* ld-x86-64/lea1.s: Likewise.
	* ld-i386/lea1a.d: Updated.
	* ld-i386/lea1b.d: Likewise.
	* ld-i386/lea1c.d: 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.
2015-10-16 03:14:40 -07:00
H.J. Lu
80d873266d 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.
2012-08-31 04:26:17 +00:00