diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2015-10-26 07:08:39 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2015-10-26 07:08:39 -0700 |
commit | b8cb22578e50183fb923f80a9490bcf1fe3ead9c (patch) | |
tree | 60529e2947399e394facca377031c70660394b26 | |
parent | e99717784e628eb85c8495952c1dec562586b0f1 (diff) | |
download | binutils-gdb-users/hjl/pr19171.tar.gz |
-rw-r--r-- | bfd/bfd-in2.h | 2 | ||||
-rw-r--r-- | bfd/elf32-i386.c | 6 | ||||
-rw-r--r-- | bfd/elf64-x86-64.c | 2 | ||||
-rw-r--r-- | bfd/linker.c | 46 |
4 files changed, 42 insertions, 14 deletions
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index c39fadf681c..57d31f29138 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -7516,7 +7516,7 @@ bfd_boolean bfd_hide_sym_by_version (struct bfd_elf_version_tree *verdefs, const char *sym_name); bfd_boolean bfd_link_get_defined_symbol - (bfd *output_bfd, struct bfd_link_hash_entry *h, + (struct bfd_link_info *info, struct bfd_link_hash_entry *h, asection **sec, bfd_vma *value); /* Extracted from simple.c. */ diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 5987767e0f6..97170623077 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -2967,9 +2967,6 @@ convert_branch: } else { - asection *tsec; - bfd_vma toff; - /* We have "mov foo@GOT[(%re1g)], %reg2", "test %reg1, foo@GOT(%reg2)" and "binop foo@GOT[(%reg1)], %reg2". @@ -2979,7 +2976,8 @@ convert_branch: if (h == htab->elf.hdynamic) continue; - if (bfd_link_get_defined_symbol (abfd, &h->root, &tsec, &toff) + if (bfd_link_get_defined_symbol (link_info, &h->root, NULL, + NULL) && SYMBOL_REFERENCES_LOCAL (link_info, h)) { convert_load: diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 269bce5cd78..9778f2fa496 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -3126,7 +3126,7 @@ elf_x86_64_convert_load (bfd *abfd, asection *sec, || h->root.type == bfd_link_hash_warning) h = (struct elf_link_hash_entry *) h->root.u.i.link; - defined = bfd_link_get_defined_symbol (abfd, &h->root, + defined = bfd_link_get_defined_symbol (link_info, &h->root, &tsec, &toff); /* STT_GNU_IFUNC must keep GOTPCREL relocations. We also diff --git a/bfd/linker.c b/bfd/linker.c index 0eafb98f408..0f15d9bcbe2 100644 --- a/bfd/linker.c +++ b/bfd/linker.c @@ -3310,7 +3310,7 @@ FUNCTION SYNOPSIS bfd_boolean bfd_link_get_defined_symbol - (bfd *output_bfd, struct bfd_link_hash_entry *h, + (struct bfd_link_info *info, struct bfd_link_hash_entry *h, asection **sec, bfd_vma *value); DESCRIPTION @@ -3319,15 +3319,17 @@ DESCRIPTION */ bfd_boolean -bfd_link_get_defined_symbol (bfd *output_bfd, +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) { - *sec = h->u.def.section; - *value = h->u.def.value; + if (sec) + *sec = h->u.def.section; + if (value) + *value = h->u.def.value; return TRUE; } @@ -3348,11 +3350,39 @@ bfd_link_get_defined_symbol (bfd *output_bfd, if (sec_name != NULL && *sec_name != '\0') { - asection *s = bfd_get_section_by_name (output_bfd, sec_name); - if (s != NULL) + bfd *i; + bfd_vma size = 0; + bfd_boolean found = FALSE; + + for (i = info->input_bfds; i != NULL; i = i->link.next) + { + asection *s = bfd_get_section_by_name (i, sec_name); + if (s != NULL) + { + if (!found) + { + if (sec) + *sec = s; + if (!value) + return TRUE; + if (sec_name == (h->root.string + 8)) + { + *value = 0; + return TRUE; + } + found = TRUE; + } + + /* Estimate the size of the output XXX section for + __stop_XXX value. */ + size = align_power (size, s->alignment_power); + size += s->size; + } + } + + if (found) { - *sec = s; - *value = sec_name == (h->root.string + 7) ? s->size : 0; + *value = size; return TRUE; } } |