This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC PATCH 1/4] [BFD][LD] Fix linker error when using NT weak externals


Lets take the following example:

a.c:
	void foo(void);

	int main()
	{
		foo();
			return 0;
	}

b.c:
	#include <stdio.h>

	void __attribute__((weak)) foo(void)
	{
		printf("%s weak\n", __func__);
	}

Compiling this with mingw will trigger the following linker error:

$ i686-w64-mingw32-gcc -o a.exe a.c b.c
/tmp/ccZ6Yw7O.o:a.c:(.text+0xc): undefined reference to `foo'
collect2: error: ld returned 1 exit status

Depending on the order in which a.c and b.c are link the following is
happening in _bfd_generic_link_add_one_symbol:

1. If we linked in a.c b.c order then foo will be added in as an
undefined symbol from a.c. Then it will be added as a weak undefined*
symbol from b.c (section undefined, flags BSF_WEAK) and the action
taken will be no action, i.e. keep the symbol undefined.

2. If we linkin b.c a.c order then foo will first be added as an
undefined weak symbol from b.c. Then it will be added as undefined
from a.c and the action taken will be to make the symbol undefined.

To fix these issues we change the link_action table as follows:

1. When an weak undefined symbol is added and the current symbol is
undefined we change its state to weak undefined.

2. When an undefined symbol is added and the current symbol is weak
undefined, we keep the state to weak undefined.

*In PE COFF case defined weak symbols are implemented as weak
externals which requires them to be seen as undefined (weak) symbols.

bfd/

2015-10-22  Octavian Purdila <octavian.purdila@intel.com>

    * linker.c: update the link_action table to correctly deal with NT
    weak externals
---
 bfd/ChangeLog | 5 +++++
 bfd/linker.c  | 4 ++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index db6fe6b..3241ccd 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,8 @@
+2015-10-22  Octavian Purdila <octavian.purdila@intel.com>
+
+	* linker.c: update the link_action table to correctly deal with NT
+	weak externals
+
 2015-10-05  H.J. Lu  <hongjiu.lu@intel.com>
 
 	PR ld/18914
diff --git a/bfd/linker.c b/bfd/linker.c
index 86a7a19..b2b7558 100644
--- a/bfd/linker.c
+++ b/bfd/linker.c
@@ -1354,8 +1354,8 @@ enum link_action
 static const enum link_action link_action[8][8] =
 {
   /* current\prev    new    undef  undefw def    defw   com    indr   warn  */
-  /* UNDEF_ROW 	*/  {UND,   NOACT, UND,   REF,   REF,   NOACT, REFC,  WARNC },
-  /* UNDEFW_ROW	*/  {WEAK,  NOACT, NOACT, REF,   REF,   NOACT, REFC,  WARNC },
+  /* UNDEF_ROW 	*/  {UND,   NOACT, NOACT,   REF,   REF,   NOACT, REFC,  WARNC },
+  /* UNDEFW_ROW	*/  {WEAK,  WEAK, NOACT, REF,   REF,   NOACT, REFC,  WARNC },
   /* DEF_ROW 	*/  {DEF,   DEF,   DEF,   MDEF,  DEF,   CDEF,  MDEF,  CYCLE },
   /* DEFW_ROW 	*/  {DEFW,  DEFW,  DEFW,  NOACT, NOACT, NOACT, NOACT, CYCLE },
   /* COMMON_ROW	*/  {COM,   COM,   COM,   CREF,  COM,   BIG,   REFC,  WARNC },
-- 
2.1.0


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]