diff options
author | Alan Modra <amodra@gmail.com> | 2008-10-04 06:08:59 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2008-10-04 06:08:59 +0000 |
commit | 8a99a385a72553a657a1238d310f94bafad182be (patch) | |
tree | 900f06409b15b8c0b6a3fb6b6c1551c883b7e37f /ld/ldlang.c | |
parent | 2605c5df34a43fcbd60dcb4d974938022baae1ce (diff) | |
download | gdb-8a99a385a72553a657a1238d310f94bafad182be.zip gdb-8a99a385a72553a657a1238d310f94bafad182be.tar.gz gdb-8a99a385a72553a657a1238d310f94bafad182be.tar.bz2 |
* ldemul.c (ldemul_place_orphan): Add "constraint" param.
* ldemul.h (ldemul_place_orphan): Update prototype.
(struct ld_emulation_xfer_struct <place_orphan>): Likewise add param.
* ldlang.c (unique_section_p): Make static.
(lang_output_section_statement_lookup): Optimise creation of SPECIAL
sections.
(lang_insert_orphan): Add "constraint" param. Pass to
lang_enter_output_section_statement.
(init_os): Don't use an existing bfd section for SPECIAL sections.
(lang_place_orphans): Don't rename unique output sections, instead
mark their output section statements SPECIAL.
* ldlang.h (lang_insert_orphan): Update prototype.
(unique_section_p): Delete.
* emultempl/beos.em (place_orphan): Add "constraint" param.
* emultempl/elf32.em (place_orphan): Likewise. Don't match existing
output sections if set.
* emultempl/pe.em (place_orphan): Likewise.
* emultempl/pep.em (place_orphan): Likewise.
* emultempl/mmo.em (mmo_place_orphan): Update.
* emultempl/spuelf.em (spu_place_special_section): Update.
Diffstat (limited to 'ld/ldlang.c')
-rw-r--r-- | ld/ldlang.c | 63 |
1 files changed, 32 insertions, 31 deletions
diff --git a/ld/ldlang.c b/ld/ldlang.c index 44fb136..2908449 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -193,7 +193,7 @@ input_statement_is_archive_path (const char *file_spec, char *sep, return match; } -bfd_boolean +static bfd_boolean unique_section_p (const asection *sec) { struct unique_sections *unam; @@ -1278,19 +1278,25 @@ lang_output_section_statement_lookup (const char *const name, struct out_section_hash_entry *last_ent; unsigned long hash = entry->root.hash; - do - { - if (entry->s.output_section_statement.constraint >= 0 - && (constraint == 0 - || (constraint == entry->s.output_section_statement.constraint - && constraint != SPECIAL))) - return &entry->s.output_section_statement; - last_ent = entry; - entry = (struct out_section_hash_entry *) entry->root.next; - } - while (entry != NULL - && entry->root.hash == hash - && strcmp (name, entry->s.output_section_statement.name) == 0); + if (create && constraint == SPECIAL) + /* Not traversing to the end reverses the order of the second + and subsequent SPECIAL sections in the hash table chain, + but that shouldn't matter. */ + last_ent = entry; + else + do + { + if (entry->s.output_section_statement.constraint >= 0 + && (constraint == 0 + || (constraint + == entry->s.output_section_statement.constraint))) + return &entry->s.output_section_statement; + last_ent = entry; + entry = (struct out_section_hash_entry *) entry->root.next; + } + while (entry != NULL + && entry->root.hash == hash + && strcmp (name, entry->s.output_section_statement.name) == 0); if (!create) return NULL; @@ -1556,6 +1562,7 @@ insert_os_after (lang_output_section_statement_type *after) lang_output_section_statement_type * lang_insert_orphan (asection *s, const char *secname, + int constraint, lang_output_section_statement_type *after, struct orphan_save *place, etree_type *address, @@ -1611,7 +1618,7 @@ lang_insert_orphan (asection *s, os_tail = ((lang_output_section_statement_type **) lang_output_section_statement.tail); os = lang_enter_output_section_statement (secname, address, 0, NULL, NULL, - NULL, 0); + NULL, constraint); if (add_child == NULL) add_child = &os->children; @@ -1914,10 +1921,11 @@ init_os (lang_output_section_statement_type *s, asection *isec, if (strcmp (s->name, DISCARD_SECTION_NAME) == 0) einfo (_("%P%F: Illegal use of `%s' section\n"), DISCARD_SECTION_NAME); - s->bfd_section = bfd_get_section_by_name (link_info.output_bfd, s->name); + if (s->constraint != SPECIAL) + s->bfd_section = bfd_get_section_by_name (link_info.output_bfd, s->name); if (s->bfd_section == NULL) - s->bfd_section = bfd_make_section_with_flags (link_info.output_bfd, - s->name, flags); + s->bfd_section = bfd_make_section_anyway_with_flags (link_info.output_bfd, + s->name, flags); if (s->bfd_section == NULL) { einfo (_("%P%F: output format %s cannot represent section called %s\n"), @@ -5655,23 +5663,16 @@ lang_place_orphans (void) else { const char *name = s->name; + int constraint = 0; - if ((config.unique_orphan_sections - || unique_section_p (s)) - && bfd_get_section_by_name (link_info.output_bfd, - name) != NULL) - { - static int count = 1; - name = bfd_get_unique_section_name (link_info.output_bfd, - name, &count); - if (name == NULL) - einfo ("%F%P: place_orphan failed: %E\n"); - } + if (config.unique_orphan_sections || unique_section_p (s)) + constraint = SPECIAL; - if (!ldemul_place_orphan (s, name)) + if (!ldemul_place_orphan (s, name, constraint)) { lang_output_section_statement_type *os; - os = lang_output_section_statement_lookup (name, 0, + os = lang_output_section_statement_lookup (name, + constraint, TRUE); lang_add_section (&os->children, s, os); } |