152 lines
5.2 KiB
Diff
152 lines
5.2 KiB
Diff
From 20932eba3b856aec9ad15b8a5f6220dce10bf1fa Mon Sep 17 00:00:00 2001
|
|
From: Octavian Purdila <octavian dot purdila at intel dot com>
|
|
Date: Mon, 26 Oct 2015 15:57:34 +0200
|
|
Subject: [PATCH 2/3] Relocate aux entries for NT weak externals
|
|
|
|
Currently the tagndx for NT weak externals are not relocated when
|
|
creating a relocatable object which breaks relocations when doing the
|
|
final link of the relocatable object.
|
|
|
|
For 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-ld -r -o r.o a.o b.o
|
|
|
|
This is how the symbol table looks for b.o:
|
|
|
|
$ i686-w64-mingw32-objdump -x b.o | grep -A 1 foo
|
|
[ 23](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 .weak._foo.
|
|
[ 24](sec 0)(fl 0x00)(ty 20)(scl 105) (nx 1) 0x00000000 _foo
|
|
|
|
And this is how the symbol table table looks for r.o:
|
|
|
|
$ i686-w64-mingw32-objdump -x r.o | grep -A 1 foo
|
|
[ 45](sec 0)(fl 0x00)(ty 20)(scl 105) (nx 1) 0x00000000 _foo
|
|
AUX lnno 1 size 0x0 tagndx 23
|
|
...
|
|
[ 48](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 .weak._foo.
|
|
|
|
As you can see the AUX entry for _foo is wrong in r.o, it should be 48
|
|
but it is 23.
|
|
|
|
The patch uses the sym_indices array to relocate the AUX entries for
|
|
weak externals in _bfd_coff_link_input_bfd.
|
|
|
|
In order to do so we need the .weak. counterpart symbol to be loaded
|
|
before the weak external symbol. This is prevented by by the ISFCN()
|
|
check _bfd_coff_link_input_bfd and is caused by the fact that the AUX
|
|
entry type is 0. To fix this issue we patch gas to propagate the type
|
|
of external weak symbols to its .weak. counterpart symbol.
|
|
|
|
Note that we perform the AUX tag relocations only int the case of
|
|
relocatable output because weak external relocation handling
|
|
(_bfd_coff_generic_relocate_section) uses the tagndx relative to the
|
|
input object.
|
|
|
|
bfd/
|
|
|
|
2015-10-26 Octavian Purdila <octavian.purdila@intel.com>
|
|
|
|
* cofflink.c (_bfd_coff_link_input_bfd): relocate AUX entries for
|
|
weak externals when generating relocatable objects
|
|
|
|
gas/
|
|
|
|
2015-10-26 Octavian Purdila <octavian.purdila@intel.com>
|
|
|
|
* obj-coff.c (coff_frob_symbol): propagate the type of external
|
|
weak symbol to its .weak. counterpart
|
|
---
|
|
bfd/ChangeLog | 5 +++++
|
|
bfd/cofflink.c | 14 +++++++++++---
|
|
gas/ChangeLog | 5 +++++
|
|
gas/config/obj-coff.c | 1 +
|
|
4 files changed, 22 insertions(+), 3 deletions(-)
|
|
|
|
diff --git binutils-2.28.orig/bfd/ChangeLog binutils-2.28/bfd/ChangeLog
|
|
index 246bb64..05cb3df 100644
|
|
--- binutils-2.28.orig/bfd/ChangeLog
|
|
+++ binutils-2.28/bfd/ChangeLog
|
|
@@ -1,4 +1,8 @@
|
|
2017-04-29 octavian purdila <octavian.purdila@intel.com>
|
|
+ * cofflink.c (_bfd_coff_link_input_bfd): relocate AUX entries for
|
|
+ weak externals when generating relocatable objects
|
|
+
|
|
+2017-04-29 octavian purdila <octavian.purdila@intel.com>
|
|
|
|
* cofflink.c: Move weak external relocation code to a new function
|
|
(_bfd_coff_relocate_weak_externals)
|
|
diff --git binutils-2.28.orig/bfd/cofflink.c binutils-2.28/bfd/cofflink.c
|
|
index 7c4637c..5e1fae7 100644
|
|
--- binutils-2.28.orig/bfd/cofflink.c
|
|
+++ binutils-2.28/bfd/cofflink.c
|
|
@@ -1977,7 +1977,8 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd)
|
|
if ((*indexp < 0
|
|
|| (bfd_size_type) *indexp < syment_base)
|
|
&& (*sym_hash == NULL
|
|
- || (*sym_hash)->auxbfd != input_bfd))
|
|
+ || (*sym_hash)->auxbfd != input_bfd)
|
|
+ && isymp->n_sclass != C_NT_WEAK)
|
|
esym += add * isymesz;
|
|
else
|
|
{
|
|
@@ -2047,8 +2048,15 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd)
|
|
auxp->x_file.x_n.x_offset = STRING_SIZE_SIZE + indx;
|
|
}
|
|
}
|
|
- else if ((isymp->n_sclass != C_STAT || isymp->n_type != T_NULL)
|
|
- && isymp->n_sclass != C_NT_WEAK)
|
|
+ else if (isymp->n_sclass == C_NT_WEAK)
|
|
+ {
|
|
+ long *tagndx = &auxp->x_sym.x_tagndx.l;
|
|
+
|
|
+ if (bfd_link_relocatable(flaginfo->info) &&
|
|
+ flaginfo->sym_indices[*tagndx] > 0)
|
|
+ *tagndx = flaginfo->sym_indices[*tagndx];
|
|
+ }
|
|
+ else if (isymp->n_sclass != C_STAT || isymp->n_type != T_NULL)
|
|
{
|
|
unsigned long indx;
|
|
|
|
diff --git binutils-2.28.orig/gas/ChangeLog binutils-2.28/gas/ChangeLog
|
|
index 8a586ad..ebf2946 100644
|
|
--- binutils-2.28.orig/gas/ChangeLog
|
|
+++ binutils-2.28/gas/ChangeLog
|
|
@@ -1,3 +1,8 @@
|
|
+2017-04-29 Octavian Purdila <octavian.purdila@intel.com>
|
|
+
|
|
+ * obj-coff.c (coff_frob_symbol): propagate the type of external
|
|
+ weak symbol to its .weak. counterpart
|
|
+
|
|
2017-03-02 Tristan Gingold <gingold@adacore.com>
|
|
|
|
* configure: Regenerate.
|
|
diff --git binutils-2.28.orig/gas/config/obj-coff.c binutils-2.28/gas/config/obj-coff.c
|
|
index 5913b4a..106fb20 100644
|
|
--- binutils-2.28.orig/gas/config/obj-coff.c
|
|
+++ binutils-2.28/gas/config/obj-coff.c
|
|
@@ -1263,6 +1263,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
|
|
{
|