summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2011-06-10 14:04:23 +0000
committerNick Clifton <nickc@redhat.com>2011-06-10 14:04:23 +0000
commit1f1f769d367925f35765c3b683caff6e592372f3 (patch)
tree508934f3fea0090bdc2d6cbc68781bc9e92a270b
parent4725c921b7bee688081b6d63c3c96a6c1c6037d1 (diff)
downloadbinutils-redhat-1f1f769d367925f35765c3b683caff6e592372f3.tar.gz
* elflink.c (_bfd_elf_link_create_dynamic_sections): If the
backend does not provide a function for creating dynamic sections then fail. (bfd_elf_final_link): Issue a warning message if a dynamic section has the SHT_NOTE type. (bfd_elf_final_link): Do not look for dynamic strings in a section that does not have the SHT_STRTAB type or the name .dynstr. * elf32-arm.c (elf32_arm_finish_dynamic_sections): Fail if the got section is not in the output binary. * elf32-hppa.c (elf32_hppa_finish_dynamic_sections): Likewise. * ld-elf/elf.exp: Add test for linking a shared library with a broken linker script that marks dynamic sections as being notes. * ld-elf/note-3.s: New test source file. * ld-elf/note-3.t: New test linker script. * ld-elf/note-3.l: Expected output from the linker. * lib/ld-lib.exp (run_ld_link_tests): Improve description.
-rw-r--r--bfd/ChangeLog13
-rw-r--r--bfd/elf32-arm.c4
-rw-r--r--bfd/elf32-hppa.c19
-rw-r--r--bfd/elflink.c12
-rw-r--r--bfd/linker.c2
-rw-r--r--ld/testsuite/ChangeLog9
-rw-r--r--ld/testsuite/ld-elf/elf.exp39
-rw-r--r--ld/testsuite/ld-elf/note-3.l2
-rw-r--r--ld/testsuite/ld-elf/note-3.s10
-rw-r--r--ld/testsuite/ld-elf/note-3.t22
-rw-r--r--ld/testsuite/lib/ld-lib.exp34
11 files changed, 144 insertions, 22 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 58aa6e723c..1e72bf2d86 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,16 @@
+2011-06-10 Nick Clifton <nickc@redhat.com>
+
+ * elflink.c (_bfd_elf_link_create_dynamic_sections): If the
+ backend does not provide a function for creating dynamic sections
+ then fail.
+ (bfd_elf_final_link): Issue a warning message if a dynamic section
+ has the SHT_NOTE type.
+ (bfd_elf_final_link): Do not look for dynamic strings in a section
+ that does not have the SHT_STRTAB type or the name .dynstr.
+ * elf32-arm.c (elf32_arm_finish_dynamic_sections): Fail if the got
+ section is not in the output binary.
+ * elf32-hppa.c (elf32_hppa_finish_dynamic_sections): Likewise.
+
2011-06-09 Tristan Gingold <gingold@adacore.com>
* elfnn-ia64.c (elfNN_ia64_relax_section, elfNN_ia64_choose_gp)
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index d5a4a4ecff..8ace48a801 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -13744,6 +13744,10 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info
dynobj = elf_hash_table (info)->dynobj;
sgot = htab->root.sgotplt;
+ /* A broken linker script might have discarded the dynamic sections.
+ Catch this here so that we do not seg-fault later on. */
+ if (sgot != NULL && bfd_is_abs_section (sgot->output_section))
+ return FALSE;
sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
if (elf_hash_table (info)->dynamic_sections_created)
diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c
index 81bc042a61..e70d7e52f3 100644
--- a/bfd/elf32-hppa.c
+++ b/bfd/elf32-hppa.c
@@ -4498,6 +4498,7 @@ elf32_hppa_finish_dynamic_sections (bfd *output_bfd,
bfd *dynobj;
struct elf32_hppa_link_hash_table *htab;
asection *sdyn;
+ asection * sgot;
htab = hppa_link_hash_table (info);
if (htab == NULL)
@@ -4505,6 +4506,12 @@ elf32_hppa_finish_dynamic_sections (bfd *output_bfd,
dynobj = htab->etab.dynobj;
+ sgot = htab->sgot;
+ /* A broken linker script might have discarded the dynamic sections.
+ Catch this here so that we do not seg-fault later on. */
+ if (sgot != NULL && bfd_is_abs_section (sgot->output_section))
+ return FALSE;
+
sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
if (htab->etab.dynamic_sections_created)
@@ -4569,19 +4576,19 @@ elf32_hppa_finish_dynamic_sections (bfd *output_bfd,
}
}
- if (htab->sgot != NULL && htab->sgot->size != 0)
+ if (sgot != NULL && sgot->size != 0)
{
/* Fill in the first entry in the global offset table.
We use it to point to our dynamic section, if we have one. */
bfd_put_32 (output_bfd,
sdyn ? sdyn->output_section->vma + sdyn->output_offset : 0,
- htab->sgot->contents);
+ sgot->contents);
/* The second entry is reserved for use by the dynamic linker. */
- memset (htab->sgot->contents + GOT_ENTRY_SIZE, 0, GOT_ENTRY_SIZE);
+ memset (sgot->contents + GOT_ENTRY_SIZE, 0, GOT_ENTRY_SIZE);
/* Set .got entry size. */
- elf_section_data (htab->sgot->output_section)
+ elf_section_data (sgot->output_section)
->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
}
@@ -4601,8 +4608,8 @@ elf32_hppa_finish_dynamic_sections (bfd *output_bfd,
if ((htab->splt->output_offset
+ htab->splt->output_section->vma
+ htab->splt->size)
- != (htab->sgot->output_offset
- + htab->sgot->output_section->vma))
+ != (sgot->output_offset
+ + sgot->output_section->vma))
{
(*_bfd_error_handler)
(_(".got section not immediately after .plt section"));
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 639c3e7edf..ef7a524809 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -286,7 +286,8 @@ _bfd_elf_link_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
/* Let the backend create the rest of the sections. This lets the
backend set the right flags. The backend will normally create
the .got and .plt sections. */
- if (! (*bed->elf_backend_create_dynamic_sections) (abfd, info))
+ if (bed->elf_backend_create_dynamic_sections == NULL
+ || ! (*bed->elf_backend_create_dynamic_sections) (abfd, info))
return FALSE;
elf_hash_table (info)->dynamic_sections_created = TRUE;
@@ -11148,6 +11149,13 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
(_("%B: could not find output section %s"), abfd, name);
goto error_return;
}
+ if (elf_section_data (o->output_section)->this_hdr.sh_type == SHT_NOTE)
+ {
+ (*_bfd_error_handler)
+ (_("warning: section '%s' is being made into a note"), name);
+ bfd_set_error (bfd_error_nonrepresentable_section);
+ goto error_return;
+ }
dyn.d_un.d_ptr = o->vma;
break;
@@ -11235,7 +11243,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
continue;
if ((elf_section_data (o->output_section)->this_hdr.sh_type
!= SHT_STRTAB)
- || strcmp (bfd_get_section_name (abfd, o), ".dynstr") != 0)
+ && (strcmp (bfd_get_section_name (abfd, o), ".dynstr") != 0))
{
/* FIXME: octets_per_byte. */
if (! bfd_set_section_contents (abfd, o->output_section,
diff --git a/bfd/linker.c b/bfd/linker.c
index 90ab63e354..bac541799f 100644
--- a/bfd/linker.c
+++ b/bfd/linker.c
@@ -1566,6 +1566,8 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
struct bfd_link_hash_entry *h;
bfd_boolean cycle;
+ BFD_ASSERT (section != NULL);
+
if (bfd_is_ind_section (section)
|| (flags & BSF_INDIRECT) != 0)
row = INDR_ROW;
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index 43b678f66f..d224e3c51b 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,12 @@
+2011-06-10 Nick Clifton <nickc@redhat.com>
+
+ * ld-elf/elf.exp: Add test for linking a shared library with a
+ broken linker script that marks dynamic sections as being notes.
+ * ld-elf/note-3.s: New test source file.
+ * ld-elf/note-3.t: New test linker script.
+ * ld-elf/note-3.l: Expected output from the linker.
+ * lib/ld-lib.exp (run_ld_link_tests): Improve description.
+
2011-06-08 H.J. Lu <hongjiu.lu@intel.com>
* ld-x86-64/x86-64.exp: Build x32 DSO from x86-64 object file
diff --git a/ld/testsuite/ld-elf/elf.exp b/ld/testsuite/ld-elf/elf.exp
index e991f830ce..61efc4a140 100644
--- a/ld/testsuite/ld-elf/elf.exp
+++ b/ld/testsuite/ld-elf/elf.exp
@@ -49,6 +49,45 @@ run_ld_link_tests {
{symbol3w.s} {} "symbol3w.a"}
}
+# Run a test to check linking a shared library with a broken linker
+# script that accidentally marks dynamic sections as notes. The
+# resulting executable is not expected to work, but the linker
+# should not seg-fault whilst creating the binary.
+#
+# Only run the test on targets thats support creating shared libraries.
+if { ! [istarget arc-*-*]
+ && ! [istarget avr-*-*]
+ && ! [istarget cr16-*-*]
+ && ! [istarget cris*-*-*]
+ && ! [istarget crx-*-*]
+ && ! [istarget d10v-*-*]
+ && ! [istarget d30v-*-*]
+ && ! [istarget dlx-*-*]
+ && ! [istarget fr30-*-*]
+ && ! [istarget frv-*-*]
+ && ! [istarget h8300-*-*]
+ && ! [istarget ip2k-*-*]
+ && ! [istarget m32r-*-*]
+ && ! [istarget mcore*-*-*]
+ && ! [istarget mn10200-*-*]
+ && ! [istarget msp430-*-*]
+ && ! [istarget openrisc-*-*]
+ && ! [istarget or32-*-*]
+ && ! [istarget pj-*-*]
+ && ! [istarget rx-*-*]
+ && ! [istarget v850-*-*]
+ && ! [istarget *-*-irix*]
+ && ! [istarget *-*-rtems] } {
+ run_ld_link_tests {
+ {"Build shared library for next test"
+ "-shared" "" "note-3.s" {} "note-3.so" }
+ {"Link using broken linker script"
+ "--script note-3.t tmpdir/note-3.so" "" ""
+ { { ld "note-3.l" } }
+ "a.out" }
+ }
+}
+
set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
foreach t $test_list {
# We need to strip the ".d", but can leave the dirname.
diff --git a/ld/testsuite/ld-elf/note-3.l b/ld/testsuite/ld-elf/note-3.l
new file mode 100644
index 0000000000..551ebaa795
--- /dev/null
+++ b/ld/testsuite/ld-elf/note-3.l
@@ -0,0 +1,2 @@
+.*warning: section '.hash' is being made into a note
+.*
diff --git a/ld/testsuite/ld-elf/note-3.s b/ld/testsuite/ld-elf/note-3.s
new file mode 100644
index 0000000000..3a1d190887
--- /dev/null
+++ b/ld/testsuite/ld-elf/note-3.s
@@ -0,0 +1,10 @@
+ .globl _entry
+ .text
+_entry:
+ .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+ .global foo
+foo:
+ .byte 9
+
+ .section .note,"",%note
+ .byte 0
diff --git a/ld/testsuite/ld-elf/note-3.t b/ld/testsuite/ld-elf/note-3.t
new file mode 100644
index 0000000000..13324ae547
--- /dev/null
+++ b/ld/testsuite/ld-elf/note-3.t
@@ -0,0 +1,22 @@
+PHDRS
+{
+ text PT_LOAD FILEHDR PHDRS ;
+ note PT_NOTE;
+}
+SECTIONS
+{
+ . = . + SIZEOF_HEADERS ;
+ .text : { *(.text) *(.rodata) } :text
+ .note : { *(.note) } :note :text
+
+ /* BUG: This linker script is broken here. It has not reset the
+ output segment for the following sections, so they are all
+ treated as notes... */
+
+ .hash : { *(.hash) }
+
+ .dynstr : { *(.dynstr) }
+ .dynsym : { *(.dynsym) }
+ .got.plt : { *(.got.plt) *(.igot.plt) }
+ /DISCARD/ : { *(*) }
+}
diff --git a/ld/testsuite/lib/ld-lib.exp b/ld/testsuite/lib/ld-lib.exp
index 62e0ff70d2..2020372437 100644
--- a/ld/testsuite/lib/ld-lib.exp
+++ b/ld/testsuite/lib/ld-lib.exp
@@ -903,18 +903,24 @@ proc ar_simple_create { ar aropts target objects } {
# List contains test-items with 3 items followed by 2 lists, one item and
# one optional item:
-# 0:name 1:ld/ar options 2:assembler options
-# 3:filenames of assembler files 4: action and options. 5: name of output file
-# 6:compiler flags (optional)
+# 0:name
+# 1:ld/ar options
+# 2:assembler options
+# 3:filenames of assembler files
+# 4:list of actions, options and expected outputs.
+# 5:name of output file
+# 6:compiler flags (optional)
#
-# Actions:
-# objdump: Apply objdump options on result. Compare with regex (last arg).
-# nm: Apply nm options on result. Compare with regex (last arg).
-# readelf: Apply readelf options on result. Compare with regex (last arg).
-# ld: Don't apply anything on result. Compare output during linking with
-# regex (second arg). Note that this *must* be the first action if it
-# is to be used at all; in all other cases, any output from the linker
-# during linking is treated as a sign of an error and FAILs the test.
+# Actions: { command command-line-options file-containg-expected-output-regexps }
+# Commands:
+# objdump: Apply objdump options on result.
+# nm: Apply nm options on result.
+# readelf: Apply readelf options on result.
+# ld: Don't apply anything on result. Compare output during linking with
+# the file containing regexps (which is the second arg, not the third).
+# Note that this *must* be the first action if it is to be used at all;
+# in all other cases, any output from the linker during linking is
+# treated as a sign of an error and FAILs the test.
#
proc run_ld_link_tests { ldtests } {
global ld
@@ -1019,11 +1025,11 @@ proc run_ld_link_tests { ldtests } {
}
if { $action == "ld" } {
- set dumpfile [lindex $actionlist 1]
- verbose "dumpfile is $dumpfile"
+ set regexpfile $progopts
+ verbose "regexpfile is $srcdir/$subdir/$regexpfile"
set_file_contents "tmpdir/ld.messages" "$ld_output"
verbose "ld.messages has '[file_contents tmpdir/ld.messages]'"
- if { [regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$dumpfile"] } then {
+ if { [regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$regexpfile"] } then {
verbose "output is $ld_output" 2
set failed 1
break