This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Ping: [PATCH] COFF/PE: insert local symbols from foreign input objects into output executable
- From: "Jan Beulich" <JBeulich at suse dot com>
- To: <dave dot korn dot cygwin at gmail dot com>,<dj at redhat dot com>
- Cc: <binutils at sourceware dot org>
- Date: Tue, 11 Oct 2011 07:48:05 +0100
- Subject: Ping: [PATCH] COFF/PE: insert local symbols from foreign input objects into output executable
- References: <4E8328950200007800058310@nat28.tlf.novell.com>
There are no arch-independent PE/COFF maintainers listed, so you being
the ix86 ones are getting closest.
Thanks, Jan
>>> On 28.09.11 at 14:00, "Jan Beulich" <JBeulich@suse.com> wrote:
> Building EFI binaries, particularly larger ones (like e.g. Xen does), on
> Linux
> (where relocatable objects are in ELF format) so far led to all local (aka
> static) symbols to be discarded, making debugging quite a bit more difficult
> (like Linux, Xen builds an internal symbol lookup table from nm output
> generated on the binary produced by an earlier linking pass). Therefore,
> this
> patch arranges to insert all (relevant) local symbols from non-COFF objects
> into the final executable's symbol table between those coming from COFF
> input
> files and the global ones.
>
> bfd/
> 2011-09-28 Jan Beulich <jbeulich@suse.com>
>
> * coffgen.c (coff_write_alien_symbol): Make public. Add 'struct
> internal_syment *' parameter. Extend 'dummy' to an array with two
> elements. Set n_numaux early. Handle BSF_FILE.
> (coff_write_symbols): Pass NULL as new third argument to
> coff_write_alien_symbol().
> * cofflink.c (_bfd_coff_final_link): Don't use COFF-specific
> obj_raw_syment_count() on non-COFF input BFD. Insert local symbols
> from non-COFF input BFDs.
> * libcoff-in.h (coff_write_alien_symbol): Declare.
> * libcoff.h (coff_write_alien_symbol): Re-generate.
>
> --- 2011-09-28/bfd/coffgen.c 2011-09-16 08:37:33.000000000 +0200
> +++ 2011-09-28/bfd/coffgen.c 2011-09-28 12:01:54.000000000 +0200
> @@ -983,23 +983,26 @@ coff_write_symbol (bfd *abfd,
> file originally. This symbol may have been created by the linker,
> or we may be linking a non COFF file to a COFF file. */
>
> -static bfd_boolean
> +bfd_boolean
> coff_write_alien_symbol (bfd *abfd,
> asymbol *symbol,
> + struct internal_syment *isym,
> bfd_vma *written,
> bfd_size_type *string_size_p,
> asection **debug_string_section_p,
> bfd_size_type *debug_string_size_p)
> {
> combined_entry_type *native;
> - combined_entry_type dummy;
> + combined_entry_type dummy[2];
> asection *output_section = symbol->section->output_section
> ? symbol->section->output_section
> : symbol->section;
> + bfd_boolean ret;
>
> - native = &dummy;
> + native = dummy;
> native->u.syment.n_type = T_NULL;
> native->u.syment.n_flags = 0;
> + native->u.syment.n_numaux = 0;
> if (bfd_is_und_section (symbol->section))
> {
> native->u.syment.n_scnum = N_UNDEF;
> @@ -1010,6 +1013,11 @@ coff_write_alien_symbol (bfd *abfd,
> native->u.syment.n_scnum = N_UNDEF;
> native->u.syment.n_value = symbol->value;
> }
> + else if (symbol->flags & BSF_FILE)
> + {
> + native->u.syment.n_scnum = N_DEBUG;
> + native->u.syment.n_numaux = 1;
> + }
> else if (symbol->flags & BSF_DEBUGGING)
> {
> /* There isn't much point to writing out a debugging symbol
> @@ -1017,6 +1025,8 @@ coff_write_alien_symbol (bfd *abfd,
> format. So, we just ignore them. We must clobber the symbol
> name to keep it from being put in the string table. */
> symbol->name = "";
> + if (isym != NULL)
> + memset (isym, 0, sizeof(*isym));
> return TRUE;
> }
> else
> @@ -1037,16 +1047,20 @@ coff_write_alien_symbol (bfd *abfd,
> }
>
> native->u.syment.n_type = 0;
> - if (symbol->flags & BSF_LOCAL)
> + if (symbol->flags & BSF_FILE)
> + native->u.syment.n_sclass = C_FILE;
> + else if (symbol->flags & BSF_LOCAL)
> native->u.syment.n_sclass = C_STAT;
> else if (symbol->flags & BSF_WEAK)
> native->u.syment.n_sclass = obj_pe (abfd) ? C_NT_WEAK : C_WEAKEXT;
> else
> native->u.syment.n_sclass = C_EXT;
> - native->u.syment.n_numaux = 0;
>
> - return coff_write_symbol (abfd, symbol, native, written, string_size_p,
> - debug_string_section_p, debug_string_size_p);
> + ret = coff_write_symbol (abfd, symbol, native, written, string_size_p,
> + debug_string_section_p, debug_string_size_p);
> + if (isym != NULL)
> + *isym = native->u.syment;
> + return ret;
> }
>
> /* Write a native symbol to a COFF file. */
> @@ -1153,8 +1167,8 @@ coff_write_symbols (bfd *abfd)
> if (c_symbol == (coff_symbol_type *) NULL
> || c_symbol->native == (combined_entry_type *) NULL)
> {
> - if (!coff_write_alien_symbol (abfd, symbol, &written, &string_size,
> - &debug_string_section,
> + if (!coff_write_alien_symbol (abfd, symbol, NULL, &written,
> + &string_size, &debug_string_section,
> &debug_string_size))
> return FALSE;
> }
> --- 2011-09-28/bfd/cofflink.c 2011-09-16 08:37:33.000000000 +0200
> +++ 2011-09-28/bfd/cofflink.c 2011-09-28 12:01:54.000000000 +0200
> @@ -866,7 +866,7 @@ _bfd_coff_final_link (bfd *abfd,
> size_t sz;
>
> sub->output_has_begun = FALSE;
> - sz = obj_raw_syment_count (sub);
> + sz = bfd_family_coff (sub) ? obj_raw_syment_count (sub) : 2;
> if (sz > max_sym_count)
> max_sym_count = sz;
> }
> @@ -943,6 +943,92 @@ _bfd_coff_final_link (bfd *abfd,
> }
> }
>
> + if (finfo.info->strip != strip_all && finfo.info->discard != discard_all)
> + {
> + /* Add local symbols from foreign inputs. */
> + for(sub = info->input_bfds; sub != NULL; sub = sub->link_next)
> + {
> + unsigned int i;
> +
> + if (bfd_family_coff (sub) || ! bfd_get_outsymbols (sub))
> + continue;
> + for (i = 0; i < bfd_get_symcount (sub); ++i)
> + {
> + asymbol *sym = bfd_get_outsymbols (sub) [i];
> + file_ptr pos;
> + struct internal_syment isym;
> + bfd_size_type string_size = 0;
> + bfd_vma written = 0;
> + bfd_boolean rewrite = FALSE;
> +
> + if (! (sym->flags & BSF_LOCAL)
> + || (sym->flags & (BSF_SECTION_SYM | BSF_DEBUGGING_RELOC
> + | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC
> + | BSF_SYNTHETIC))
> + || ((sym->flags & BSF_DEBUGGING)
> + && ! (sym->flags & BSF_FILE)))
> + continue;
> +
> + /* See if we are discarding symbols with this name. */
> + if ((finfo.info->strip == strip_some
> + && (bfd_hash_lookup (finfo.info->keep_hash,
> + bfd_asymbol_name(sym), FALSE, FALSE)
> + == NULL))
> + || (((finfo.info->discard == discard_sec_merge
> + && (bfd_get_section (sym)->flags & SEC_MERGE)
> + && ! finfo.info->relocatable)
> + || finfo.info->discard == discard_l)
> + && bfd_is_local_label_name (sub, bfd_asymbol_name(sym))))
> + continue;
> +
> + pos = obj_sym_filepos (abfd) + obj_raw_syment_count (abfd)
> + * symesz;
> + if (bfd_seek (abfd, pos, SEEK_SET) != 0)
> + goto error_return;
> + if (! coff_write_alien_symbol(abfd, sym, &isym, &written,
> + &string_size, NULL, NULL))
> + goto error_return;
> +
> + if (string_size)
> + {
> + bfd_boolean hash = ! (abfd->flags & BFD_TRADITIONAL_FORMAT);
> + bfd_size_type indx;
> +
> + indx = _bfd_stringtab_add (finfo.strtab,
> + bfd_asymbol_name (sym), hash,
> + FALSE);
> + if (indx == (bfd_size_type) -1)
> + goto error_return;
> + isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx;
> + bfd_coff_swap_sym_out (abfd, &isym, finfo.outsyms);
> + rewrite = TRUE;
> + }
> +
> + if (isym.n_sclass == C_FILE)
> + {
> + if (finfo.last_file_index != -1)
> + {
> + finfo.last_file.n_value = obj_raw_syment_count (abfd);
> + bfd_coff_swap_sym_out (abfd, &finfo.last_file,
> + finfo.outsyms);
> + pos = obj_sym_filepos (abfd) + finfo.last_file_index
> + * symesz;
> + rewrite = TRUE;
> + }
> + finfo.last_file_index = obj_raw_syment_count (abfd);
> + finfo.last_file = isym;
> + }
> +
> + if (rewrite
> + && (bfd_seek (abfd, pos, SEEK_SET) != 0
> + || bfd_bwrite (finfo.outsyms, symesz, abfd) != symesz))
> + goto error_return;
> +
> + obj_raw_syment_count (abfd) += written;
> + }
> + }
> + }
> +
> if (! bfd_coff_final_link_postscript (abfd, & finfo))
> goto error_return;
>
> --- 2011-09-28/bfd/libcoff-in.h 2011-09-16 08:37:39.000000000 +0200
> +++ 2011-09-28/bfd/libcoff-in.h 2011-09-28 12:01:54.000000000 +0200
> @@ -318,6 +318,9 @@ extern void coff_mangle_symbols
> (bfd *);
> extern bfd_boolean coff_write_symbols
> (bfd *);
> +extern bfd_boolean coff_write_alien_symbol
> + (bfd *, asymbol *, struct internal_syment *, bfd_vma *,
> + bfd_size_type *, asection **, bfd_size_type *);
> extern bfd_boolean coff_write_linenumbers
> (bfd *);
> extern alent *coff_get_lineno
> --- 2011-09-28/bfd/libcoff.h 2011-09-16 08:37:39.000000000 +0200
> +++ 2011-09-28/bfd/libcoff.h 2011-09-28 12:01:54.000000000 +0200
> @@ -322,6 +322,9 @@ extern void coff_mangle_symbols
> (bfd *);
> extern bfd_boolean coff_write_symbols
> (bfd *);
> +extern bfd_boolean coff_write_alien_symbol
> + (bfd *, asymbol *, struct internal_syment *, bfd_vma *,
> + bfd_size_type *, asection **, bfd_size_type *);
> extern bfd_boolean coff_write_linenumbers
> (bfd *);
> extern alent *coff_get_lineno