X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=ld%2Fldlang.c;h=d97a55b084c26995af33427c0ecb25e5cbfe7120;hb=2b3decb5e194cab298545ca41d0fe22ad282d2e6;hp=65e092bb1928b672284fbf34f7634fbbd2a7ad93;hpb=011aa75f625b8ef2fe1a8adb9498680410174d3c;p=binutils-gdb.git diff --git a/ld/ldlang.c b/ld/ldlang.c index 65e092bb192..d97a55b084c 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -1322,8 +1322,13 @@ lang_memory_default (asection * section) return lang_memory_region_lookup (DEFAULT_MEMORY_REGION, FALSE); } +/* Find or create an output_section_statement with the given NAME. + If CONSTRAINT is non-zero match one with that constraint, otherwise + match any non-negative constraint. If CREATE, always make a + new output_section_statement for SPECIAL CONSTRAINT. */ + lang_output_section_statement_type * -lang_output_section_statement_lookup (const char *const name, +lang_output_section_statement_lookup (const char *name, int constraint, bfd_boolean create) { @@ -1344,8 +1349,8 @@ lang_output_section_statement_lookup (const char *const name, /* We have a section of this name, but it might not have the correct constraint. */ struct out_section_hash_entry *last_ent; - unsigned long hash = entry->root.hash; + name = entry->s.output_section_statement.name; if (create && constraint == SPECIAL) /* Not traversing to the end reverses the order of the second and subsequent SPECIAL sections in the hash table chain, @@ -1354,17 +1359,15 @@ lang_output_section_statement_lookup (const char *const name, else do { - if (entry->s.output_section_statement.constraint >= 0 - && (constraint == 0 - || (constraint - == entry->s.output_section_statement.constraint))) + if (constraint == entry->s.output_section_statement.constraint + || (constraint == 0 + && entry->s.output_section_statement.constraint >= 0)) 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); + && name == entry->s.output_section_statement.name); if (!create) return NULL; @@ -1388,6 +1391,36 @@ lang_output_section_statement_lookup (const char *const name, return &entry->s.output_section_statement; } +/* Find the next output_section_statement with the same name as OS. + If CONSTRAINT is non-zero, find one with that constraint otherwise + match any non-negative constraint. */ + +lang_output_section_statement_type * +next_matching_output_section_statement (lang_output_section_statement_type *os, + int constraint) +{ + /* All output_section_statements are actually part of a + struct out_section_hash_entry. */ + struct out_section_hash_entry *entry = (struct out_section_hash_entry *) + ((char *) os + - offsetof (struct out_section_hash_entry, s.output_section_statement)); + const char *name = os->name; + + ASSERT (name == entry->root.string); + do + { + entry = (struct out_section_hash_entry *) entry->root.next; + if (entry == NULL + || name != entry->s.output_section_statement.name) + return NULL; + } + while (constraint != entry->s.output_section_statement.constraint + && (constraint != 0 + || entry->s.output_section_statement.constraint < 0)); + + return &entry->s.output_section_statement; +} + /* A variant of lang_output_section_find used by place_orphan. Returns the output statement that should precede a new output statement for SEC. If an exact match is found on certain flags,