Check symbol defined by assignment in linker script

Symbol symbol defined by an assignment in a linker script has type
bfd_link_hash_new.  elf_i386_convert_load and elf_x86_64_convert_load
should check bfd_link_hash_new to see if a symbol is defined by a linker
script.

bfd/

	PR ld/19175
	* elf32-i386.c (elf_i386_convert_load): Check bfd_link_hash_new
	instead of calling bfd_link_get_defined_symbol.
	* elf64-x86-64.c (elf_x86_64_convert_load): Likewise.  Skip
	relocation overflow for bfd_link_hash_new.
	* linker.c (bfd_link_get_defined_symbol): Removed.
	* bfd-in2.h: Regenerated.

ld/testsuite/

	PR ld/19175
	* ld-i386/i386.exp: Run pr19175.
	* ld-x86-64/x86-64.exp: Likewise.
	* ld-i386/pr19175.d: New file.
	* ld-i386/pr19175.s: Likewise.
	* ld-i386/pr19175.t: Likewise.
	* ld-x86-64/pr19175.d: Likewise.
	* ld-x86-64/pr19175.s: Likewise.
	* ld-x86-64/pr19175.t: Likewise.
This commit is contained in:
H.J. Lu
2015-10-26 16:32:34 -07:00
parent 0fde2c536b
commit 7b7e7f1da2
14 changed files with 102 additions and 102 deletions

View File

@@ -1,3 +1,13 @@
2015-10-26 H.J. Lu <hongjiu.lu@intel.com>
PR ld/19175
* elf32-i386.c (elf_i386_convert_load): Check bfd_link_hash_new
instead of calling bfd_link_get_defined_symbol.
* elf64-x86-64.c (elf_x86_64_convert_load): Likewise. Skip
relocation overflow for bfd_link_hash_new.
* linker.c (bfd_link_get_defined_symbol): Removed.
* bfd-in2.h: Regenerated.
2015-10-26 H.J. Lu <hongjiu.lu@intel.com> 2015-10-26 H.J. Lu <hongjiu.lu@intel.com>
PR ld/19171 PR ld/19171

View File

@@ -7515,10 +7515,6 @@ struct bfd_elf_version_tree * bfd_find_version_for_sym
bfd_boolean bfd_hide_sym_by_version bfd_boolean bfd_hide_sym_by_version
(struct bfd_elf_version_tree *verdefs, const char *sym_name); (struct bfd_elf_version_tree *verdefs, const char *sym_name);
bfd_boolean bfd_link_get_defined_symbol
(struct bfd_link_info *info, struct bfd_link_hash_entry *h,
asection **sec, bfd_vma *value);
/* Extracted from simple.c. */ /* Extracted from simple.c. */
bfd_byte *bfd_simple_get_relocated_section_contents bfd_byte *bfd_simple_get_relocated_section_contents
(bfd *abfd, asection *sec, bfd_byte *outbuf, asymbol **symbol_table); (bfd *abfd, asection *sec, bfd_byte *outbuf, asymbol **symbol_table);

View File

@@ -2976,8 +2976,11 @@ convert_branch:
if (h == htab->elf.hdynamic) if (h == htab->elf.hdynamic)
continue; continue;
if (bfd_link_get_defined_symbol (link_info, &h->root, NULL, /* bfd_link_hash_new is set by an assignment in a linker
NULL) script in bfd_elf_record_link_assignment. */
if ((h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak
|| h->root.type == bfd_link_hash_new)
&& SYMBOL_REFERENCES_LOCAL (link_info, h)) && SYMBOL_REFERENCES_LOCAL (link_info, h))
{ {
convert_load: convert_load:

View File

@@ -3116,8 +3116,6 @@ elf_x86_64_convert_load (bfd *abfd, asection *sec,
} }
else else
{ {
bfd_boolean defined;
indx = r_symndx - symtab_hdr->sh_info; indx = r_symndx - symtab_hdr->sh_info;
h = elf_sym_hashes (abfd)[indx]; h = elf_sym_hashes (abfd)[indx];
BFD_ASSERT (h != NULL); BFD_ASSERT (h != NULL);
@@ -3126,17 +3124,26 @@ elf_x86_64_convert_load (bfd *abfd, asection *sec,
|| h->root.type == bfd_link_hash_warning) || h->root.type == bfd_link_hash_warning)
h = (struct elf_link_hash_entry *) h->root.u.i.link; h = (struct elf_link_hash_entry *) h->root.u.i.link;
defined = bfd_link_get_defined_symbol (link_info, &h->root,
&tsec, &toff);
/* STT_GNU_IFUNC must keep GOTPCREL relocations. We also /* STT_GNU_IFUNC must keep GOTPCREL relocations. We also
avoid optimizing GOTPCREL relocations againt _DYNAMIC avoid optimizing GOTPCREL relocations againt _DYNAMIC
since ld.so may use its link-time address. */ since ld.so may use its link-time address. */
if (defined if ((h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak
|| h->root.type == bfd_link_hash_new)
&& h->type != STT_GNU_IFUNC && h->type != STT_GNU_IFUNC
&& h != htab->elf.hdynamic && h != htab->elf.hdynamic
&& SYMBOL_REFERENCES_LOCAL (link_info, h)) && SYMBOL_REFERENCES_LOCAL (link_info, h))
{
/* bfd_link_hash_new is set by an assignment in a linker
script in bfd_elf_record_link_assignment. FIXME: If
we ever get a linker error due relocation overflow, we
will skip this optimization. */
if (h->root.type == bfd_link_hash_new)
goto convert;
tsec = h->root.u.def.section;
toff = h->root.u.def.value;
symtype = h->type; symtype = h->type;
}
else else
continue; continue;
} }
@@ -3213,6 +3220,7 @@ elf_x86_64_convert_load (bfd *abfd, asection *sec,
continue; continue;
} }
convert:
if (opcode == 0xff) if (opcode == 0xff)
{ {
/* We have "call/jmp *foo@GOTPCREL(%rip)". */ /* We have "call/jmp *foo@GOTPCREL(%rip)". */

View File

@@ -3303,92 +3303,3 @@ bfd_hide_sym_by_version (struct bfd_elf_version_tree *verdefs,
bfd_find_version_for_sym (verdefs, sym_name, &hidden); bfd_find_version_for_sym (verdefs, sym_name, &hidden);
return hidden; return hidden;
} }
/*
FUNCTION
bfd_link_get_defined_symbol
SYNOPSIS
bfd_boolean bfd_link_get_defined_symbol
(struct bfd_link_info *info, struct bfd_link_hash_entry *h,
asection **sec, bfd_vma *value);
DESCRIPTION
Return TRUE, store symbol section and value in @var{*sec} and
@var{*value} if symbol @var{h} is defined during a final link.
*/
bfd_boolean
bfd_link_get_defined_symbol (struct bfd_link_info *info,
struct bfd_link_hash_entry *h,
asection **sec, bfd_vma *value)
{
if (h->type == bfd_link_hash_defined
|| h->type == bfd_link_hash_defweak)
{
if (sec)
*sec = h->u.def.section;
if (value)
*value = h->u.def.value;
return TRUE;
}
if (h->type == bfd_link_hash_new
|| h->type == bfd_link_hash_undefined
|| h->type == bfd_link_hash_undefweak)
{
/* Check yet undefined reference to __start_XXX or __stop_XXX
symbols. The linker will later define such symbols for output
sections that have a name representable as a C identifier. */
const char *sec_name;
if (strncmp (h->root.string, "__start_", 8) == 0)
sec_name = h->root.string + 8;
else if (strncmp (h->root.string, "__stop_", 7) == 0)
sec_name = h->root.string + 7;
else
sec_name = NULL;
if (sec_name != NULL && *sec_name != '\0')
{
bfd *i;
for (i = info->input_bfds; i != NULL; i = i->link.next)
{
asection *s = bfd_get_section_by_name (i, sec_name);
if (s != NULL)
{
asection *asect;
bfd_vma size;
if (sec)
*sec = s;
if (!value)
return TRUE;
if (sec_name == (h->root.string + 8))
{
/* Set __start_XXX symbol value. */
*value = 0;
return TRUE;
}
/* Get the size of the output XXX section for
__stop_XXX symbol value. */
size = 0;
for (asect = s->output_section->map_head.s;
asect != NULL;
asect = asect->map_head.s)
{
size = align_power (size, asect->alignment_power);
size += asect->size;
}
*value = size;
return TRUE;
}
}
}
}
return FALSE;
}

View File

@@ -1,3 +1,15 @@
2015-10-26 H.J. Lu <hongjiu.lu@intel.com>
PR ld/19175
* ld-i386/i386.exp: Run pr19175.
* ld-x86-64/x86-64.exp: Likewise.
* ld-i386/pr19175.d: New file.
* ld-i386/pr19175.s: Likewise.
* ld-i386/pr19175.t: Likewise.
* ld-x86-64/pr19175.d: Likewise.
* ld-x86-64/pr19175.s: Likewise.
* ld-x86-64/pr19175.t: Likewise.
2015-10-26 H.J. Lu <hongjiu.lu@intel.com> 2015-10-26 H.J. Lu <hongjiu.lu@intel.com>
PR ld/19171 PR ld/19171

View File

@@ -315,6 +315,7 @@ run_dump_test "load4b"
run_dump_test "load5a" run_dump_test "load5a"
run_dump_test "load5b" run_dump_test "load5b"
run_dump_test "load6" run_dump_test "load6"
run_dump_test "pr19175"
if { !([istarget "i?86-*-linux*"] if { !([istarget "i?86-*-linux*"]
|| [istarget "i?86-*-gnu*"] || [istarget "i?86-*-gnu*"]

View File

@@ -0,0 +1,13 @@
#source: pr19175.s
#as: --32
#ld: -Bsymbolic -shared -melf_i386 -T pr19175.t
#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

View File

@@ -0,0 +1,5 @@
.globl _start
.type _start, @function
_start:
movl _text@GOT(%ecx), %eax
.size _start, .-_start

View File

@@ -0,0 +1,11 @@
EXTERN(_start)
ENTRY(_start)
SECTIONS
{
.text :
{
_text = .;
*(.text*)
}
}

View File

@@ -0,0 +1,13 @@
#source: pr19175.s
#as: --64
#ld: -Bsymbolic -shared -melf_x86_64 -T pr19175.t
#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]+ <_start>
#pass

View File

@@ -0,0 +1,5 @@
.globl _start
.type _start, @function
_start:
movq _text@GOTPCREL(%rip), %rax
.size _start, .-_start

View File

@@ -0,0 +1,11 @@
EXTERN(_start)
ENTRY(_start)
SECTIONS
{
.text :
{
_text = .;
*(.text*)
}
}

View File

@@ -347,6 +347,7 @@ run_dump_test "pr18815"
run_dump_test "pr19013" run_dump_test "pr19013"
run_dump_test "pr19013-x32" run_dump_test "pr19013-x32"
run_dump_test "pr19013-nacl" run_dump_test "pr19013-nacl"
run_dump_test "pr19175"
# Add $PLT_CFLAGS if PLT is expected. # Add $PLT_CFLAGS if PLT is expected.
global PLT_CFLAGS global PLT_CFLAGS