Set my_archive for thin archives

LTO plugin support in plugin_maybe_claim wants to close the IR bfd
after replacing it with the recompiled object, but can't do so for
archive elements due to various pointers that access the archive bfd.
Thin archives have the same problem.  They too cannot have their
element bfds closed.

	PR ld/20241
bfd/
	* archive.c (open_nested_file): Set my_archive.
	* bfd.c (_bfd_default_error_handler <%B>): Exclude archive file name
	for thin archives.
	* bfdio.c (bfd_tell): Don't adjust origin for thin archives.
	(bfd_seek): Likewise.
	* bfdwin.c (bfd_get_file_window): Likewise.
	* cache.c (cache_bmmap): Likewise.
	(bfd_cache_lookup_worker): Don't look in my_archive for thin archives.
	* mach-o.c (bfd_mach_o_follow_dsym): Don't open my_archive for
	thin archives.
	* plugin.c (try_claim): Likewise.
	* xcofflink.c (xcoff_link_add_dynamic_symbols): Use import path of
	file within thin archive, not the archive.
binutils/
	* bucomm.c (bfd_get_archive_filename): Return file name within thin
	archive.
ld/
	* ldmain.c (add_archive_element): Just print file name of file within
	thin archives.
	* ldmisc.c (vfinfo): Likewise.
	* plugin.c (plugin_object_p): Open file within thin archives.
	(plugin_maybe_claim): Expand comment.
This commit is contained in:
Alan Modra 2016-06-14 13:12:00 +09:30
parent 57bc0e78e9
commit b0cffb4767
15 changed files with 66 additions and 19 deletions

View File

@ -1,3 +1,20 @@
2016-06-14 Alan Modra <amodra@gmail.com>
PR ld/20241
* archive.c (open_nested_file): Set my_archive.
* bfd.c (_bfd_default_error_handler <%B>): Exclude archive file name
for thin archives.
* bfdio.c (bfd_tell): Don't adjust origin for thin archives.
(bfd_seek): Likewise.
* bfdwin.c (bfd_get_file_window): Likewise.
* cache.c (cache_bmmap): Likewise.
(bfd_cache_lookup_worker): Don't look in my_archive for thin archives.
* mach-o.c (bfd_mach_o_follow_dsym): Don't open my_archive for
thin archives.
* plugin.c (try_claim): Likewise.
* xcofflink.c (xcoff_link_add_dynamic_symbols): Use import path of
file within thin archive, not the archive.
2016-06-13 H.J. Lu <hongjiu.lu@intel.com>
PR ld/20244

View File

@ -392,6 +392,7 @@ open_nested_file (const char *filename, bfd *archive)
{
n_bfd->lto_output = archive->lto_output;
n_bfd->no_export = archive->no_export;
n_bfd->my_archive = archive;
}
return n_bfd;
}

View File

@ -703,7 +703,8 @@ _bfd_default_error_handler (const char *fmt, ...)
if (abfd == NULL)
/* Invoking %B with a null bfd pointer is an internal error. */
abort ();
else if (abfd->my_archive)
else if (abfd->my_archive
&& !bfd_is_thin_archive (abfd->my_archive))
snprintf (bufp, avail, "%s(%s)",
abfd->my_archive->filename, abfd->filename);
else

View File

@ -234,7 +234,8 @@ bfd_tell (bfd *abfd)
bfd *parent_bfd = abfd;
ptr = abfd->iovec->btell (abfd);
while (parent_bfd->my_archive != NULL)
while (parent_bfd->my_archive != NULL
&& !bfd_is_thin_archive (parent_bfd->my_archive))
{
ptr -= parent_bfd->origin;
parent_bfd = parent_bfd->my_archive;
@ -289,7 +290,7 @@ bfd_seek (bfd *abfd, file_ptr position, int direction)
if (direction == SEEK_CUR && position == 0)
return 0;
if (abfd->format != bfd_archive && abfd->my_archive == 0)
if (abfd->my_archive == NULL || bfd_is_thin_archive (abfd->my_archive))
{
if (direction == SEEK_SET && (bfd_vma) position == abfd->where)
return 0;
@ -314,7 +315,8 @@ bfd_seek (bfd *abfd, file_ptr position, int direction)
{
bfd *parent_bfd = abfd;
while (parent_bfd->my_archive != NULL)
while (parent_bfd->my_archive != NULL
&& !bfd_is_thin_archive (parent_bfd->my_archive))
{
file_position += parent_bfd->origin;
parent_bfd = parent_bfd->my_archive;

View File

@ -144,7 +144,8 @@ bfd_get_file_window (bfd *abfd,
int fd;
/* Find the real file and the real offset into it. */
while (abfd->my_archive != NULL)
while (abfd->my_archive != NULL
&& !bfd_is_thin_archive (abfd->my_archive))
{
offset += abfd->origin;
abfd = abfd->my_archive;

View File

@ -241,7 +241,8 @@ bfd_cache_lookup_worker (bfd *abfd, enum cache_flag flag)
if ((abfd->flags & BFD_IN_MEMORY) != 0)
abort ();
while (abfd->my_archive)
while (abfd->my_archive != NULL
&& !bfd_is_thin_archive (abfd->my_archive))
abfd = abfd->my_archive;
if (abfd->iostream != NULL)
@ -466,7 +467,8 @@ cache_bmmap (struct bfd *abfd ATTRIBUTE_UNUSED,
pagesize_m1 = getpagesize () - 1;
/* Handle archive members. */
if (abfd->my_archive != NULL)
if (abfd->my_archive != NULL
&& !bfd_is_thin_archive (abfd->my_archive))
offset += abfd->origin;
/* Align. */

View File

@ -5708,7 +5708,7 @@ bfd_mach_o_follow_dsym (bfd *abfd)
if (abfd == NULL || bfd_get_flavour (abfd) != bfd_target_mach_o_flavour)
return NULL;
if (abfd->my_archive)
if (abfd->my_archive && !bfd_is_thin_archive (abfd->my_archive))
base_bfd = abfd->my_archive;
/* BFD may have been opened from a stream. */
if (base_bfd->filename == NULL)

View File

@ -167,7 +167,7 @@ try_claim (bfd *abfd)
file.name = abfd->filename;
if (abfd->my_archive)
if (abfd->my_archive && !bfd_is_thin_archive (abfd->my_archive))
{
iobfd = abfd->my_archive;
file.offset = abfd->origin;
@ -185,7 +185,7 @@ try_claim (bfd *abfd)
file.fd = fileno ((FILE *) iobfd->iostream);
if (!abfd->my_archive)
if (!abfd->my_archive || bfd_is_thin_archive (abfd->my_archive))
{
struct stat stat_buf;
if (fstat (file.fd, &stat_buf))

View File

@ -997,7 +997,7 @@ xcoff_link_add_dynamic_symbols (bfd *abfd, struct bfd_link_info *info)
return FALSE;
n->next = NULL;
if (abfd->my_archive == NULL)
if (abfd->my_archive == NULL || bfd_is_thin_archive (abfd->my_archive))
{
if (!bfd_xcoff_split_import_path (abfd, abfd->filename,
&n->path, &n->file))

View File

@ -1,3 +1,9 @@
2016-06-14 Alan Modra <amodra@gmail.com>
PR ld/20241
* bucomm.c (bfd_get_archive_filename): Return file name within thin
archive.
2016-06-02 Nick Clifton <nickc@redhat.com>
PR 20089

View File

@ -605,7 +605,8 @@ bfd_get_archive_filename (const bfd *abfd)
assert (abfd != NULL);
if (!abfd->my_archive)
if (abfd->my_archive == NULL
|| bfd_is_thin_archive (abfd->my_archive))
return bfd_get_filename (abfd);
needed = (strlen (bfd_get_filename (abfd->my_archive))

View File

@ -1,3 +1,12 @@
2016-06-14 Alan Modra <amodra@gmail.com>
PR ld/20241
* ldmain.c (add_archive_element): Just print file name of file within
thin archives.
* ldmisc.c (vfinfo): Likewise.
* plugin.c (plugin_object_p): Open file within thin archives.
(plugin_maybe_claim): Expand comment.
2016-06-13 H.J. Lu <hongjiu.lu@intel.com>
PR ld/20244

View File

@ -865,7 +865,8 @@ add_archive_element (struct bfd_link_info *info,
header_printed = TRUE;
}
if (bfd_my_archive (abfd) == NULL)
if (bfd_my_archive (abfd) == NULL
|| bfd_is_thin_archive (bfd_my_archive (abfd)))
{
minfo ("%s", bfd_get_filename (abfd));
len = strlen (bfd_get_filename (abfd));

View File

@ -201,7 +201,8 @@ vfinfo (FILE *fp, const char *fmt, va_list arg, bfd_boolean is_warning)
if (abfd == NULL)
fprintf (fp, "%s generated", program_name);
else if (abfd->my_archive)
else if (abfd->my_archive != NULL
&& !bfd_is_thin_archive (abfd->my_archive))
fprintf (fp, "%s(%s)", abfd->my_archive->filename,
abfd->filename);
else
@ -230,11 +231,13 @@ vfinfo (FILE *fp, const char *fmt, va_list arg, bfd_boolean is_warning)
lang_input_statement_type *i;
i = va_arg (arg, lang_input_statement_type *);
if (bfd_my_archive (i->the_bfd) != NULL)
if (bfd_my_archive (i->the_bfd) != NULL
&& !bfd_is_thin_archive (bfd_my_archive (i->the_bfd)))
fprintf (fp, "(%s)",
bfd_get_filename (bfd_my_archive (i->the_bfd)));
fprintf (fp, "%s", i->local_sym_name);
if (bfd_my_archive (i->the_bfd) == NULL
if ((bfd_my_archive (i->the_bfd) == NULL
|| bfd_is_thin_archive (bfd_my_archive (i->the_bfd)))
&& filename_cmp (i->local_sym_name, i->filename) != 0)
fprintf (fp, " (%s)", i->filename);
}

View File

@ -1089,7 +1089,8 @@ plugin_object_p (bfd *ibfd)
return NULL;
}
inarchive = bfd_my_archive (ibfd) != NULL;
inarchive = (bfd_my_archive (ibfd) != NULL
&& !bfd_is_thin_archive (bfd_my_archive (ibfd)));
name = inarchive ? bfd_my_archive (ibfd)->filename : ibfd->filename;
fd = open (name, O_RDONLY | O_BINARY);
@ -1201,8 +1202,10 @@ plugin_maybe_claim (lang_input_statement_type *entry)
/* 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. */
/* We can't call bfd_close on archives. BFD archive handling
caches elements, and add_archive_element keeps pointers to
the_bfd and the_bfd->filename in a lang_input_statement_type
linker script statement. */
if (entry->the_bfd->my_archive == NULL)
bfd_close (entry->the_bfd);
entry->the_bfd = abfd;