aboutsummaryrefslogtreecommitdiff
path: root/ld/ldlang.c
diff options
context:
space:
mode:
Diffstat (limited to 'ld/ldlang.c')
-rw-r--r--ld/ldlang.c49
1 files changed, 41 insertions, 8 deletions
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 65e092b..d97a55b 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,