mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-05 15:15:42 +00:00
bfd/COFF: propagate function size when copying/linking ELF objects
While COFF, unlike ELF, doesn't have a generic way to express symbol size, there is a means to do so for functions. When inputs are ELF, propagate function sizes, including the fact that a symbol denotes a function, to the output's symbol table. Note that this requires hackery (cross-object-format processing) in two places - when linking, global symbols are entered into a global hash table, and hence relevant information needs to be updated there in that case, while otherwise the original symbol structures can be consulted. For the setting of ->u.syment.n_type the later writing of the field to literal 0 needs to be dropped from coff_write_alien_symbol(). It was redundant anyway with an earlier write of the field using C_NUL.
This commit is contained in:
@@ -42,6 +42,7 @@
|
||||
#include "libbfd.h"
|
||||
#include "coff/internal.h"
|
||||
#include "libcoff.h"
|
||||
#include "elf-bfd.h"
|
||||
#include "hashtab.h"
|
||||
|
||||
/* Extract a long section name at STRINDEX and copy it to the bfd objstack.
|
||||
@@ -1270,9 +1271,24 @@ coff_write_alien_symbol (bfd *abfd,
|
||||
if (c != (coff_symbol_type *) NULL)
|
||||
native->u.syment.n_flags = bfd_asymbol_bfd (&c->symbol)->flags;
|
||||
}
|
||||
|
||||
const elf_symbol_type *elfsym = elf_symbol_from (symbol);
|
||||
if (elfsym
|
||||
&& (symbol->flags & BSF_FUNCTION)
|
||||
&& elfsym->internal_elf_sym.st_size)
|
||||
{
|
||||
/* coff_data (abfd)->local_n_btshft is what ought to be used here,
|
||||
just that it's set only when reading in COFF objects. */
|
||||
native->u.syment.n_type = DT_FCN << 4;
|
||||
native->u.syment.n_numaux = 1;
|
||||
native[1].u.auxent.x_sym.x_misc.x_fsize
|
||||
= elfsym->internal_elf_sym.st_size;
|
||||
/* FIXME .u.auxent.x_sym.x_fcnary.x_fcn.x_endndx would better also
|
||||
be set, which would require updating the field once the next
|
||||
function is seen. */
|
||||
}
|
||||
}
|
||||
|
||||
native->u.syment.n_type = 0;
|
||||
if (symbol->flags & BSF_FILE)
|
||||
native->u.syment.n_sclass = C_FILE;
|
||||
else if (symbol->flags & BSF_LOCAL)
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "libbfd.h"
|
||||
#include "coff/internal.h"
|
||||
#include "libcoff.h"
|
||||
#include "elf-bfd.h"
|
||||
#include "safe-ctype.h"
|
||||
|
||||
static bool coff_link_add_object_symbols (bfd *, struct bfd_link_info *);
|
||||
@@ -931,14 +932,52 @@ _bfd_coff_final_link (bfd *abfd,
|
||||
bfd_vma written = 0;
|
||||
bool rewrite = false;
|
||||
|
||||
if (! (sym->flags & BSF_LOCAL)
|
||||
|| (sym->flags & (BSF_SECTION_SYM | BSF_DEBUGGING_RELOC
|
||||
if ((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;
|
||||
|
||||
if (! (sym->flags & BSF_LOCAL))
|
||||
{
|
||||
/* For ELF symbols try to represent their function-ness and
|
||||
size, if available. */
|
||||
if (! (sym->flags & BSF_FUNCTION))
|
||||
continue;
|
||||
|
||||
const elf_symbol_type *elfsym = elf_symbol_from (sym);
|
||||
if (!elfsym)
|
||||
continue;
|
||||
|
||||
struct coff_link_hash_entry *hent
|
||||
= (struct coff_link_hash_entry *) bfd_hash_lookup
|
||||
(&info->hash->table, bfd_asymbol_name (sym),
|
||||
false, false);
|
||||
if (!hent)
|
||||
continue;
|
||||
|
||||
/* coff_data (abfd)->local_n_btshft is what ought to be used
|
||||
here, just that it's set only when reading in COFF
|
||||
objects. */
|
||||
hent->type = DT_FCN << 4;
|
||||
if (!elfsym->internal_elf_sym.st_size)
|
||||
continue;
|
||||
|
||||
hent->aux = bfd_zalloc (abfd, sizeof (*hent->aux));
|
||||
if (!hent->aux)
|
||||
continue;
|
||||
|
||||
hent->numaux = 1;
|
||||
hent->aux->x_sym.x_misc.x_fsize
|
||||
= elfsym->internal_elf_sym.st_size;
|
||||
/* FIXME ->x_sym.x_fcnary.x_fcn.x_endndx would better
|
||||
also be set, yet that would likely need to happen
|
||||
elsewhere anyway. */
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* See if we are discarding symbols with this name. */
|
||||
if ((flaginfo.info->strip == strip_some
|
||||
&& (bfd_hash_lookup (flaginfo.info->keep_hash,
|
||||
|
||||
Reference in New Issue
Block a user