diff options
author | Alan Modra <amodra@gmail.com> | 2009-05-15 14:22:36 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2009-05-15 14:22:36 +0000 |
commit | d127ecce68b9052033148696008a8a905f661301 (patch) | |
tree | c4b31acc130ee14648913fb99d0a280de36dcb3c /ld/ldlang.c | |
parent | 0643c12ee1f4e258e1efea52d46b4c4e67fc8f78 (diff) | |
download | gdb-d127ecce68b9052033148696008a8a905f661301.zip gdb-d127ecce68b9052033148696008a8a905f661301.tar.gz gdb-d127ecce68b9052033148696008a8a905f661301.tar.bz2 |
ld/
* ldlang.c (lang_output_section_statement_lookup): Add function
comment. Make "name" non-const. Ensure duplicate entries use
the same string, allowing simple comparison in hash bucket loop.
Tweak constraint check.
(next_matching_output_section_statement): New function.
* ldlang.h (lang_output_section_statement_lookup): Update.
(next_matching_output_section_statement): Declare.
* emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): Don't
combine orphan sections when input sections flags differ in
alloc or load.
* emultempl/pe.em: Formatting throughout.
(gld${EMULATION_NAME}_place_orphan): As for elf32.em.
* emultempl/pep.em: Formatting throughout.
(gld${EMULATION_NAME}_place_orphan): As for elf32.em.
ld/testsuite/
* ld-elf/orphan3.d, * ld-elf/orphan3a.s, * ld-elf/orphan3b.s,
* ld-elf/orphan3c.s, * ld-elf/orphan3d.s, * ld-elf/orphan3e.s,
* ld-elf/orphan3f.s: New test.
* ld-pe/orphan.d, * ld-pe/orphana.s, * ld-pe/orphanb.s,
* ld-pe/orphand.s, * ld-pe/orphane.s: New test.
* ld-pe/direct.exp: Use is_pecoff_format.
* ld-pe/longsecn.exp: Delete.
* ld-pe/pe.exp: Run new test and longsecn tests.
Diffstat (limited to 'ld/ldlang.c')
-rw-r--r-- | ld/ldlang.c | 49 |
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, |