+2008-10-22 Alan Modra <amodra@bigpond.net.au>
+
+ * ldlang.c (lang_output_section_find_by_flags): Handle non-alloc
+ sections.
+ * emultempl/elf32.em (enum orphan_save_index): Add orphan_nonalloc.
+ (hold): Likewise.
+ (gld${EMULATION_NAME}_place_orphan): Handle non-alloc orphans.
+
2008-10-22 Bernhard Reutner-Fischer <aldot@gcc.gnu.org>
* emultempl/armelf.em (PARSE_AND_LIST_OPTIONS): Correct typo in
0, 0, 0, 0 },
{ ".sdata",
SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_SMALL_DATA,
- 0, 0, 0, 0 }
+ 0, 0, 0, 0 },
+ { 0,
+ SEC_HAS_CONTENTS,
+ 0, 0, 0, 0 },
};
enum orphan_save_index
{
orphan_bss,
orphan_rel,
orphan_interp,
- orphan_sdata
+ orphan_sdata,
+ orphan_nonalloc
};
static int orphan_init_done = 0;
struct orphan_save *place;
if (!orphan_init_done)
{
+ lang_output_section_statement_type *lookup;
struct orphan_save *ho;
+
for (ho = hold; ho < hold + sizeof (hold) / sizeof (hold[0]); ++ho)
if (ho->name != NULL)
{
if (ho->os != NULL && ho->os->flags == 0)
ho->os->flags = ho->flags;
}
+ lookup = hold[orphan_bss].os;
+ if (lookup == NULL)
+ lookup = &lang_output_section_statement.head->output_section_statement;
+ for (; lookup != NULL; lookup = lookup->next)
+ if ((lookup->bfd_section != NULL
+ && (lookup->bfd_section->flags & SEC_DEBUGGING) != 0)
+ || strcmp (lookup->name, ".comment") == 0)
+ break;
+ hold[orphan_nonalloc].os = lookup ? lookup->prev : NULL;
+ hold[orphan_nonalloc].name = ".comment";
orphan_init_done = 1;
}
in the first page. */
place = NULL;
- if ((s->flags & SEC_ALLOC) == 0)
+ if ((s->flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0)
+ place = &hold[orphan_nonalloc];
+ else if ((s->flags & SEC_ALLOC) == 0)
;
else if ((s->flags & SEC_LOAD) != 0
&& ((iself && sh_type == SHT_NOTE)
return found;
}
- if (sec->flags & SEC_CODE)
+ if ((sec->flags & SEC_CODE) != 0
+ && (sec->flags & SEC_ALLOC) != 0)
{
/* Try for a rw code section. */
for (look = first; look; look = look->next)
found = look;
}
}
- else if (sec->flags & (SEC_READONLY | SEC_THREAD_LOCAL))
+ else if ((sec->flags & (SEC_READONLY | SEC_THREAD_LOCAL)) != 0
+ && (sec->flags & SEC_ALLOC) != 0)
{
/* .rodata can go after .text, .sdata2 after .rodata. */
for (look = first; look; look = look->next)
found = look;
}
}
- else if (sec->flags & SEC_SMALL_DATA)
+ else if ((sec->flags & SEC_SMALL_DATA) != 0
+ && (sec->flags & SEC_ALLOC) != 0)
{
/* .sdata goes after .data, .sbss after .sdata. */
for (look = first; look; look = look->next)
found = look;
}
}
- else if (sec->flags & SEC_HAS_CONTENTS)
+ else if ((sec->flags & SEC_HAS_CONTENTS) != 0
+ && (sec->flags & SEC_ALLOC) != 0)
{
/* .data goes after .rodata. */
for (look = first; look; look = look->next)
found = look;
}
}
- else
+ else if ((sec->flags & SEC_ALLOC) != 0)
{
- /* .bss goes last. */
+ /* .bss goes after any other alloc section. */
for (look = first; look; look = look->next)
{
flags = look->flags;
found = look;
}
}
+ else
+ {
+ /* non-alloc go last. */
+ for (look = first; look; look = look->next)
+ {
+ flags = look->flags;
+ if (look->bfd_section != NULL)
+ flags = look->bfd_section->flags;
+ flags ^= sec->flags;
+ if (!(flags & SEC_DEBUGGING))
+ found = look;
+ }
+ return found;
+ }
if (found || !match_type)
return found;