From bc03e2e40e51474f2244f5909f3e8f5a4cf60ab0 Mon Sep 17 00:00:00 2001 From: Octavian Purdila Date: Mon, 26 Oct 2015 15:57:35 +0200 Subject: [PATCH 3/3] Convert NT weak externals to locals This patch allows converting a weak external symbol to a local symbol by setting up its section and value to the ones of the alternate symbol. This is useful when we want to make only a few selected symbols visible (e.g. objcopy -G). The conversion is triggered when an NT weak external symbol has been marked with BSF_LOCAL. bfd/ 2015-10-22 Octavian Purdila * coffgen.c: add coff_nt_weak_to_local() that implements weak external to local symbol conversion * coffcode.h (coff_write_object_contents): call coff_nt_weak_to_local() * libcoff.h: add coff_nt_weak_to_local() declaration binutils/ 2015-10-26 Octavian Purdila * objcopy.c (filter_symbols): allow converting undefined weak symbols to local symbols for PE objects (as PE weak externals are implemented as undefined weak symbols) --- bfd/ChangeLog | 8 ++++++++ bfd/coffcode.h | 1 + bfd/coffgen.c | 43 +++++++++++++++++++++++++++++++++++++++++++ bfd/libcoff.h | 2 ++ binutils/ChangeLog | 6 ++++++ binutils/objcopy.c | 5 ++++- 6 files changed, 64 insertions(+), 1 deletion(-) diff --git binutils-2.28.orig/bfd/ChangeLog binutils-2.28/bfd/ChangeLog index 05cb3df..0a6765a 100644 --- binutils-2.28.orig/bfd/ChangeLog +++ binutils-2.28/bfd/ChangeLog @@ -1,4 +1,11 @@ 2017-04-29 octavian purdila + * coffgen.c: add coff_nt_weak_to_local() that implements weak + external to local symbol conversion + * coffcode.h (coff_write_object_contents): call + coff_nt_weak_to_local() + * libcoff.h: add coff_nt_weak_to_local() declaration + +2017-04-29 octavian purdila * cofflink.c (_bfd_coff_link_input_bfd): relocate AUX entries for weak externals when generating relocatable objects diff --git binutils-2.28.orig/bfd/coffcode.h binutils-2.28/bfd/coffcode.h index 2ef4e92..a8eba93 100644 --- binutils-2.28.orig/bfd/coffcode.h +++ binutils-2.28/bfd/coffcode.h @@ -4212,6 +4212,7 @@ coff_write_object_contents (bfd * abfd) { int firstundef; + coff_nt_weak_to_local(abfd); if (!coff_renumber_symbols (abfd, &firstundef)) return FALSE; coff_mangle_symbols (abfd); diff --git binutils-2.28.orig/bfd/coffgen.c binutils-2.28/bfd/coffgen.c index d2cc591..0b79745 100644 --- binutils-2.28.orig/bfd/coffgen.c +++ binutils-2.28/bfd/coffgen.c @@ -790,6 +790,49 @@ coff_renumber_symbols (bfd *bfd_ptr, int *first_undef) return TRUE; } +/* Transform weak externals to local symbols if requested (e.g. objcopy). */ +void coff_nt_weak_to_local(bfd *abfd) +{ + unsigned int symbol_count = bfd_get_symcount (abfd); + asymbol **symbol_ptr_ptr = abfd->outsymbols; + unsigned int symbol_index; + + for (symbol_index = 0; symbol_index < symbol_count; symbol_index++) + { + asymbol *symbol = symbol_ptr_ptr[symbol_index]; + coff_symbol_type *coff_symbol_ptr; + combined_entry_type *native; + struct internal_syment *sym; + + coff_symbol_ptr = coff_symbol_from (symbol); + if (!coff_symbol_ptr) + continue; + + native = coff_symbol_ptr->native; + if (!native) + continue; + + sym = &native->u.syment; + + if ((symbol->flags & BSF_LOCAL) && sym->n_sclass == C_NT_WEAK + && sym->n_numaux == 1) { + union internal_auxent *aux = &native[1].u.auxent; + struct internal_syment *wsym = &aux->x_sym.x_tagndx.p->u.syment; + + if (!wsym) { + symbol->flags &= BSF_LOCAL; + continue; + } + + symbol->flags &= ~BSF_WEAK; + symbol->value = wsym->n_value; + symbol->section = coff_section_from_bfd_index (abfd, wsym->n_scnum); + symbol->section->output_section = symbol->section; + sym->n_numaux = 0; + } + } +} + /* Run thorough the symbol table again, and fix it so that all pointers to entries are changed to the entries' index in the output symbol table. */ diff --git binutils-2.28.orig/bfd/libcoff.h binutils-2.28/bfd/libcoff.h index c93d152..1d7a0bf 100644 --- binutils-2.28.orig/bfd/libcoff.h +++ binutils-2.28/bfd/libcoff.h @@ -309,6 +309,8 @@ extern long coff_canonicalize_symtab (bfd *, asymbol **); extern int coff_count_linenumbers (bfd *); +extern void coff_nt_weak_to_local + (bfd *); extern bfd_boolean coff_renumber_symbols (bfd *, int *); extern void coff_mangle_symbols diff --git binutils-2.28.orig/binutils/ChangeLog binutils-2.28/binutils/ChangeLog index aa17468..e79dc05 100644 --- binutils-2.28.orig/binutils/ChangeLog +++ binutils-2.28/binutils/ChangeLog @@ -1,3 +1,9 @@ +2017-04-29 Octavian Purdila + + * objcopy.c (filter_symbols): allow converting undefined weak + symbols to local symbols for PE objects (as PE weak externals are + implemented as undefined weak symbols) + 2017-03-02 Tristan Gingold * configure: Regenerate. diff --git binutils-2.28.orig/binutils/objcopy.c binutils-2.28/binutils/objcopy.c index 2636ab4..9c888bb 100644 --- binutils-2.28.orig/binutils/objcopy.c +++ binutils-2.28/binutils/objcopy.c @@ -1549,7 +1549,10 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms, sym->flags |= BSF_WEAK; } - if (!undefined + /* We want to check even undefined weak symbols in the case of PE, + * since weak externals are classified as undefined. */ + if ((!undefined || (bfd_get_flavour (abfd) == bfd_target_coff_flavour && + CONST_STRNEQ ((abfd)->xvec->name, "pe"))) && (flags & (BSF_GLOBAL | BSF_WEAK)) && (is_specified_symbol (name, localize_specific_htab) || (htab_elements (keepglobal_specific_htab) != 0