aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog19
-rw-r--r--bfd/bfd-in2.h2
-rw-r--r--bfd/elf64-ppc.c2
-rw-r--r--bfd/format.c24
-rw-r--r--bfd/libbfd-in.h3
-rw-r--r--bfd/libbfd.h3
-rw-r--r--bfd/section.c23
7 files changed, 44 insertions, 32 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 655c0ad..8ef34ef 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,22 @@
+2018-05-16 Alan Modra <amodra@gmail.com>
+
+ PR 22458
+ * format.c (struct bfd_preserve): Add section_id.
+ (bfd_preserve_save, bfd_preserve_restore): Save and restore
+ _bfd_section_id.
+ (bfd_reinit): Set _bfd_section_id.
+ (bfd_check_format_matches): Put all matches of any priority into
+ matching_vector. Save initial section id and start each attempted
+ match at that section id.
+ * libbfd-in.h (_bfd_section_id): Declare.
+ * section.c (_bfd_section_id): Rename from section_id and make
+ global. Adjust uses.
+ (bfd_get_next_section_id): Delete.
+ * elf64-ppc.c (ppc64_elf_setup_section_lists): Replace use of
+ bfd_get_section_id with _bfd_section_id.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+
2018-05-15 Christophe Guillon <christophe.guillon@st.com>
* coffcode.h (coff_bigobj_swap_aux_in): Make sure that all fields
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 4822686..5f7ecd3 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -1892,8 +1892,6 @@ asection *bfd_make_section_with_flags
asection *bfd_make_section (bfd *, const char *name);
-int bfd_get_next_section_id (void);
-
bfd_boolean bfd_set_section_flags
(bfd *abfd, asection *sec, flagword flags);
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 09377d1..b166558 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -11760,7 +11760,7 @@ ppc64_elf_setup_section_lists (struct bfd_link_info *info)
if (htab == NULL)
return -1;
- htab->sec_info_arr_size = bfd_get_next_section_id ();
+ htab->sec_info_arr_size = _bfd_section_id;
amt = sizeof (*htab->sec_info) * (htab->sec_info_arr_size);
htab->sec_info = bfd_zmalloc (amt);
if (htab->sec_info == NULL)
diff --git a/bfd/format.c b/bfd/format.c
index 64d33f7..c4afd97 100644
--- a/bfd/format.c
+++ b/bfd/format.c
@@ -103,6 +103,7 @@ struct bfd_preserve
struct bfd_section *sections;
struct bfd_section *section_last;
unsigned int section_count;
+ unsigned int section_id;
struct bfd_hash_table section_htab;
const struct bfd_build_id *build_id;
};
@@ -125,6 +126,7 @@ bfd_preserve_save (bfd *abfd, struct bfd_preserve *preserve)
preserve->sections = abfd->sections;
preserve->section_last = abfd->section_last;
preserve->section_count = abfd->section_count;
+ preserve->section_id = _bfd_section_id;
preserve->section_htab = abfd->section_htab;
preserve->marker = bfd_alloc (abfd, 1);
preserve->build_id = abfd->build_id;
@@ -138,12 +140,13 @@ bfd_preserve_save (bfd *abfd, struct bfd_preserve *preserve)
/* Clear out a subset of BFD state. */
static void
-bfd_reinit (bfd *abfd)
+bfd_reinit (bfd *abfd, unsigned int section_id)
{
abfd->tdata.any = NULL;
abfd->arch_info = &bfd_default_arch_struct;
abfd->flags &= BFD_FLAGS_SAVED;
bfd_section_list_clear (abfd);
+ _bfd_section_id = section_id;
}
/* Restores bfd state saved by bfd_preserve_save. */
@@ -160,6 +163,7 @@ bfd_preserve_restore (bfd *abfd, struct bfd_preserve *preserve)
abfd->sections = preserve->sections;
abfd->section_last = preserve->section_last;
abfd->section_count = preserve->section_count;
+ _bfd_section_id = preserve->section_id;
abfd->build_id = preserve->build_id;
/* bfd_release frees all memory more recently bfd_alloc'd than
@@ -214,6 +218,7 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
const bfd_target *save_targ, *right_targ, *ar_right_targ, *match_targ;
int match_count, best_count, best_match;
int ar_match_index;
+ unsigned int initial_section_id = _bfd_section_id;
struct bfd_preserve preserve;
if (matching != NULL)
@@ -287,14 +292,13 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
/* Don't check the default target twice. */
if (*target == &binary_vec
- || (!abfd->target_defaulted && *target == save_targ)
- || (*target)->match_priority > best_match)
+ || (!abfd->target_defaulted && *target == save_targ))
continue;
/* If we already tried a match, the bfd is modified and may
have sections attached, which will confuse the next
_bfd_check_format call. */
- bfd_reinit (abfd);
+ bfd_reinit (abfd, initial_section_id);
/* Change BFD's target temporarily. */
abfd->xvec = *target;
@@ -329,9 +333,6 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
|| (bfd_has_map (abfd)
&& bfd_get_error () != bfd_error_wrong_object_format))
{
- /* This format checks out as ok! */
- right_targ = temp;
-
/* If this is the default target, accept it, even if
other targets might match. People who want those
other targets have to set the GNUTARGET variable. */
@@ -347,7 +348,12 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
best_match = match_priority;
best_count = 0;
}
- best_count++;
+ if (match_priority <= best_match)
+ {
+ /* This format checks out as ok! */
+ right_targ = temp;
+ best_count++;
+ }
}
else
{
@@ -446,7 +452,7 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
state (except possibly for XVEC). */
if (match_targ != right_targ)
{
- bfd_reinit (abfd);
+ bfd_reinit (abfd, initial_section_id);
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
goto err_ret;
match_targ = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
index 0c80f4d..d8b445f 100644
--- a/bfd/libbfd-in.h
+++ b/bfd/libbfd-in.h
@@ -53,6 +53,9 @@ struct section_hash_entry
asection section;
};
+/* Unique section id. */
+extern unsigned int _bfd_section_id;
+
/* tdata for an archive. For an input archive, cache
needs to be free()'d. For an output archive, symdefs do. */
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 66c2a5a..495ffb4 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -58,6 +58,9 @@ struct section_hash_entry
asection section;
};
+/* Unique section id. */
+extern unsigned int _bfd_section_id;
+
/* tdata for an archive. For an input archive, cache
needs to be free()'d. For an output archive, symdefs do. */
diff --git a/bfd/section.c b/bfd/section.c
index 752f291..7ee3f69 100644
--- a/bfd/section.c
+++ b/bfd/section.c
@@ -820,21 +820,21 @@ _bfd_generic_new_section_hook (bfd *abfd, asection *newsect)
return TRUE;
}
-static unsigned int section_id = 0x10; /* id 0 to 3 used by STD_SECTION. */
+unsigned int _bfd_section_id = 0x10; /* id 0 to 3 used by STD_SECTION. */
/* Initializes a new section. NEWSECT->NAME is already set. */
static asection *
bfd_section_init (bfd *abfd, asection *newsect)
{
- newsect->id = section_id;
+ newsect->id = _bfd_section_id;
newsect->index = abfd->section_count;
newsect->owner = abfd;
if (! BFD_SEND (abfd, _new_section_hook, (abfd, newsect)))
return NULL;
- section_id++;
+ _bfd_section_id++;
abfd->section_count++;
bfd_section_list_append (abfd, newsect);
return newsect;
@@ -1286,23 +1286,6 @@ bfd_make_section (bfd *abfd, const char *name)
/*
FUNCTION
- bfd_get_next_section_id
-
-SYNOPSIS
- int bfd_get_next_section_id (void);
-
-DESCRIPTION
- Returns the id that the next section created will have.
-*/
-
-int
-bfd_get_next_section_id (void)
-{
- return section_id;
-}
-
-/*
-FUNCTION
bfd_set_section_flags
SYNOPSIS