aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2005-04-01 03:49:46 +0000
committerH.J. Lu <hjl.tools@gmail.com>2005-04-01 03:49:46 +0000
commit01b3c8abd1990d27f28e2b90d118fd259993d895 (patch)
tree1fdb1b1b7cb48e5570d1e70f3ccc44231bbd1540
parent35090471860b6c110a9090aba7ff901ec019de2b (diff)
downloadgdb-01b3c8abd1990d27f28e2b90d118fd259993d895.zip
gdb-01b3c8abd1990d27f28e2b90d118fd259993d895.tar.gz
gdb-01b3c8abd1990d27f28e2b90d118fd259993d895.tar.bz2
2005-03-31 H.J. Lu <hongjiu.lu@intel.com>
* elf-bfd.h (_bfd_elf_check_kept_section): New. * elf.c (assign_section_numbers): When sh_link points to a discarded section, call _bfd_elf_check_kept_section to see if the kept section can be used. Otherwise reject sh_link pointing to discarded section. * elflink.c (_bfd_elf_check_kept_section): New. (elf_link_input_bfd): Use it.
-rw-r--r--bfd/ChangeLog12
-rw-r--r--bfd/elf-bfd.h2
-rw-r--r--bfd/elf.c20
-rw-r--r--bfd/elflink.c33
4 files changed, 58 insertions, 9 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index c5b7887..5a948c5 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,15 @@
+2005-03-31 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-bfd.h (_bfd_elf_check_kept_section): New.
+
+ * elf.c (assign_section_numbers): When sh_link points to a
+ discarded section, call _bfd_elf_check_kept_section to see if
+ the kept section can be used. Otherwise reject sh_link
+ pointing to discarded section.
+
+ * elflink.c (_bfd_elf_check_kept_section): New.
+ (elf_link_input_bfd): Use it.
+
2005-04-01 Alan Modra <amodra@bigpond.net.au>
* elf64-ppc.c (ppc64_elf_edit_toc): Account for dynamic relocs
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index a5047de..9d3871b 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -1441,6 +1441,8 @@ extern void _bfd_elf_section_already_linked
(bfd *, struct bfd_section *);
extern void bfd_elf_set_group_contents
(bfd *, asection *, void *);
+extern asection *_bfd_elf_check_kept_section
+ (asection *);
extern void _bfd_elf_link_just_syms
(asection *, struct bfd_link_info *);
extern bfd_boolean _bfd_elf_copy_private_header_data
diff --git a/bfd/elf.c b/bfd/elf.c
index dfbad3c..3aa91a4 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -2919,7 +2919,25 @@ assign_section_numbers (bfd *abfd)
}
else
{
- s = elf_shdrp[elfsec]->bfd_section->output_section;
+ s = elf_shdrp[elfsec]->bfd_section;
+ if (elf_discarded_section (s))
+ {
+ asection *kept;
+ (*_bfd_error_handler)
+ (_("%B: sh_link of section `%A' points to discarded section `%A' of `%B'"),
+ abfd, d->this_hdr.bfd_section,
+ s, s->owner);
+ /* Point to the kept section if it has
+ the same size as the discarded
+ one. */
+ kept = _bfd_elf_check_kept_section (s);
+ if (kept == NULL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+ s = s->output_section;
BFD_ASSERT (s != NULL);
d->this_hdr.sh_link = elf_section_data (s)->this_idx;
}
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 8134834..d37b19b 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -6700,6 +6700,26 @@ match_group_member (asection *sec, asection *group)
return NULL;
}
+/* Check if the kept section of a discarded section SEC can be used
+ to replace it. Return the replacement if it is OK. Otherwise return
+ NULL. */
+
+asection *
+_bfd_elf_check_kept_section (asection *sec)
+{
+ asection *kept;
+
+ kept = sec->kept_section;
+ if (kept != NULL)
+ {
+ if (elf_sec_group (sec) != NULL)
+ kept = match_group_member (sec, kept);
+ if (kept != NULL && sec->size != kept->size)
+ kept = NULL;
+ }
+ return kept;
+}
+
/* Link an input file into the linker output file. This function
handles all the sections and relocations of the input file at once.
This is so that we only have to read the local symbols once, and
@@ -7013,8 +7033,6 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
discarded section. */
if ((sec = *ps) != NULL && elf_discarded_section (sec))
{
- asection *kept;
-
BFD_ASSERT (r_symndx != 0);
if (action & COMPLAIN)
{
@@ -7035,13 +7053,12 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
is that we warn in non-debug sections, and
debug sections tend to come after other
sections. */
- kept = sec->kept_section;
- if (kept != NULL && (action & PRETEND))
+ if (action & PRETEND)
{
- if (elf_sec_group (sec) != NULL)
- kept = match_group_member (sec, kept);
- if (kept != NULL
- && sec->size == kept->size)
+ asection *kept;
+
+ kept = _bfd_elf_check_kept_section (sec);
+ if (kept != NULL)
{
*ps = kept;
continue;