1# This shell script emits a C file. -*- C -*-
2#   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
3#
4# This file is part of GLD, the Gnu Linker.
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19#
20
21# This file is sourced from elf32.em and mmo.em, used to define
22# MMIX-specific things common to ELF and MMO.
23
24cat >>e${EMULATION_NAME}.c <<EOF
25#include "elf/mmix.h"
26
27/* Set up handling of linker-allocated global registers.  */
28
29static void
30mmix_before_allocation (void)
31{
32  /* Call the default first.  */
33  gld${EMULATION_NAME}_before_allocation ();
34
35  /* There's a needrelax.em which uses this ..._before_allocation-hook and
36     just has the statement below as payload.  It's more of a hassle to
37     use that than to just include these two lines and take the
38     maintenance burden to keep them in sync.  (Of course we lose the
39     maintenance burden of checking that it still does what we need.)  */
40
41  /* Force -relax on (regardless of whether we're doing a relocatable
42     link).  */
43  command_line.relax = TRUE;
44
45  if (!_bfd_mmix_before_linker_allocation (output_bfd, &link_info))
46    einfo ("%X%P: Internal problems setting up section %s",
47	   MMIX_LD_ALLOCATED_REG_CONTENTS_SECTION_NAME);
48}
49
50/* We need to set the VMA of the .MMIX.reg_contents section when it has
51   been allocated, and produce the final settings for the linker-generated
52   GREGs.  */
53
54static void
55mmix_after_allocation (void)
56{
57  asection *sec
58    = bfd_get_section_by_name (output_bfd, MMIX_REG_CONTENTS_SECTION_NAME);
59  bfd_signed_vma regvma;
60
61  /* If there's no register section, we don't need to do anything.  On the
62     other hand, if there's a non-standard linker-script without a mapping
63     from MMIX_LD_ALLOCATED_REG_CONTENTS_SECTION_NAME when that section is
64     present (as in the ld test "NOCROSSREFS 2"), that section (1) will be
65     orphaned; not inserted in MMIX_REG_CONTENTS_SECTION_NAME and (2) we
66     will not do the necessary preparations for those relocations that
67     caused it to be created.  We'll SEGV from the latter error.  The
68     former error in separation will result in a non-working binary, but
69     that's expected when you play tricks with linker scripts.  The
70     "NOCROSSREFS 2" test does not run the output so it does not matter
71     there.  */
72  if (sec == NULL)
73    sec
74      = bfd_get_section_by_name (output_bfd,
75				 MMIX_LD_ALLOCATED_REG_CONTENTS_SECTION_NAME);
76  if (sec == NULL)
77    return;
78
79  regvma = 256 * 8 - sec->_raw_size - 8;
80
81  /* If we start on a local register, we have too many global registers.
82     We treat this error as nonfatal (meaning processing will continue in
83     search for other errors), because it's a link error in the same way
84     as an undefined symbol.  */
85  if (regvma < 32 * 8)
86    {
87      einfo ("%X%P: Too many global registers: %u, max 223\n",
88	     (unsigned) sec->_raw_size / 8);
89      regvma = 32 * 8;
90    }
91
92  /* Set vma to correspond to first such register number * 8.  */
93  bfd_set_section_vma (output_bfd, sec, (bfd_vma) regvma);
94
95  /* ??? Why isn't the section size (_cooked_size) set?  Doesn't it get
96     set regardless of presence of relocations?  */
97  if (sec->_cooked_size == 0
98      && ! bfd_set_section_size (output_bfd, sec, sec->_raw_size))
99    {
100      /* This is a fatal error; make the einfo call not return.  */
101      einfo ("%F%P: Can't set section %s size to %u\n",
102	     MMIX_REG_CONTENTS_SECTION_NAME, (unsigned) sec->_raw_size);
103    }
104
105  /* Simplify symbol output for the register section (without contents;
106     created for register symbols) by setting the output offset to 0.
107     This section is only present when there are register symbols.  */
108  sec = bfd_get_section_by_name (output_bfd, MMIX_REG_SECTION_NAME);
109  if (sec != NULL)
110    bfd_set_section_vma (abfd, sec, 0);
111
112  if (!_bfd_mmix_after_linker_allocation (output_bfd, &link_info))
113    {
114      /* This is a fatal error; make einfo call not return.  */
115      einfo ("%F%P: Can't finalize linker-allocated global registers\n");
116    }
117}
118EOF
119
120LDEMUL_AFTER_ALLOCATION=mmix_after_allocation
121LDEMUL_BEFORE_ALLOCATION=mmix_before_allocation
122