* 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.
This commit is contained in:
Alan Modra
2009-05-15 14:22:36 +00:00
parent 0643c12ee1
commit d127ecce68
22 changed files with 321 additions and 170 deletions

View File

@@ -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,