From efdfc2c2508c40104ebb67810cde8af8a8b50e05 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Tue, 21 Oct 2008 22:55:04 +0000 Subject: [PATCH] * 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. --- ld/ChangeLog | 8 ++++++++ ld/emultempl/elf32.em | 24 +++++++++++++++++++++--- ld/ldlang.c | 30 ++++++++++++++++++++++++------ 3 files changed, 53 insertions(+), 9 deletions(-) diff --git a/ld/ChangeLog b/ld/ChangeLog index 59fa810d6..7677999b5 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,11 @@ +2008-10-22 Alan Modra + + * 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 * emultempl/armelf.em (PARSE_AND_LIST_OPTIONS): Correct typo in diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em index e1e7420ee..bb299d98d 100644 --- a/ld/emultempl/elf32.em +++ b/ld/emultempl/elf32.em @@ -1662,7 +1662,10 @@ gld${EMULATION_NAME}_place_orphan (asection *s, 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 { @@ -1672,7 +1675,8 @@ gld${EMULATION_NAME}_place_orphan (asection *s, orphan_bss, orphan_rel, orphan_interp, - orphan_sdata + orphan_sdata, + orphan_nonalloc }; static int orphan_init_done = 0; struct orphan_save *place; @@ -1728,7 +1732,9 @@ gld${EMULATION_NAME}_place_orphan (asection *s, 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) { @@ -1736,6 +1742,16 @@ gld${EMULATION_NAME}_place_orphan (asection *s, 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; } @@ -1758,7 +1774,9 @@ gld${EMULATION_NAME}_place_orphan (asection *s, 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) diff --git a/ld/ldlang.c b/ld/ldlang.c index 29084490e..322ce5bc5 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -1363,7 +1363,8 @@ lang_output_section_find_by_flags (const asection *sec, 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) @@ -1383,7 +1384,8 @@ lang_output_section_find_by_flags (const asection *sec, 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) @@ -1404,7 +1406,8 @@ lang_output_section_find_by_flags (const asection *sec, 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) @@ -1426,7 +1429,8 @@ lang_output_section_find_by_flags (const asection *sec, 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) @@ -1446,9 +1450,9 @@ lang_output_section_find_by_flags (const asection *sec, 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; @@ -1465,6 +1469,20 @@ lang_output_section_find_by_flags (const asection *sec, 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; -- 2.11.4.GIT