summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@bigpond.net.au>2008-10-21 22:55:04 +0000
committerAlan Modra <amodra@bigpond.net.au>2008-10-21 22:55:04 +0000
commitefdfc2c2508c40104ebb67810cde8af8a8b50e05 (patch)
treec13e3eaff3b5992754c7b1613ae9f5352595940f
parent3d36428e75cb8c30353830c268ae2bd2c1fb0e90 (diff)
downloadbinutils-redhat-efdfc2c2508c40104ebb67810cde8af8a8b50e05.tar.gz
* 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.
-rw-r--r--ld/ChangeLog8
-rw-r--r--ld/emultempl/elf32.em24
-rw-r--r--ld/ldlang.c30
3 files changed, 53 insertions, 9 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 59fa810d6a..7677999b58 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,11 @@
+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
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index e1e7420ee9..bb299d98d1 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 29084490e7..322ce5bc5d 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;