This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[patch] Weak definition operrides strong definition
- From: Paul Brook <paul at codesourcery dot com>
- To: binutils at sources dot redhat dot com
- Date: Mon, 2 May 2005 02:44:36 +0100
- Subject: [patch] Weak definition operrides strong definition
When linking a mixture of strong and weak symbols the attributes (size, type)
of the resulting symbol is the size/type of the last symbol seen, not the
strong definition. This breaks Arm interworking when linking an arm
(STT_FUNC) weak definition and a thumb (STT_ARM_TFUNC) strong definition, and
vice versa. If the weak definition appears after the strong definition the
symbol is given the STT_FUNC, and the wrong interworking stubs are generated.
This bug could also cause problems with utilities that use the st_size field.
The attached files demonstrate the problem. Compile with gcc foo1.c foo2.c and
the "foo" symbol will have the address of the smaller routine, but the size
of the larger.
The attached patch fixes this by skipping weak definitions if we have already
seen a non-weak definition.
Tested on i686-linux and arm-none-eabi.
Ok?
Paul
2005-05-01 Paul Brook <paul@codesourcery.com>
* elflink.c (_bfd_elf_merge_symbol): Skip weak definitions if a strong
definition has already been seen.
void foo ()
{
}
int main()
{
foo();
return 0;
}
#include <stdio.h>
void __attribute__((weak))
foo()
{
printf("Hello\n");
printf("World\n");
}
Index: bfd/elflink.c
===================================================================
RCS file: /var/cvsroot/src-cvs/src/bfd/elflink.c,v
retrieving revision 1.136.2.1
diff -u -p -r1.136.2.1 elflink.c
--- bfd/elflink.c 22 Mar 2005 14:49:54 -0000 1.136.2.1
+++ bfd/elflink.c 1 May 2005 12:51:24 -0000
@@ -1075,6 +1075,10 @@ _bfd_elf_merge_symbol (bfd *abfd,
|| h->root.type == bfd_link_hash_undefined)
*size_change_ok = TRUE;
+ /* Skip weak definitions of symbols that are already defined. */
+ if (newdef && olddef && newweak && !oldweak)
+ *skip = TRUE;
+
/* NEWDYNCOMMON and OLDDYNCOMMON indicate whether the new or old
symbol, respectively, appears to be a common symbol in a dynamic
object. If a symbol appears in an uninitialized section, and is