This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[patch] relax16.c: Eliminate an assertion failure.
- To: binutils at sources dot redhat dot com
- Subject: [patch] relax16.c: Eliminate an assertion failure.
- From: Kazu Hirata <kazu at hxi dot com>
Hi,
Attached is a patch to stop an abortion causesed by an assertion in
bfd/reloc16.c.
First, here is the way to cause this assertion failure.
main1.c / main2.c (both the same contents)
void
test ()
{
main ();
}
int
main ()
{
return 0;
}
Compile these with:
h8300-hms-gcc -mh -Wl,--relax -Wall -O2 -fomit-frame-pointer -o bfdbug main1.c main2.c
Then I get:
/usr/local/bin/h8300-hms-gcc -mh -Wl,--relax -Wall -o h8os.out main1.o main2.o
main2.o(.text+0x0):main2.c: multiple definition of `test'
main1.o(.text+0x0):main1.c: first defined here
main2.o(.text+0x6):main2.c: multiple definition of `main'
main1.o(.text+0x6):main1.c: first defined here
/usr/local/lib/gcc-lib/h8300-hms/2.96/../../../../h8300-hms/bin/ld: bfd assertion fail ../../src/bfd/reloc16.c:131
collect2: ld returned 1 exit status
make: *** [h8os.out] Error 1
The problem is that a hash key entry for 'main' gets slipped _twice_
as a result of relaxation even though both a symbol for 'main' in
main.c and another one in main2.c get slipped only once each.
I looked for something in the infrastructure that tells whether a
given symbol is defined multiple times, but I could not find that. If
such a thing were there, then I could at least conditionalize the
assertion in question like:
if (! multiple_definition)
BFD_ASSERT (h->root.u.def.value == p->value);
This is why I chose an easier way of simply deleting the assertion. I
hate to remove an assertion that looks right, but I don't think any
input, even erroneous like the one above, should hit that. (Another
possible way of handling this is to prevent relaxation from happening
by a global variable (or per-section variable?) that tells whether at
least one symbol has been defined multiple times.)
Thanks,
Kazu Hirata
===File ~/gnu/binutils/reloc16.c.patch======================
Index: reloc16.c
===================================================================
RCS file: /cvs/src/src/bfd/reloc16.c,v
retrieving revision 1.4
diff -u -r1.4 reloc16.c
--- reloc16.c 2000/07/03 17:49:37 1.4
+++ reloc16.c 2000/09/12 04:31:50
@@ -128,7 +128,6 @@
BFD_ASSERT (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak);
h->root.u.def.value -= slip;
- BFD_ASSERT (h->root.u.def.value == p->value);
}
}
}
============================================================