mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-28 06:20:30 +00:00
PR ld/12365
bfd/ * elfcode.h (elf_slurp_symbol_table): Put common plugin IR symbols in their own common section. * elflink.c (elf_link_add_object_symbols): Likewise. * linker.c (generic_link_check_archive_element): Don't lose flags if common section is pre-existing. (_bfd_generic_link_add_one_symbol): Likewise. ld/ * ldfile.c (ldfile_try_open_bfd): Move code creating and switching to plugin IR BFD.. * ldmain.c (add_archive_element): ..and similar code here.. * plugin.c (plugin_maybe_claim): ..to here. New function. (plugin_call_claim_file): Make static. (asymbol_from_plugin_symbol): Set ELF st_shndx for common syms. (plugin_multiple_common): New function. (plugin_call_all_symbols_read): Hook in plugin_multiple_common. * plugin.h (plugin_call_claim_file): Don't declare. (plugin_maybe_claim): Declare.
This commit is contained in:
parent
24f58f47de
commit
02d002477b
@ -1,3 +1,13 @@
|
||||
2011-04-20 Alan Modra <amodra@gmail.com>
|
||||
|
||||
PR ld/12365
|
||||
* elfcode.h (elf_slurp_symbol_table): Put common plugin IR symbols
|
||||
in their own common section.
|
||||
* elflink.c (elf_link_add_object_symbols): Likewise.
|
||||
* linker.c (generic_link_check_archive_element): Don't lose flags
|
||||
if common section is pre-existing.
|
||||
(_bfd_generic_link_add_one_symbol): Likewise.
|
||||
|
||||
2011-04-20 Alan Modra <amodra@gmail.com>
|
||||
|
||||
PR ld/12365
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* ELF executable support for BFD.
|
||||
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
|
||||
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
|
||||
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
Written by Fred Fish @ Cygnus Support, from information published
|
||||
@ -1282,6 +1282,20 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic)
|
||||
else if (isym->st_shndx == SHN_COMMON)
|
||||
{
|
||||
sym->symbol.section = bfd_com_section_ptr;
|
||||
if ((abfd->flags & BFD_PLUGIN) != 0)
|
||||
{
|
||||
asection *xc = bfd_get_section_by_name (abfd, "COMMON");
|
||||
|
||||
if (xc == NULL)
|
||||
{
|
||||
flagword flags = (SEC_ALLOC | SEC_IS_COMMON | SEC_KEEP
|
||||
| SEC_EXCLUDE);
|
||||
xc = bfd_make_section_with_flags (abfd, "COMMON", flags);
|
||||
if (xc == NULL)
|
||||
goto error_return;
|
||||
}
|
||||
sym->symbol.section = xc;
|
||||
}
|
||||
/* Elf puts the alignment into the `value' field, and
|
||||
the size into the `size' field. BFD wants to see the
|
||||
size in the value field, and doesn't care (at the
|
||||
|
@ -3937,18 +3937,31 @@ error_free_dyn:
|
||||
goto error_free_vers;
|
||||
|
||||
if (isym->st_shndx == SHN_COMMON
|
||||
&& ELF_ST_TYPE (isym->st_info) == STT_TLS
|
||||
&& !info->relocatable)
|
||||
&& (abfd->flags & BFD_PLUGIN) != 0)
|
||||
{
|
||||
asection *xc = bfd_get_section_by_name (abfd, "COMMON");
|
||||
|
||||
if (xc == NULL)
|
||||
{
|
||||
flagword sflags = (SEC_ALLOC | SEC_IS_COMMON | SEC_KEEP
|
||||
| SEC_EXCLUDE);
|
||||
xc = bfd_make_section_with_flags (abfd, "COMMON", sflags);
|
||||
if (xc == NULL)
|
||||
goto error_free_vers;
|
||||
}
|
||||
sec = xc;
|
||||
}
|
||||
else if (isym->st_shndx == SHN_COMMON
|
||||
&& ELF_ST_TYPE (isym->st_info) == STT_TLS
|
||||
&& !info->relocatable)
|
||||
{
|
||||
asection *tcomm = bfd_get_section_by_name (abfd, ".tcommon");
|
||||
|
||||
if (tcomm == NULL)
|
||||
{
|
||||
tcomm = bfd_make_section_with_flags (abfd, ".tcommon",
|
||||
(SEC_ALLOC
|
||||
| SEC_IS_COMMON
|
||||
| SEC_LINKER_CREATED
|
||||
| SEC_THREAD_LOCAL));
|
||||
flagword sflags = (SEC_ALLOC | SEC_THREAD_LOCAL | SEC_IS_COMMON
|
||||
| SEC_LINKER_CREATED);
|
||||
tcomm = bfd_make_section_with_flags (abfd, ".tcommon", sflags);
|
||||
if (tcomm == NULL)
|
||||
goto error_free_vers;
|
||||
}
|
||||
|
10
bfd/linker.c
10
bfd/linker.c
@ -1296,7 +1296,7 @@ generic_link_check_archive_element (bfd *abfd,
|
||||
else
|
||||
h->u.c.p->section = bfd_make_section_old_way (symbfd,
|
||||
p->section->name);
|
||||
h->u.c.p->section->flags = SEC_ALLOC;
|
||||
h->u.c.p->section->flags |= SEC_ALLOC;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1756,13 +1756,13 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
|
||||
if (section == bfd_com_section_ptr)
|
||||
{
|
||||
h->u.c.p->section = bfd_make_section_old_way (abfd, "COMMON");
|
||||
h->u.c.p->section->flags = SEC_ALLOC;
|
||||
h->u.c.p->section->flags |= SEC_ALLOC;
|
||||
}
|
||||
else if (section->owner != abfd)
|
||||
{
|
||||
h->u.c.p->section = bfd_make_section_old_way (abfd,
|
||||
section->name);
|
||||
h->u.c.p->section->flags = SEC_ALLOC;
|
||||
h->u.c.p->section->flags |= SEC_ALLOC;
|
||||
}
|
||||
else
|
||||
h->u.c.p->section = section;
|
||||
@ -1803,13 +1803,13 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
|
||||
{
|
||||
h->u.c.p->section
|
||||
= bfd_make_section_old_way (abfd, "COMMON");
|
||||
h->u.c.p->section->flags = SEC_ALLOC;
|
||||
h->u.c.p->section->flags |= SEC_ALLOC;
|
||||
}
|
||||
else if (section->owner != abfd)
|
||||
{
|
||||
h->u.c.p->section
|
||||
= bfd_make_section_old_way (abfd, section->name);
|
||||
h->u.c.p->section->flags = SEC_ALLOC;
|
||||
h->u.c.p->section->flags |= SEC_ALLOC;
|
||||
}
|
||||
else
|
||||
h->u.c.p->section = section;
|
||||
|
14
ld/ChangeLog
14
ld/ChangeLog
@ -1,3 +1,17 @@
|
||||
2011-04-20 Alan Modra <amodra@gmail.com>
|
||||
|
||||
PR ld/12365
|
||||
* ldfile.c (ldfile_try_open_bfd): Move code creating and switching
|
||||
to plugin IR BFD..
|
||||
* ldmain.c (add_archive_element): ..and similar code here..
|
||||
* plugin.c (plugin_maybe_claim): ..to here. New function.
|
||||
(plugin_call_claim_file): Make static.
|
||||
(asymbol_from_plugin_symbol): Set ELF st_shndx for common syms.
|
||||
(plugin_multiple_common): New function.
|
||||
(plugin_call_all_symbols_read): Hook in plugin_multiple_common.
|
||||
* plugin.h (plugin_call_claim_file): Don't declare.
|
||||
(plugin_maybe_claim): Declare.
|
||||
|
||||
2011-04-20 Alan Modra <amodra@gmail.com>
|
||||
|
||||
PR ld/12365
|
||||
|
28
ld/ldfile.c
28
ld/ldfile.c
@ -1,6 +1,7 @@
|
||||
/* Linker file opening and searching.
|
||||
Copyright 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001, 2002,
|
||||
2003, 2004, 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Binutils.
|
||||
|
||||
@ -320,35 +321,12 @@ success:
|
||||
if (fd >= 0)
|
||||
{
|
||||
struct ld_plugin_input_file file;
|
||||
int claimed = 0;
|
||||
|
||||
file.name = attempt;
|
||||
file.offset = 0;
|
||||
file.filesize = lseek (fd, 0, SEEK_END);
|
||||
file.fd = fd;
|
||||
/* We create a dummy BFD, initially empty, to house
|
||||
whatever symbols the plugin may want to add. */
|
||||
file.handle = plugin_get_ir_dummy_bfd (attempt, entry->the_bfd);
|
||||
if (plugin_call_claim_file (&file, &claimed))
|
||||
einfo (_("%P%F: %s: plugin reported error claiming file\n"),
|
||||
plugin_error_plugin ());
|
||||
/* fd belongs to us, not the plugin; but we don't need it. */
|
||||
close (fd);
|
||||
if (claimed)
|
||||
{
|
||||
/* Discard the real file's BFD and substitute the dummy one. */
|
||||
bfd_close (entry->the_bfd);
|
||||
entry->the_bfd = file.handle;
|
||||
entry->claimed = TRUE;
|
||||
bfd_make_readable (entry->the_bfd);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If plugin didn't claim the file, we don't need the dummy
|
||||
bfd. Can't avoid speculatively creating it, alas. */
|
||||
bfd_close_all_done (file.handle);
|
||||
entry->claimed = FALSE;
|
||||
}
|
||||
plugin_maybe_claim (&file, entry);
|
||||
}
|
||||
}
|
||||
#endif /* ENABLE_PLUGINS */
|
||||
|
23
ld/ldmain.c
23
ld/ldmain.c
@ -813,7 +813,7 @@ add_archive_element (struct bfd_link_info *info,
|
||||
if (fd >= 0)
|
||||
{
|
||||
struct ld_plugin_input_file file;
|
||||
int claimed = 0;
|
||||
|
||||
/* Offset and filesize must refer to the individual archive
|
||||
member, not the whole file, and must exclude the header.
|
||||
Fortunately for us, that is how the data is stored in the
|
||||
@ -822,29 +822,12 @@ add_archive_element (struct bfd_link_info *info,
|
||||
file.offset = abfd->origin;
|
||||
file.filesize = arelt_size (abfd);
|
||||
file.fd = fd;
|
||||
/* We create a dummy BFD, initially empty, to house
|
||||
whatever symbols the plugin may want to add. */
|
||||
file.handle = plugin_get_ir_dummy_bfd (abfd->filename, abfd);
|
||||
if (plugin_call_claim_file (&file, &claimed))
|
||||
einfo (_("%P%F: %s: plugin reported error claiming file\n"),
|
||||
plugin_error_plugin ());
|
||||
/* fd belongs to us, not the plugin; but we don't need it. */
|
||||
close (fd);
|
||||
if (claimed)
|
||||
plugin_maybe_claim (&file, input);
|
||||
if (input->claimed)
|
||||
{
|
||||
/* Substitute the dummy BFD. */
|
||||
input->the_bfd = file.handle;
|
||||
input->claimed = TRUE;
|
||||
input->claim_archive = TRUE;
|
||||
bfd_make_readable (input->the_bfd);
|
||||
*subsbfd = input->the_bfd;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Abandon the dummy BFD. */
|
||||
bfd_close_all_done (file.handle);
|
||||
input->claimed = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* ENABLE_PLUGINS */
|
||||
|
68
ld/plugin.c
68
ld/plugin.c
@ -140,6 +140,11 @@ static bfd_boolean plugin_multiple_definition (struct bfd_link_info *info,
|
||||
bfd *nbfd,
|
||||
asection *nsec,
|
||||
bfd_vma nval);
|
||||
static bfd_boolean plugin_multiple_common (struct bfd_link_info *info,
|
||||
struct bfd_link_hash_entry *h,
|
||||
bfd *nbfd,
|
||||
enum bfd_link_hash_type ntype,
|
||||
bfd_vma nsize);
|
||||
|
||||
#if !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H)
|
||||
|
||||
@ -312,7 +317,10 @@ asymbol_from_plugin_symbol (bfd *abfd, asymbol *asym,
|
||||
asym->value = ldsym->size;
|
||||
/* For ELF targets, set alignment of common symbol to 1. */
|
||||
if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
|
||||
((elf_symbol_type *) asym)->internal_elf_sym.st_value = 1;
|
||||
{
|
||||
((elf_symbol_type *) asym)->internal_elf_sym.st_shndx = SHN_COMMON;
|
||||
((elf_symbol_type *) asym)->internal_elf_sym.st_value = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -812,7 +820,7 @@ plugin_load_plugins (void)
|
||||
}
|
||||
|
||||
/* Call 'claim file' hook for all plugins. */
|
||||
int
|
||||
static int
|
||||
plugin_call_claim_file (const struct ld_plugin_input_file *file, int *claimed)
|
||||
{
|
||||
plugin_t *curplug = plugins_list;
|
||||
@ -835,6 +843,42 @@ plugin_call_claim_file (const struct ld_plugin_input_file *file, int *claimed)
|
||||
return plugin_error_p () ? -1 : 0;
|
||||
}
|
||||
|
||||
void
|
||||
plugin_maybe_claim (struct ld_plugin_input_file *file,
|
||||
lang_input_statement_type *entry)
|
||||
{
|
||||
int claimed = 0;
|
||||
|
||||
/* We create a dummy BFD, initially empty, to house whatever symbols
|
||||
the plugin may want to add. */
|
||||
file->handle = plugin_get_ir_dummy_bfd (entry->the_bfd->filename,
|
||||
entry->the_bfd);
|
||||
if (plugin_call_claim_file (file, &claimed))
|
||||
einfo (_("%P%F: %s: plugin reported error claiming file\n"),
|
||||
plugin_error_plugin ());
|
||||
/* fd belongs to us, not the plugin; but we don't need it. */
|
||||
close (file->fd);
|
||||
if (claimed)
|
||||
{
|
||||
/* Discard the real file's BFD and substitute the dummy one. */
|
||||
|
||||
/* BFD archive handling caches elements so we can't call
|
||||
bfd_close for archives. */
|
||||
if (entry->the_bfd->my_archive == NULL)
|
||||
bfd_close (entry->the_bfd);
|
||||
entry->the_bfd = file->handle;
|
||||
entry->claimed = TRUE;
|
||||
bfd_make_readable (entry->the_bfd);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If plugin didn't claim the file, we don't need the dummy bfd.
|
||||
Can't avoid speculatively creating it, alas. */
|
||||
bfd_close_all_done (file->handle);
|
||||
entry->claimed = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Call 'all symbols read' hook for all plugins. */
|
||||
int
|
||||
plugin_call_all_symbols_read (void)
|
||||
@ -845,6 +889,7 @@ plugin_call_all_symbols_read (void)
|
||||
no_more_claiming = TRUE;
|
||||
|
||||
plugin_callbacks.multiple_definition = &plugin_multiple_definition;
|
||||
plugin_callbacks.multiple_common = &plugin_multiple_common;
|
||||
|
||||
while (curplug)
|
||||
{
|
||||
@ -955,3 +1000,22 @@ plugin_multiple_definition (struct bfd_link_info *info,
|
||||
|
||||
return (*orig_callbacks->multiple_definition) (info, h, nbfd, nsec, nval);
|
||||
}
|
||||
|
||||
static bfd_boolean
|
||||
plugin_multiple_common (struct bfd_link_info *info,
|
||||
struct bfd_link_hash_entry *h,
|
||||
bfd *nbfd, enum bfd_link_hash_type ntype, bfd_vma nsize)
|
||||
{
|
||||
if (h->type == bfd_link_hash_common
|
||||
&& is_ir_dummy_bfd (h->u.c.p->section->owner)
|
||||
&& ntype == bfd_link_hash_common
|
||||
&& !is_ir_dummy_bfd (nbfd))
|
||||
{
|
||||
/* Arrange to have it replaced. */
|
||||
ASSERT (nsize != 0);
|
||||
h->u.c.size = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return (*orig_callbacks->multiple_common) (info, h, nbfd, ntype, nsize);
|
||||
}
|
||||
|
@ -50,8 +50,8 @@ extern int plugin_load_plugins (void);
|
||||
extern const char *plugin_error_plugin (void);
|
||||
|
||||
/* Call 'claim file' hook for all plugins. */
|
||||
extern int plugin_call_claim_file (const struct ld_plugin_input_file *file,
|
||||
int *claimed);
|
||||
extern void plugin_maybe_claim (struct ld_plugin_input_file *,
|
||||
lang_input_statement_type *);
|
||||
|
||||
/* Call 'all symbols read' hook for all plugins. */
|
||||
extern int plugin_call_all_symbols_read (void);
|
||||
|
Loading…
Reference in New Issue
Block a user