R_MMIX_BASE_PLUS_OFFSET relocs.
* emultempl/mmix-elfnmmo.em (mmix_after_allocation): Rename from
mmix_set_reg_section_vma. Call
_bfd_mmix_finalize_linker_allocated_gregs.
(mmix_before_allocation): New function.
(LDEMUL_AFTER_ALLOCATION): Set to mmix_after_allocation.
(LDEMUL_BEFORE_ALLOCATION): Define to mmix_before_allocation.
* scripttempl/mmo.sc (.text): Mark .init, .fini as KEEP.
(.MMIX.reg_contents): Add .MMIX.reg_contents.linker_allocated
before .MMIX.reg_contents.
* emultempl/mmo.em (gldmmo_before_allocation): Define to default.
(mmo_after_open): New function.
(LDEMUL_AFTER_OPEN): Define to mmo_after_open.
* emulparams/elf64mmix.sh (OTHER_SECTIONS): Tweak formatting. Add
.MMIX.reg_contents.linker_allocated before .MMIX.reg_contents.
+2002-02-01 Hans-Peter Nilsson <hp@bitrange.com>
+
+ Support on-demand global register allocation from
+ R_MMIX_BASE_PLUS_OFFSET relocs.
+ * emultempl/mmix-elfnmmo.em (mmix_after_allocation): Rename from
+ mmix_set_reg_section_vma. Call
+ _bfd_mmix_finalize_linker_allocated_gregs.
+ (mmix_before_allocation): New function.
+ (LDEMUL_AFTER_ALLOCATION): Set to mmix_after_allocation.
+ (LDEMUL_BEFORE_ALLOCATION): Define to mmix_before_allocation.
+ * scripttempl/mmo.sc (.text): Mark .init, .fini as KEEP.
+ (.MMIX.reg_contents): Add .MMIX.reg_contents.linker_allocated
+ before .MMIX.reg_contents.
+ * emultempl/mmo.em (gldmmo_before_allocation): Define to default.
+ (mmo_after_open): New function.
+ (LDEMUL_AFTER_OPEN): Define to mmo_after_open.
+ * emulparams/elf64mmix.sh (OTHER_SECTIONS): Tweak formatting. Add
+ .MMIX.reg_contents.linker_allocated before .MMIX.reg_contents.
+
2002-01-31 Ivan Guzvinec <ivang@opencores.org>
* emulparams/or32.sh: New file.
PROVIDE (Main = DEFINED (Main) ? Main : (DEFINED (_start) ? _start : _start.));
'
-OTHER_SECTIONS="
+OTHER_SECTIONS='
.MMIX.reg_contents :
{
/* Note that this section always has a fixed VMA - that of its
first register * 8. */
+ *(.MMIX.reg_contents.linker_allocated);
*(.MMIX.reg_contents);
}
-"
+'
# FIXME: Also bit by the PROVIDE bug? If not, this could be
# EXECUTABLE_SYMBOLS.
# This shell script emits a C file. -*- C -*-
-# Copyright 2001 Free Software Foundation, Inc.
+# Copyright 2001, 2002 Free Software Foundation, Inc.
#
# This file is part of GLD, the Gnu Linker.
#
cat >>e${EMULATION_NAME}.c <<EOF
#include "elf/mmix.h"
-static void mmix_set_reg_section_vma PARAMS ((void));
+static void mmix_before_allocation PARAMS ((void));
+static void mmix_after_allocation PARAMS ((void));
+
+/* Set up handling of linker-allocated global registers. */
+
+static void
+mmix_before_allocation ()
+{
+ /* Call the default first. */
+ gld${EMULATION_NAME}_before_allocation ();
+
+ /* There's a needrelax.em which uses this ..._before_allocation-hook and
+ just has the statement below as payload. It's more of a hassle to
+ use that than to just include these two lines and take the
+ maintenance burden to keep them in sync. (Of course we lose the
+ maintenance burden of checking that it still does what we need.) */
+
+ /* Force -relax on if not doing a relocatable link. */
+ if (! link_info.relocateable)
+ command_line.relax = true;
+
+ if (!_bfd_mmix_prepare_linker_allocated_gregs (output_bfd, &link_info))
+ einfo ("%X%P: Internal problems setting up section %s",
+ MMIX_LD_ALLOCATED_REG_CONTENTS_SECTION_NAME);
+}
/* We need to set the VMA of the .MMIX.reg_contents section when it has
- been allocated. */
+ been allocated, and produce the final settings for the linker-generated
+ GREGs. */
static void
-mmix_set_reg_section_vma ()
+mmix_after_allocation ()
{
asection *sec
= bfd_get_section_by_name (output_bfd, MMIX_REG_CONTENTS_SECTION_NAME);
}
/* Simplify symbol output for the register section (without contents;
- created for register symbols) by setting the output offset to 0. */
+ created for register symbols) by setting the output offset to 0.
+ This section is only present when there are register symbols. */
sec = bfd_get_section_by_name (output_bfd, MMIX_REG_SECTION_NAME);
- if (sec == NULL)
- return;
-
- bfd_set_section_vma (abfd, sec, 0);
+ if (sec != NULL)
+ bfd_set_section_vma (abfd, sec, 0);
+ if (!_bfd_mmix_finalize_linker_allocated_gregs (output_bfd, &link_info))
+ {
+ einfo ("%X%P: Can't finalize linker-allocated global registers\n");
+ /* In case stuff is added after this conditional. */
+ return;
+ }
}
EOF
-LDEMUL_AFTER_ALLOCATION=mmix_set_reg_section_vma
+LDEMUL_AFTER_ALLOCATION=mmix_after_allocation
+LDEMUL_BEFORE_ALLOCATION=mmix_before_allocation
# This shell script emits a C file. -*- C -*-
-# Copyright 2001 Free Software Foundation, Inc.
+# Copyright 2001, 2002 Free Software Foundation, Inc.
#
# This file is part of GLD, the Gnu Linker.
#
# This file is sourced from elf32.em and mmo.em, used to define
# linker MMIX-specifics common to ELF and MMO.
+cat >>e${EMULATION_NAME}.c <<EOF
+/* Need to have this define before mmix-elfnmmo, which includes
+ needrelax.em which uses this name for the before_allocation function,
+ normally defined in elf32.em. */
+#define gldmmo_before_allocation before_allocation_default
+EOF
+
. ${srcdir}/emultempl/mmix-elfnmmo.em
cat >>e${EMULATION_NAME}.c <<EOF
PARAMS ((lang_output_section_statement_type *));
static void mmo_finish PARAMS ((void));
static void mmo_wipe_sec_reloc_flag PARAMS ((bfd *, asection *, PTR));
+static void mmo_after_open PARAMS ((void));
/* Find the last output section before given output statement.
Used by place_orphan. */
{
bfd_map_over_sections (output_bfd, mmo_wipe_sec_reloc_flag, NULL);
}
+\f
+/* To get on-demand global register allocation right, we need to parse the
+ relocs, like what happens when linking to ELF. It needs to be done
+ before all input sections are supposed to be present. When linking to
+ ELF, it's done when reading symbols. When linking to mmo, we do it
+ when all input files are seen, which is equivalent. */
+static void
+mmo_after_open ()
+{
+ LANG_FOR_EACH_INPUT_STATEMENT (is)
+ {
+ if (bfd_get_flavour (is->the_bfd) == bfd_target_elf_flavour
+ && !_bfd_mmix_check_all_relocs (is->the_bfd, &link_info))
+ einfo ("%X%P: Internal problems scanning %B after opening it",
+ is->the_bfd);
+ }
+}
EOF
LDEMUL_PLACE_ORPHAN=mmo_place_orphan
LDEMUL_FINISH=mmo_finish
+LDEMUL_AFTER_OPEN=mmo_after_open
/* FIXME: Move .init, .fini, .ctors and .dtors to their own sections. */
${RELOCATING+ PROVIDE (_init_start = .);}
${RELOCATING+ PROVIDE (_init = .);}
- ${RELOCATING+ *(.init)}
+ ${RELOCATING+ KEEP (*(.init))}
${RELOCATING+ PROVIDE (_init_end = .);}
${RELOCATING+ PROVIDE (_fini_start = .);}
${RELOCATING+ PROVIDE (_fini = .);}
- ${RELOCATING+ *(.fini)}
+ ${RELOCATING+ KEEP (*(.fini))}
${RELOCATING+ PROVIDE (_fini_end = .);}
/* FIXME: Align ctors, dtors, ehframe. */
{
/* Note that this section always has a fixed VMA - that of its
first register * 8. */
+ *(.MMIX.reg_contents.linker_allocated);
*(.MMIX.reg_contents);
}