* 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.
This commit is contained in:
parent
12af614e24
commit
894891db7f
@ -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>
|
2011-06-09 Tristan Gingold <gingold@adacore.com>
|
||||||
|
|
||||||
* elfnn-ia64.c (elfNN_ia64_relax_section, elfNN_ia64_choose_gp)
|
* elfnn-ia64.c (elfNN_ia64_relax_section, elfNN_ia64_choose_gp)
|
||||||
|
@ -13744,6 +13744,10 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info
|
|||||||
dynobj = elf_hash_table (info)->dynobj;
|
dynobj = elf_hash_table (info)->dynobj;
|
||||||
|
|
||||||
sgot = htab->root.sgotplt;
|
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");
|
sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
|
||||||
|
|
||||||
if (elf_hash_table (info)->dynamic_sections_created)
|
if (elf_hash_table (info)->dynamic_sections_created)
|
||||||
|
@ -4498,6 +4498,7 @@ elf32_hppa_finish_dynamic_sections (bfd *output_bfd,
|
|||||||
bfd *dynobj;
|
bfd *dynobj;
|
||||||
struct elf32_hppa_link_hash_table *htab;
|
struct elf32_hppa_link_hash_table *htab;
|
||||||
asection *sdyn;
|
asection *sdyn;
|
||||||
|
asection * sgot;
|
||||||
|
|
||||||
htab = hppa_link_hash_table (info);
|
htab = hppa_link_hash_table (info);
|
||||||
if (htab == NULL)
|
if (htab == NULL)
|
||||||
@ -4505,6 +4506,12 @@ elf32_hppa_finish_dynamic_sections (bfd *output_bfd,
|
|||||||
|
|
||||||
dynobj = htab->etab.dynobj;
|
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");
|
sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
|
||||||
|
|
||||||
if (htab->etab.dynamic_sections_created)
|
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.
|
/* Fill in the first entry in the global offset table.
|
||||||
We use it to point to our dynamic section, if we have one. */
|
We use it to point to our dynamic section, if we have one. */
|
||||||
bfd_put_32 (output_bfd,
|
bfd_put_32 (output_bfd,
|
||||||
sdyn ? sdyn->output_section->vma + sdyn->output_offset : 0,
|
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. */
|
/* 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. */
|
/* Set .got entry size. */
|
||||||
elf_section_data (htab->sgot->output_section)
|
elf_section_data (sgot->output_section)
|
||||||
->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
|
->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4601,8 +4608,8 @@ elf32_hppa_finish_dynamic_sections (bfd *output_bfd,
|
|||||||
if ((htab->splt->output_offset
|
if ((htab->splt->output_offset
|
||||||
+ htab->splt->output_section->vma
|
+ htab->splt->output_section->vma
|
||||||
+ htab->splt->size)
|
+ htab->splt->size)
|
||||||
!= (htab->sgot->output_offset
|
!= (sgot->output_offset
|
||||||
+ htab->sgot->output_section->vma))
|
+ sgot->output_section->vma))
|
||||||
{
|
{
|
||||||
(*_bfd_error_handler)
|
(*_bfd_error_handler)
|
||||||
(_(".got section not immediately after .plt section"));
|
(_(".got section not immediately after .plt section"));
|
||||||
|
@ -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
|
/* Let the backend create the rest of the sections. This lets the
|
||||||
backend set the right flags. The backend will normally create
|
backend set the right flags. The backend will normally create
|
||||||
the .got and .plt sections. */
|
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;
|
return FALSE;
|
||||||
|
|
||||||
elf_hash_table (info)->dynamic_sections_created = TRUE;
|
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);
|
(_("%B: could not find output section %s"), abfd, name);
|
||||||
goto error_return;
|
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;
|
dyn.d_un.d_ptr = o->vma;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -11235,7 +11243,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
|
|||||||
continue;
|
continue;
|
||||||
if ((elf_section_data (o->output_section)->this_hdr.sh_type
|
if ((elf_section_data (o->output_section)->this_hdr.sh_type
|
||||||
!= SHT_STRTAB)
|
!= SHT_STRTAB)
|
||||||
|| strcmp (bfd_get_section_name (abfd, o), ".dynstr") != 0)
|
&& (strcmp (bfd_get_section_name (abfd, o), ".dynstr") != 0))
|
||||||
{
|
{
|
||||||
/* FIXME: octets_per_byte. */
|
/* FIXME: octets_per_byte. */
|
||||||
if (! bfd_set_section_contents (abfd, o->output_section,
|
if (! bfd_set_section_contents (abfd, o->output_section,
|
||||||
|
@ -1566,6 +1566,8 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
|
|||||||
struct bfd_link_hash_entry *h;
|
struct bfd_link_hash_entry *h;
|
||||||
bfd_boolean cycle;
|
bfd_boolean cycle;
|
||||||
|
|
||||||
|
BFD_ASSERT (section != NULL);
|
||||||
|
|
||||||
if (bfd_is_ind_section (section)
|
if (bfd_is_ind_section (section)
|
||||||
|| (flags & BSF_INDIRECT) != 0)
|
|| (flags & BSF_INDIRECT) != 0)
|
||||||
row = INDR_ROW;
|
row = INDR_ROW;
|
||||||
|
@ -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>
|
2011-06-08 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
* ld-x86-64/x86-64.exp: Build x32 DSO from x86-64 object file
|
* ld-x86-64/x86-64.exp: Build x32 DSO from x86-64 object file
|
||||||
|
@ -49,6 +49,45 @@ run_ld_link_tests {
|
|||||||
{symbol3w.s} {} "symbol3w.a"}
|
{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]]
|
set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
|
||||||
foreach t $test_list {
|
foreach t $test_list {
|
||||||
# We need to strip the ".d", but can leave the dirname.
|
# We need to strip the ".d", but can leave the dirname.
|
||||||
|
2
ld/testsuite/ld-elf/note-3.l
Normal file
2
ld/testsuite/ld-elf/note-3.l
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
.*warning: section '.hash' is being made into a note
|
||||||
|
.*
|
10
ld/testsuite/ld-elf/note-3.s
Normal file
10
ld/testsuite/ld-elf/note-3.s
Normal file
@ -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
|
22
ld/testsuite/ld-elf/note-3.t
Normal file
22
ld/testsuite/ld-elf/note-3.t
Normal file
@ -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/ : { *(*) }
|
||||||
|
}
|
@ -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
|
# List contains test-items with 3 items followed by 2 lists, one item and
|
||||||
# one optional item:
|
# one optional item:
|
||||||
# 0:name 1:ld/ar options 2:assembler options
|
# 0:name
|
||||||
# 3:filenames of assembler files 4: action and options. 5: name of output file
|
# 1:ld/ar options
|
||||||
# 6:compiler flags (optional)
|
# 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:
|
# Actions: { command command-line-options file-containg-expected-output-regexps }
|
||||||
# objdump: Apply objdump options on result. Compare with regex (last arg).
|
# Commands:
|
||||||
# nm: Apply nm options on result. Compare with regex (last arg).
|
# objdump: Apply objdump options on result.
|
||||||
# readelf: Apply readelf options on result. Compare with regex (last arg).
|
# nm: Apply nm options on result.
|
||||||
# ld: Don't apply anything on result. Compare output during linking with
|
# readelf: Apply readelf options on result.
|
||||||
# regex (second arg). Note that this *must* be the first action if it
|
# ld: Don't apply anything on result. Compare output during linking with
|
||||||
# is to be used at all; in all other cases, any output from the linker
|
# the file containing regexps (which is the second arg, not the third).
|
||||||
# during linking is treated as a sign of an error and FAILs the test.
|
# 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 } {
|
proc run_ld_link_tests { ldtests } {
|
||||||
global ld
|
global ld
|
||||||
@ -1019,11 +1025,11 @@ proc run_ld_link_tests { ldtests } {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if { $action == "ld" } {
|
if { $action == "ld" } {
|
||||||
set dumpfile [lindex $actionlist 1]
|
set regexpfile $progopts
|
||||||
verbose "dumpfile is $dumpfile"
|
verbose "regexpfile is $srcdir/$subdir/$regexpfile"
|
||||||
set_file_contents "tmpdir/ld.messages" "$ld_output"
|
set_file_contents "tmpdir/ld.messages" "$ld_output"
|
||||||
verbose "ld.messages has '[file_contents tmpdir/ld.messages]'"
|
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
|
verbose "output is $ld_output" 2
|
||||||
set failed 1
|
set failed 1
|
||||||
break
|
break
|
||||||
|
Loading…
x
Reference in New Issue
Block a user