This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[RFC PATCH 2/4] Fix relocations for NT weak external symbols
- From: Octavian Purdila <octavian dot purdila at intel dot com>
- To: binutils at sourceware dot org
- Cc: Octavian Purdila <octavian dot purdila at intel dot com>
- Date: Thu, 22 Oct 2015 19:10:18 +0300
- Subject: [RFC PATCH 2/4] Fix relocations for NT weak external symbols
- Authentication-results: sourceware.org; auth=none
- References: <1445530220-4412-1-git-send-email-octavian dot purdila at intel dot com>
Relocations are currently broken for weak eternals. This can be
observed with 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__);
}
$ i686-w64-mingw32-gcc -o a.exe a.c b.c
$ wine ./a.exe
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00000000).
Register dump:
CS:0023 SS:002b DS:002b ES:002b FS:0063 GS:006b
EIP:00000000 ESP:0061fd7c EBP:0061fd88 EFLAGS:00010202( R- -- I - - - )
EAX:00000001 EBX:00000001 ECX:0061fd20 EDX:00115b50
ESI:00113738 EDI:0000001d
Stack dump:
0x0061fd7c: 00401570 00000000 7b83a376 0061fe50
0x0061fd8c: 004013e2 00000001 00113738 00115b50
0x0061fd9c: 3b503f44 0061fe20 00000000 0061fdc8
0x0061fdac: 7bc854b1 cccccccc cccccccc cccccccc
0x0061fdbc: cccccccc cccccccc cccccccc cccccccc
0x0061fdcc: cccccccc 0061fdf0 7b8ae000 7b8263e1
000c: sel=0067 base=00000000 limit=00000000 32-bit r-x
Backtrace:
=>0 0x00000000 (0x0061fd88)
1 0x004013e2 in a (+0x13e1) (0x0061fe50)
2 0x7b85a75c call_process_entry+0xb() in kernel32 (0x0061fe68)
$ objdump -x a.exe
...
00401560 <_main>:
401560: 55 push %ebp
401561: 89 e5 mov %esp,%ebp
401563: 83 e4 f0 and $0xfffffff0,%esp
401566: e8 95 01 00 00 call 401700 <___main>
40156b: e8 90 ea bf ff call 0 <_DeleteCriticalSection@4>
401570: b8 00 00 00 00 mov $0x0,%eax
401575: c9 leave
401576: c3 ret
401577: 90 nop
00401578 <.weak._foo.>:
401578: 55 push %ebp
401579: 89 e5 mov %esp,%ebp
40157b: 83 ec 18 sub $0x18,%esp
40157e: c7 44 24 04 2d 40 40 movl $0x40402d,0x4(%esp)
401585: 00
401586: c7 04 24 24 40 40 00 movl $0x404024,(%esp)
40158d: e8 b2 11 00 00 call 402744 <_printf>
401592: c9 leave
401593: c3 ret
Notice how if we change the link order things work as expected:
$ i686-w64-mingw32-gcc -o a.exe a.c b.c
$ objdump -x a.exe
...
00401560 <.weak._foo.>:
401560: 55 push %ebp
401561: 89 e5 mov %esp,%ebp
401563: 83 ec 18 sub $0x18,%esp
401566: c7 44 24 04 2d 40 40 movl $0x40402d,0x4(%esp)
40156d: 00
40156e: c7 04 24 24 40 40 00 movl $0x404024,(%esp)
401575: e8 ca 11 00 00 call 402744 <_printf>
40157a: c9 leave
40157b: c3 ret
0040157c <_main>:
40157c: 55 push %ebp
40157d: 89 e5 mov %esp,%ebp
40157f: 83 e4 f0 and $0xfffffff0,%esp
401582: e8 79 01 00 00 call 401700 <___main>
401587: e8 d4 ff ff ff call 401560 <.weak._foo.>
40158c: b8 00 00 00 00 mov $0x0,%eax
401591: c9 leave
401592: c3 ret
This patch requires changes in both the gas coff generator and the
coff linker.
The first change is propagating the type of external weak symbols to
its .weak. counterpart symbol so that the linker can add the
.weak. counterpart symbol before processing the weak symbol
relocations (see the ISFCN() statement in _bfd_coff_link_input_bfd).
The second change is to fixup the symbol class and load the aux
information for weak externals. This is needed to relocate the NT weak
symbols in _bfd_coff_generic_relocate_section.
gas/
2015-10-22 Octavian Purdila <octavian.purdila@intel.com>
* obj-coff.c (coff_frob_symbol): propagate the type of external
weak symbol to its .weak. counterpart
bfd/
2015-10-22 Octavian Purdila <octavian.purdila@intel.com>
* cofflink.c (coff_link_add_symbols): fixup the symbol class and
load the aux information for weak externals
---
bfd/ChangeLog | 5 +++++
bfd/cofflink.c | 3 ++-
gas/ChangeLog | 5 +++++
gas/config/obj-coff.c | 1 +
4 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 3241ccd..e7b117c 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,8 @@
+2015-10-22 Octavian Purdila <octavian.purdila@intel.com>
+
+ * cofflink.c (coff_link_add_symbols): fixup the symbol class and
+ load the aux information for weak externals
+
2015-10-22 Octavian Purdila <octavian.purdila@intel.com>
* linker.c: update the link_action table to correctly deal with NT
diff --git a/bfd/cofflink.c b/bfd/cofflink.c
index 8d98fec..7f539fa 100644
--- a/bfd/cofflink.c
+++ b/bfd/cofflink.c
@@ -428,7 +428,8 @@ coff_link_add_symbols (bfd *abfd,
|| sym.n_scnum != 0
|| (sym.n_value != 0
&& (*sym_hash)->root.type != bfd_link_hash_defined
- && (*sym_hash)->root.type != bfd_link_hash_defweak))
+ && (*sym_hash)->root.type != bfd_link_hash_defweak)
+ || (sym.n_sclass == C_NT_WEAK && sym.n_numaux == 1))
{
(*sym_hash)->symbol_class = sym.n_sclass;
if (sym.n_type != T_NULL)
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 2ece5c0..c7dafe4 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+2015-10-22 Octavian Purdila <octavian.purdila@intel.com>
+
+ * obj-coff.c (coff_frob_symbol): propagate the type of external
+ weak symbol to its .weak. counterpart
+
2015-10-02 Renlin Li <renlin.li@arm.com>
* config/tc-aarch64.c (s_tlsdescadd): New.
diff --git a/gas/config/obj-coff.c b/gas/config/obj-coff.c
index c0a3f1f..ac2310c 100644
--- a/gas/config/obj-coff.c
+++ b/gas/config/obj-coff.c
@@ -1277,6 +1277,7 @@ coff_frob_symbol (symbolS *symp, int *punt)
symbol_get_value_expression (weakp));
symbol_set_frag (symp, symbol_get_frag (weakp));
S_SET_SEGMENT (symp, S_GET_SEGMENT (weakp));
+ S_SET_DATA_TYPE (symp, S_GET_DATA_TYPE (weakp));
}
else
{
--
2.1.0