Files
MSYS2-packages/binutils/0001-coff-linker-weak-nt-externals.patch
Petros Angelatos 85f0605c8b binutils: re-enable weak NT externals patches
Signed-off-by: Petros Angelatos <petrosagg@gmail.com>
2017-01-10 05:04:42 -08:00

184 lines
6.2 KiB
Diff

From f2922a47c8e0f858649d5867df3eff9186bac583 Mon Sep 17 00:00:00 2001
From: Octavian Purdila <octavian dot purdila at intel dot com>
Date: Mon, 26 Oct 2015 15:57:33 +0200
Subject: [PATCH 1/3] 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 linked the following
is happening in _bfd_generic_link_add_one_symbol:
1. If we link 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 link in 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 this issue, this patch checks for an weak external symbol when
doing relocations even if the symbol is undefined. In order to do so,
we also have to also populate the symbol_class and aux members when
adding a weak external symbol over an undefined or weak defined
symbol.
*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-26 Octavian Purdila <octavian.purdila@intel.com>
* cofflink.c: Move weak external relocation code to a new function
(_bfd_coff_relocate_weak_externals)
* cofflink.c (_bfd_coff_generic_relocate_section): Check if we
need to relocate a weak external even if the symbol is undefined
* cofflink.c (coff_link_add_symbols): Fill in the class and aux
when adding a weak external over an undefined or weakly defined
symbol
---
bfd/ChangeLog | 10 +++++++++
bfd/cofflink.c | 66 ++++++++++++++++++++++++++++++++--------------------------
2 files changed, 46 insertions(+), 30 deletions(-)
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 96152768ab..b5b5df1b13 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,13 @@
+2015-10-26 octavian purdila <octavian.purdila@intel.com>
+
+ * cofflink.c: Move weak external relocation code to a new function
+ (_bfd_coff_relocate_weak_externals)
+ * cofflink.c (_bfd_coff_generic_relocate_section): Check if we
+ need to relocate a weak external even if the symbol is undefined
+ * cofflink.c (coff_link_add_symbols): Fill in the class and aux
+ when adding a weak external over an undefined or weakly defined
+ symbol
+
2015-07-21 Tristan Gingold <gingold@adacore.com>
* version.m4: Bump version to 2.25.1
diff --git a/bfd/cofflink.c b/bfd/cofflink.c
index ef9e3623fe..caed7e4aa9 100644
--- a/bfd/cofflink.c
+++ b/bfd/cofflink.c
@@ -426,7 +426,7 @@ coff_link_add_symbols (bfd *abfd,
if (((*sym_hash)->symbol_class == C_NULL
&& (*sym_hash)->type == T_NULL)
|| sym.n_scnum != 0
- || (sym.n_value != 0
+ || ((sym.n_value != 0 || IS_WEAK_EXTERNAL(abfd, sym))
&& (*sym_hash)->root.type != bfd_link_hash_defined
&& (*sym_hash)->root.type != bfd_link_hash_defweak))
{
@@ -2890,6 +2890,37 @@ _bfd_coff_reloc_link_order (bfd *output_bfd,
return TRUE;
}
+/* See _Microsoft Portable Executable and Common Object File Format
+ Specification_, section 5.5.3. Note that weak symbols without aux records
+ are a GNU extension.
+
+ FIXME: All weak externals are treated as having characteristic
+ IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY (1). These behave as per SVR4 ABI: A
+ library member will resolve a weak external only if a normal external causes
+ the library member to be linked. See also linker.c:
+ generic_link_check_archive_element. */
+
+static void _bfd_coff_relocate_weak_externals(struct coff_link_hash_entry *h,
+ bfd_vma *val)
+{
+ long aux_index = h->aux->x_sym.x_tagndx.l;
+ struct coff_tdata *cdata = h->auxbfd->tdata.coff_obj_data;
+ struct coff_link_hash_entry *h2 = cdata->sym_hashes[aux_index];
+ asection *sec;
+
+ if (!h2 || h2->root.type == bfd_link_hash_undefined)
+ {
+ *val = 0;
+ }
+ else
+ {
+ sec = h2->root.u.def.section;
+ *val = h2->root.u.def.value + sec->output_section->vma +
+ sec->output_offset;
+ }
+}
+
+
/* A basic reloc handling routine which may be used by processors with
simple relocs. */
@@ -3007,39 +3038,14 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd,
else if (h->root.type == bfd_link_hash_undefweak)
{
if (h->symbol_class == C_NT_WEAK && h->numaux == 1)
- {
- /* See _Microsoft Portable Executable and Common Object
- File Format Specification_, section 5.5.3.
- Note that weak symbols without aux records are a GNU
- extension.
- FIXME: All weak externals are treated as having
- characteristic IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY (1).
- These behave as per SVR4 ABI: A library member
- will resolve a weak external only if a normal
- external causes the library member to be linked.
- See also linker.c: generic_link_check_archive_element. */
- asection *sec;
- struct coff_link_hash_entry *h2 =
- h->auxbfd->tdata.coff_obj_data->sym_hashes[
- h->aux->x_sym.x_tagndx.l];
-
- if (!h2 || h2->root.type == bfd_link_hash_undefined)
- {
- sec = bfd_abs_section_ptr;
- val = 0;
- }
- else
- {
- sec = h2->root.u.def.section;
- val = h2->root.u.def.value
- + sec->output_section->vma + sec->output_offset;
- }
- }
+ _bfd_coff_relocate_weak_externals(h, &val);
else
/* This is a GNU extension. */
val = 0;
}
-
+ else if (h->root.type == bfd_link_hash_undefined &&
+ h->symbol_class == C_NT_WEAK && h->numaux == 1)
+ _bfd_coff_relocate_weak_externals(h, &val);
else if (! info->relocatable)
{
if (! ((*info->callbacks->undefined_symbol)
--
2.11.0