This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
PATCH: Should ld cache bfd_check_format return?
- From: "H. J. Lu" <hjl at lucon dot org>
- To: binutils at sources dot redhat dot com
- Date: Wed, 19 Apr 2006 13:44:44 -0700
- Subject: PATCH: Should ld cache bfd_check_format return?
- References: <20060419142124.GA24515@lucon.org>
On Wed, Apr 19, 2006 at 07:21:24AM -0700, H. J. Lu wrote:
> load_symbols does
>
> ldfile_open_file (entry);
>
> if (! bfd_check_format (entry->the_bfd, bfd_archive)
> && ! bfd_check_format_matches (entry->the_bfd, bfd_object, &matching))
>
> ldfile_open_file also calls bfd_check_format. Should ld cache
> bfd_check_format return?
>
This patch caches bfd_check_format return.
H.J.
---
2006-04-19 H.J. Lu <hongjiu.lu@intel.com>
* ldfile.h (ldfile_check_format): New.
* ldlang.h (lang_input_statement_struct): Add format.
* ldfile.c (ldfile_check_format): New function.
(ldfile_try_open_bfd): Updated to use ldfile_check_format
instead of bfd_check_format.
* ldlang.c (walk_wild_file): Likewise.
(load_symbols): Likewise.
(open_input_bfds): Likewise.
(new_afile): Initialize format.
--- ld/ldfile.c.format 2005-05-16 11:04:40.000000000 -0700
+++ ld/ldfile.c 2006-04-19 13:26:02.000000000 -0700
@@ -125,6 +125,25 @@ ldfile_add_library_path (const char *nam
}
}
+/* Check format of an opened lang_input_statement. */
+
+bfd_boolean
+ldfile_check_format (lang_input_statement_type *entry,
+ bfd_format format)
+{
+ if (entry->format != bfd_unknown)
+ return entry->format == format;
+
+ if (bfd_check_format (entry->the_bfd, format))
+ {
+ entry->format = format;
+ return TRUE;
+ }
+ else
+ return FALSE;
+
+}
+
/* Try to open a BFD for a lang_input_statement. */
bfd_boolean
@@ -158,19 +177,21 @@ ldfile_try_open_bfd (const char *attempt
{
bfd *check;
- if (bfd_check_format (entry->the_bfd, bfd_archive))
- check = bfd_openr_next_archived_file (entry->the_bfd, NULL);
+ if (ldfile_check_format (entry, bfd_archive))
+ {
+ check = bfd_openr_next_archived_file (entry->the_bfd, NULL);
+ if (!check || !bfd_check_format (check, bfd_object))
+ /* No further check on unknown file. */
+ return TRUE;
+ }
else
- check = entry->the_bfd;
-
- if (check != NULL)
{
- if (! bfd_check_format (check, bfd_object))
+ check = entry->the_bfd;
+ if (!ldfile_check_format (entry, bfd_object))
{
- if (check == entry->the_bfd
- && entry->search_dirs_flag
+ if (entry->search_dirs_flag
&& bfd_get_error () == bfd_error_file_not_recognized
- && ! ldemul_unrecognized_file (entry))
+ && !ldemul_unrecognized_file (entry))
{
int token, skip = 0;
char *arg, *arg1, *arg2, *arg3;
@@ -254,37 +275,37 @@ ldfile_try_open_bfd (const char *attempt
{
einfo (_("%P: skipping incompatible %s when searching for %s\n"),
attempt, entry->local_sym_name);
- bfd_close (entry->the_bfd);
- entry->the_bfd = NULL;
- return FALSE;
+ goto bad;
}
}
+
+ /* No further check on unknown file. */
return TRUE;
}
- if (!entry->dynamic && (entry->the_bfd->flags & DYNAMIC) != 0)
+ if (!entry->dynamic
+ && (entry->the_bfd->flags & DYNAMIC) != 0)
{
einfo (_("%F%P: attempted static link of dynamic object `%s'\n"),
attempt);
- bfd_close (entry->the_bfd);
- entry->the_bfd = NULL;
- return FALSE;
+ goto bad;
}
+ }
- if (entry->search_dirs_flag
- && !bfd_arch_get_compatible (check, output_bfd,
- command_line.accept_unknown_input_arch)
- /* XCOFF archives can have 32 and 64 bit objects. */
- && ! (bfd_get_flavour (check) == bfd_target_xcoff_flavour
- && bfd_get_flavour (output_bfd) == bfd_target_xcoff_flavour
- && bfd_check_format (entry->the_bfd, bfd_archive)))
- {
- einfo (_("%P: skipping incompatible %s when searching for %s\n"),
- attempt, entry->local_sym_name);
- bfd_close (entry->the_bfd);
- entry->the_bfd = NULL;
- return FALSE;
- }
+ if (entry->search_dirs_flag
+ && !bfd_arch_get_compatible (check, output_bfd,
+ command_line.accept_unknown_input_arch)
+ /* XCOFF archives can have 32 and 64 bit objects. */
+ && ! (bfd_get_flavour (check) == bfd_target_xcoff_flavour
+ && bfd_get_flavour (output_bfd) == bfd_target_xcoff_flavour
+ && ldfile_check_format (entry, bfd_archive)))
+ {
+ einfo (_("%P: skipping incompatible %s when searching for %s\n"),
+ attempt, entry->local_sym_name);
+bad:
+ bfd_close (entry->the_bfd);
+ entry->the_bfd = NULL;
+ return FALSE;
}
}
--- ld/ldfile.h.format 2005-05-16 11:04:40.000000000 -0700
+++ ld/ldfile.h 2006-04-19 13:08:53.000000000 -0700
@@ -52,6 +52,8 @@ extern void ldfile_open_command_file
(const char *name);
extern void ldfile_open_file
(struct lang_input_statement_struct *);
+extern bfd_boolean ldfile_check_format
+ (struct lang_input_statement_struct *, bfd_format);
extern bfd_boolean ldfile_try_open_bfd
(const char *, struct lang_input_statement_struct *);
extern void ldfile_set_output_arch
--- ld/ldlang.c.format 2006-04-14 14:44:46.000000000 -0700
+++ ld/ldlang.c 2006-04-19 13:25:05.000000000 -0700
@@ -626,7 +626,7 @@ walk_wild_file (lang_wild_statement_type
void *data)
{
if (f->the_bfd == NULL
- || ! bfd_check_format (f->the_bfd, bfd_archive))
+ || ! ldfile_check_format (f, bfd_archive))
walk_wild_section (s, f, callback, data);
else
{
@@ -846,6 +846,7 @@ new_afile (const char *name,
FAIL ();
}
p->the_bfd = NULL;
+ p->format = bfd_unknown;
p->asymbols = NULL;
p->next_real_file = NULL;
p->next = NULL;
@@ -2309,15 +2310,13 @@ static bfd_boolean
load_symbols (lang_input_statement_type *entry,
lang_statement_list_type *place)
{
- char **matching;
-
if (entry->loaded)
return TRUE;
ldfile_open_file (entry);
- if (! bfd_check_format (entry->the_bfd, bfd_archive)
- && ! bfd_check_format_matches (entry->the_bfd, bfd_object, &matching))
+ if (! ldfile_check_format (entry, bfd_archive)
+ && ! ldfile_check_format (entry, bfd_object))
{
bfd_error_type err;
lang_statement_list_type *hold;
@@ -2337,7 +2336,10 @@ load_symbols (lang_input_statement_type
einfo (_("%B: file not recognized: %E\n"), entry->the_bfd);
einfo (_("%B: matching formats:"), entry->the_bfd);
- for (p = matching; *p != NULL; p++)
+
+ /* Get the list of matching formats. */
+ bfd_check_format_matches (entry->the_bfd, bfd_object, &p);
+ for (; *p != NULL; p++)
einfo (" %s", *p);
einfo ("%F\n");
}
@@ -2608,7 +2610,7 @@ get_first_input_target (void)
ldfile_open_file (s);
if (s->the_bfd != NULL
- && bfd_check_format (s->the_bfd, bfd_object))
+ && ldfile_check_format (s, bfd_object))
{
target = bfd_get_target (s->the_bfd);
@@ -2839,8 +2841,8 @@ open_input_bfds (lang_statement_union_ty
if (force
&& !s->input_statement.whole_archive
&& s->input_statement.loaded
- && bfd_check_format (s->input_statement.the_bfd,
- bfd_archive))
+ && ldfile_check_format (&s->input_statement,
+ bfd_archive))
s->input_statement.loaded = FALSE;
lang_list_init (&add);
--- ld/ldlang.h.format 2005-12-24 08:17:33.000000000 -0800
+++ ld/ldlang.h 2006-04-19 13:23:04.000000000 -0700
@@ -231,6 +231,9 @@ typedef struct lang_input_statement_stru
bfd *the_bfd;
+ /* Format of this file. */
+ bfd_format format;
+
bfd_boolean closed;
file_ptr passive_position;