* emultempl/mmo.em (mmo_place_orphan): Rewrite to also attach

orphan sections to .data and .bss output sections, not just .text.
	When giving up on finding a suitable output section, attach to any
	output section other than .MMIX.reg_contents, if it exists.
	* scripttempl/mmo.sc: Move output debug sections to just before
	.MMIX.reg_contents.  Add .gnu.attributes.  Add new . = . NOP
	assignments and move end-of-section provide-symbols after them
	to force the end-of-section symbols to the address after orphan
	placement.  Add SORT_NONE to .init and .fini sections.
This commit is contained in:
Hans-Peter Nilsson 2012-09-09 16:30:40 +00:00
parent e81fea4d17
commit a9ae0bdaba
3 changed files with 156 additions and 74 deletions

View File

@ -1,3 +1,15 @@
2012-09-09 Hans-Peter Nilsson <hp@bitrange.com>
* emultempl/mmo.em (mmo_place_orphan): Rewrite to also attach
orphan sections to .data and .bss output sections, not just .text.
When giving up on finding a suitable output section, attach to any
output section other than .MMIX.reg_contents, if it exists.
* scripttempl/mmo.sc: Move output debug sections to just before
.MMIX.reg_contents. Add .gnu.attributes. Add new . = . NOP
assignments and move end-of-section provide-symbols after them
to force the end-of-section symbols to the address after orphan
placement. Add SORT_NONE to .init and .fini sections.
2012-08-30 H.J. Lu <hongjiu.lu@intel.com>
PR ld/14525

View File

@ -53,22 +53,49 @@ mmo_place_orphan (asection *s,
const char *secname,
int constraint ATTRIBUTE_UNUSED)
{
static struct orphan_save hold_text =
{
MMO_TEXT_SECTION_NAME,
SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE,
0, 0, 0, 0
};
struct orphan_save *place;
static struct
{
flagword nonzero_flags;
struct orphan_save orphansave;
} holds[] =
{
{
SEC_CODE | SEC_READONLY,
{
MMO_TEXT_SECTION_NAME,
SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE,
0, 0, 0, 0
}
},
{
SEC_LOAD | SEC_DATA,
{
MMO_DATA_SECTION_NAME,
SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_DATA,
0, 0, 0, 0
}
},
{
SEC_ALLOC,
{
".bss",
SEC_ALLOC,
0, 0, 0, 0
}
}
};
struct orphan_save *place = NULL;
lang_output_section_statement_type *after;
lang_output_section_statement_type *os;
size_t i;
/* We have nothing to say for anything other than a final link. */
/* We have nothing to say for anything other than a final link or
for sections that are excluded. */
if (link_info.relocatable
|| (s->flags & (SEC_EXCLUDE | SEC_LOAD)) != SEC_LOAD)
|| (s->flags & SEC_EXCLUDE) != 0)
return NULL;
/* Only care for sections we're going to load. */
os = lang_output_section_find (secname);
/* We have an output section by this name. Place the section inside it
@ -79,31 +106,66 @@ mmo_place_orphan (asection *s,
return os;
}
/* If this section does not have .text-type section flags or there's no
MMO_TEXT_SECTION_NAME, we don't have anything to say. */
if ((s->flags & (SEC_CODE | SEC_READONLY)) == 0)
/* Check for matching section type flags for sections we care about.
A section without contents can have SEC_LOAD == 0, but we still
want it attached to a sane section so the symbols appear as
expected. */
if ((s->flags & (SEC_ALLOC | SEC_READONLY)) != SEC_READONLY)
for (i = 0; i < sizeof (holds) / sizeof (holds[0]); i++)
if ((s->flags & holds[i].nonzero_flags) != 0)
{
place = &holds[i].orphansave;
if (place->os == NULL)
place->os = lang_output_section_find (place->name);
break;
}
if (place == NULL)
{
/* For other combinations, we have to give up, except we make
sure not to place the orphan section after the
linker-generated register section; that'd make it continue
the reg section and we never want that to happen for orphan
sections. */
lang_output_section_statement_type *before;
lang_output_section_statement_type *lookup;
static struct orphan_save hold_nonreg =
{
NULL,
SEC_READONLY,
0, 0, 0, 0
};
if (hold_nonreg.os == NULL)
{
before = lang_output_section_find (MMIX_REG_CONTENTS_SECTION_NAME);
/* If we have no such section, all fine; we don't care where
it's placed. */
if (before == NULL)
return NULL;
/* We have to find the oss before this one, so we can use that as
"after". */
for (lookup = &lang_output_section_statement.head->output_section_statement;
lookup != NULL && lookup->next != before;
lookup = lookup->next)
;
hold_nonreg.os = lookup;
}
place = &hold_nonreg;
}
after = place->os;
if (after == NULL)
return NULL;
if (hold_text.os == NULL)
hold_text.os = lang_output_section_find (hold_text.name);
place = &hold_text;
if (hold_text.os != NULL)
after = hold_text.os;
else
after = &lang_output_section_statement.head->output_section_statement;
/* If there's an output section by this name, we'll use it, regardless
of section flags, in contrast to what's done in elf32.em. */
/* If there's an output section by *this* name, we'll use it, regardless
of actual section flags, in contrast to what's done in elf32.em. */
os = lang_insert_orphan (s, secname, 0, after, place, NULL, NULL);
/* We need an output section for .text as a root, so if there was none
(might happen with a peculiar linker script such as in "map
addresses", map-address.exp), we grab the output section created
above. */
if (hold_text.os == NULL)
hold_text.os = os;
return os;
}

View File

@ -20,12 +20,12 @@ SECTIONS
/* FIXME: Move .init, .fini, .ctors and .dtors to their own sections. */
${RELOCATING+ PROVIDE (_init_start = .);}
${RELOCATING+ PROVIDE (_init = .);}
${RELOCATING+ KEEP (*(.init))}
${RELOCATING+ KEEP (*(SORT_NONE(.init)))}
${RELOCATING+ PROVIDE (_init_end = .);}
${RELOCATING+ PROVIDE (_fini_start = .);}
${RELOCATING+ PROVIDE (_fini = .);}
${RELOCATING+ KEEP (*(.fini))}
${RELOCATING+ KEEP (*(SORT_NONE(.fini)))}
${RELOCATING+ PROVIDE (_fini_end = .);}
/* FIXME: Align ctors, dtors, ehframe. */
@ -57,12 +57,55 @@ SECTIONS
${RELOCATING+KEEP (*(.eh_frame))}
${RELOCATING+*(.gcc_except_table)}
${RELOCATING+ PROVIDE(etext = .);}
${RELOCATING+ PROVIDE(_etext = .);}
${RELOCATING+ PROVIDE(__etext = .);}
${RELOCATING+Main = DEFINED (Main) ? Main : (DEFINED (_start) ? _start : ADDR (.text));}
}
/* The following NOP assignment and those after .data and .bss, are
necessary to get orphan sections adopted by the .text inserted before
the following end-section symbols. An output section would also serve
this purpose, but we can't do that. */
. = .;
${RELOCATING+ PROVIDE(etext = .);}
${RELOCATING+ PROVIDE(_etext = .);}
${RELOCATING+ PROVIDE(__etext = .);}
.data ${RELOCATING+ ${DATA_ADDR}}:
{
${RELOCATING+ PROVIDE(__Sdata = .);}
*(.data);
${RELOCATING+*(.data.*)}
${RELOCATING+*(.gnu.linkonce.d*)}
}
. = .;
${RELOCATING+ PROVIDE(__Edata = .);}
/* Deprecated, use __Edata. */
${RELOCATING+ PROVIDE(edata = .);}
${RELOCATING+ PROVIDE(_edata = .);}
${RELOCATING+ PROVIDE(__edata = .);}
/* At the moment, although perhaps we should, we can't map sections
without contents to sections *with* contents due to FIXME: a BFD bug.
Anyway, the mmo back-end ignores sections without contents when
writing out sections, so this works fine. */
.bss :
{
${RELOCATING+ PROVIDE(__Sbss = .);}
${RELOCATING+ PROVIDE(__bss_start = .);}
${RELOCATING+ *(.sbss);}
${RELOCATING+ *(.bss);}
${RELOCATING+*(.bss.*)}
${RELOCATING+ *(COMMON);}
}
. = .;
${RELOCATING+ PROVIDE(__Ebss = .);}
/* Deprecated, use __Ebss or __Eall as appropriate. */
${RELOCATING+ PROVIDE(end = .);}
${RELOCATING+ PROVIDE(_end = .);}
${RELOCATING+ PROVIDE(__end = .);}
${RELOCATING+ PROVIDE(__Eall = .);}
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
@ -85,44 +128,7 @@ SECTIONS
.debug_ranges 0 : { *(.debug_ranges) }
/* DWARF Extension. */
.debug_macro 0 : { *(.debug_macro) }
.data ${RELOCATING+ ${DATA_ADDR}}:
{
${RELOCATING+ PROVIDE(__Sdata = .);}
*(.data);
${RELOCATING+*(.data.*)}
${RELOCATING+*(.gnu.linkonce.d*)}
${RELOCATING+ PROVIDE(__Edata = .);}
/* Deprecated, use __Edata. */
${RELOCATING+ PROVIDE(edata = .);}
${RELOCATING+ PROVIDE(_edata = .);}
${RELOCATING+ PROVIDE(__edata = .);}
}
/* At the moment, although perhaps we should, we can't map sections
without contents to sections *with* contents due to FIXME: a BFD bug.
Anyway, the mmo back-end ignores sections without contents when
writing out sections, so this works fine. */
.bss :
{
${RELOCATING+ PROVIDE(__Sbss = .);}
${RELOCATING+ PROVIDE(__bss_start = .);}
${RELOCATING+ *(.sbss);}
${RELOCATING+ *(.bss);}
${RELOCATING+*(.bss.*)}
${RELOCATING+ *(COMMON);}
${RELOCATING+ PROVIDE(__Ebss = .);}
}
/* Deprecated, use __Ebss or __Eall as appropriate. */
${RELOCATING+ PROVIDE(end = .);}
${RELOCATING+ PROVIDE(_end = .);}
${RELOCATING+ PROVIDE(__end = .);}
${RELOCATING+ PROVIDE(__Eall = .);}
.debug_macro 0 : { *(.debug_macro) }
.MMIX.reg_contents :
{
@ -140,5 +146,7 @@ SECTIONS
It can probably be fixed with some amount of work. */
/DISCARD/ :
{ ${RELOCATING+ *(.gnu.warning.*);} }
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
}
EOF