This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Committed, CRIS: Fix dynamic-linking bugs
- From: Hans-Peter Nilsson <hans-peter dot nilsson at axis dot com>
- To: binutils at sources dot redhat dot com
- Date: Thu, 31 Jan 2002 11:50:41 +0100
- Subject: Committed, CRIS: Fix dynamic-linking bugs
Two bugs: --export-dynamic wasn't honored. I didn't add the
necessary code despite this being the reason for introducing it
in bfd_link_info. Doh! And I must have missed when
_bfd_elf_strtab_delref became mandatory to be called when
"unexporting" dynamic symbols. Failure to do that resulted in
messages like
ld-new: BFD 2.11.93 20020130 assertion fail /path/to/src/bfd/elf-strtab.c:262
For the testcases, I added simplistic support for linking against
DSO:s in the still minimal ld-cris testsuite directory.
bfd:
* elf32-cris.c (elf_cris_discard_excess_program_dynamics): Don't
unexport unreferenced symbols when --export-dynamic. Call
_bfd_elf_strtab_delref when unexporting.
ld/testsuite:
* ld-cris/weakref1.d, ld-cris/libdso-1.d, ld-cris/gotrel2.s,
ld-cris/expdyn1.d, ld-cris/expdyn1.s, ld-cris/dso-1.s: New tests.
* ld-cris/cris.exp: Split run_dump_tests in two parts, executing
tests named *dso-*.d first and copying their tmpdir/dump to files
named as the .d-file.
Index: elf32-cris.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-cris.c,v
retrieving revision 1.24
diff -p -c -r1.24 elf32-cris.c
*** elf32-cris.c 2002/01/21 21:57:48 1.24
--- elf32-cris.c 2002/01/31 07:05:59
*************** elf_cris_discard_excess_program_dynamics
*** 2936,2943 ****
/* If the locally-defined symbol isn't used by a DSO, then we don't
have to export it as a dynamic symbol. This was already done for
functions; doing this for all symbols would presumably not
! introduce new problems. */
! h->root.dynindx = -1;
}
return true;
--- 2936,2949 ----
/* If the locally-defined symbol isn't used by a DSO, then we don't
have to export it as a dynamic symbol. This was already done for
functions; doing this for all symbols would presumably not
! introduce new problems. Of course we don't do this if we're
! exporting all dynamic symbols. */
! if (! info->export_dynamic)
! {
! h->root.dynindx = -1;
! _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
! h->root.dynstr_index);
! }
}
return true;
diff -cprN /dev/null ld-cris/dso-1.s
*** /dev/null Thu Jan 1 01:00:00 1970
--- ld-cris/dso-1.s Thu Jan 31 05:49:40 2002
***************
*** 0 ****
--- 1,7 ----
+ .text
+ .global dsofn
+ .type dsofn,@function
+ dsofn:
+ nop
+ .Lfe:
+ .size dsofn,.Lfe1-dsofn
diff -cprN /dev/null ld-cris/expdyn1.d
*** /dev/null Tue Jan 1 05:00:00 1980
--- ld-cris/expdyn1.d Thu Jan 31 08:20:47 2002
***************
*** 0 ****
--- 1,14 ----
+ #source: expdyn1.s
+ #as: --no-underscore
+ #ld: -m crislinux -export-dynamic tmpdir/libdso-1.so
+ #objdump: -T
+
+ .*: file format elf32-cris
+
+ # Exporting dynamic symbols means objects as well as functions.
+
+ DYNAMIC SYMBOL TABLE:
+ #...
+ 00080206 g DF .text 00000002 expfn
+ 00082208 g DO .data 00000000 expobj
+ #pass
diff -cprN /dev/null ld-cris/expdyn1.s
*** /dev/null Thu Jan 1 01:00:00 1970
--- ld-cris/expdyn1.s Thu Jan 31 06:22:09 2002
***************
*** 0 ****
--- 1,17 ----
+ .data
+ .global expobj
+ .type expobj,@object
+ expobj:
+ .dword 0
+
+ .text
+ .global _start
+ _start:
+ nop
+ .global expfn
+ expfn:
+ .type expfn,@function
+ nop
+ .Lfe1:
+ .size expfn,.Lfe1-expfn
+
diff -cprN /dev/null ld-cris/gotrel2.s
*** /dev/null Thu Jan 1 01:00:00 1970
--- ld-cris/gotrel2.s Thu Jan 31 07:31:42 2002
***************
*** 0 ****
--- 1,5 ----
+ .text
+ .weak undefweak
+ .global _start
+ _start:
+ move.d [$r0+undefweak:GOT],$r3
diff --exclude=CVS -cprN Null/libdso-1.d ld-cris/libdso-1.d
*** /dev/null Thu Jan 1 01:00:00 1970
--- ld-cris/libdso-1.d Thu Jan 31 06:06:58 2002
***************
*** 0 ****
--- 1,13 ----
+ #source: dso-1.s
+ #as: --pic --no-underscore
+ #ld: --shared -m crislinux
+ #objdump: -T
+
+ # Just check that we actually got a DSO with the dsofn symbol.
+
+ .*: file format elf32-cris
+
+ DYNAMIC SYMBOL TABLE:
+ #...
+ 00000214 g DF .text 00000000 dsofn
+ #pass
diff -cprN /dev/null ld-cris/weakref1.d
*** /dev/null Thu Jan 1 01:00:00 1970
--- ld-cris/weakref1.d Thu Jan 31 08:16:12 2002
***************
*** 0 ****
--- 1,17 ----
+ #source: gotrel2.s
+ #as: --pic --no-underscore
+ #ld: -m crislinux tmpdir/libdso-1.so
+ #objdump: -R
+
+ # A dynamic reloc for an undefined weak reference in a program got a
+ # confused symbol reference count mismatch with a bfd assertion. Linking
+ # with a DSO was needed as a catalyst to get to the faulty code; nothing
+ # in the DSO was needed. We just check that we don't get the bfd
+ # assertion. Note that no actual dynamic reloc is created for the
+ # unresolved weak. Perhaps it should; the symbol could be defined in a
+ # preloaded object or a new version of the DSO. FIXME: Revisit and adjust
+ # test-result.
+
+ .*: file format elf32-cris
+
+ DYNAMIC RELOCATION RECORDS \(none\)
Index: ld-cris/cris.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-cris/cris.exp,v
retrieving revision 1.1
diff -p -c -r1.1 cris.exp
*** cris.exp 2002/01/21 22:04:02 1.1
--- cris.exp 2002/01/31 07:29:42
*************** if ![istarget cris-*-*] {
*** 23,30 ****
}
set rd_test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
foreach atest $rd_test_list {
# We need to strip the ".d", but can leave the dirname.
! verbose [file rootname $atest]
! run_dump_test [file rootname $atest]
}
--- 23,55 ----
}
set rd_test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
+
+ # First, execute those tests that are named to indicate that they create a
+ # DSO. Copy the file from the run_dump_test "tmpdir/dump" to a unique
+ # expected name.
+ # FIXME: Add option "output: filename" to run_dump_test.
+ # FIXME: Add option "ldtail: option" to run_dump_test, so we can link
+ # libraries in the right order.
foreach atest $rd_test_list {
+ # We need to check against runtest_file_p too, or we'd mindlessly copy
+ # the last tmpdir/dump in selective test-runs.
+ if { [string match $srcdir/$subdir/*dso-*.d $atest] \
+ && [runtest_file_p $runtests [file tail $atest]] } {
+ verbose [file rootname $atest]
+ run_dump_test [file rootname $atest]
+ set cmd "cp tmpdir/dump tmpdir/[file rootname [file tail $atest]].so"
+ send_log "$cmd\n"
+ set cmdret [catch "exec $cmd" comp_output]
+ send_log "$comp_output\n"
+ # FIXME: What if it fails? Need we do something?
+ }
+ }
+
+ # Then run the ordinary tests. This round, exclude the dso-* tests.
+ foreach atest $rd_test_list {
# We need to strip the ".d", but can leave the dirname.
! if { ! [string match $srcdir/$subdir/*dso-*.d $atest] } {
! verbose [file rootname $atest]
! run_dump_test [file rootname $atest]
! }
}
brgds, H-P