2002-01-29 Chris Demetriou <cgd@broadcom.com>
authorChris Demetriou <cgd@google.com>
Wed, 30 Jan 2002 02:22:14 +0000 (02:22 +0000)
committerChris Demetriou <cgd@google.com>
Wed, 30 Jan 2002 02:22:14 +0000 (02:22 +0000)
            Mitch Lichtenberg  <mpl@broadcom.com>

        * emulparams/elf32bmip.sh (EXTRA_EM_FILE): Define to be mipself.
        * emultempl/mipself.em: New file to handle MIPS ELF embedded
        reloc creation (ld --embedded-relocs).

ld/ChangeLog
ld/emulparams/elf32bmip.sh
ld/emultempl/mipself.em [new file with mode: 0644]

index 77d8f12b99a99a0b0256da4ae41a7be792f92c49..0f4be932cd8d0eda98cd11544f422ca775c32486 100644 (file)
@@ -1,3 +1,10 @@
+2002-01-29  Chris Demetriou  <cgd@broadcom.com>
+            Mitch Lichtenberg  <mpl@broadcom.com>
+
+       * emulparams/elf32bmip.sh (EXTRA_EM_FILE): Define to be mipself.
+       * emultempl/mipself.em: New file to handle MIPS ELF embedded
+       reloc creation (ld --embedded-relocs).
+
 2002-01-27  Daniel Jacobowitz  <drow@mvista.com>
 
        * configure: Regenerated.
index cf2abde3c51331cc50c536fe4d021e56e728e43d..fa7d671ffdf7f67fc500436565dd97753cd42c8d 100644 (file)
@@ -32,4 +32,5 @@ OTHER_SECTIONS='
 ARCH=mips
 MACHINE=
 TEMPLATE_NAME=elf32
+EXTRA_EM_FILE=mipself
 GENERATE_SHLIB_SCRIPT=yes
diff --git a/ld/emultempl/mipself.em b/ld/emultempl/mipself.em
new file mode 100644 (file)
index 0000000..c28ae42
--- /dev/null
@@ -0,0 +1,183 @@
+# Copyright 2002 Free Software Foundation, Inc.
+#   Written by Mitch Lichtenberg <mpl@broadcom.com> and
+#   Chris Demetriou <cgd@broadcom.com> based on m68kelf.em and mipsecoff.em.
+#
+# This file is part of GLD, the Gnu Linker.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# This shell script emits a C file. -*- C -*-
+
+
+# This file is sourced from elf32.em, and defines some extra routines for m68k
+# embedded systems using ELF and for some other systems using m68k ELF.  While
+# it is sourced from elf32.em for all m68k ELF configurations, here we include
+# only the features we want depending on the configuration.
+
+case ${target} in
+  mips*-*-elf)
+    echo "#define SUPPORT_EMBEDDED_RELOCS" >>e${EMULATION_NAME}.c
+    ;;
+esac
+
+cat >>e${EMULATION_NAME}.c <<EOF
+
+static void mips_elf${ELFSIZE}_after_open PARAMS ((void));
+#ifdef SUPPORT_EMBEDDED_RELOCS
+static void mips_elf${ELFSIZE}_check_sections PARAMS ((bfd *, asection *,
+                                                      PTR));
+#endif
+static void mips_elf${ELFSIZE}_after_allocation PARAMS ((void));
+
+/* This function is run after all the input files have been opened.  */
+
+static void
+mips_elf${ELFSIZE}_after_open()
+{
+  /* Call the standard elf routine.  */
+  gld${EMULATION_NAME}_after_open ();
+
+#ifdef SUPPORT_EMBEDDED_RELOCS
+  if (command_line.embedded_relocs && (! link_info.relocateable))
+    {  
+      bfd *abfd;
+
+      /* In the embedded relocs mode we create a .rel.sdata section for
+        each input file with a .sdata section which has has
+        relocations.  The BFD backend will fill in these sections
+        with magic numbers which can be used to relocate the data
+        section at run time.  */
+      for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link_next)
+        {
+          asection *datasec;
+
+         /* As first-order business, make sure that each input BFD is
+            ELF.  We need to call a special BFD backend function to
+            generate the embedded relocs, and we have that function
+            only for ELF */
+
+          if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
+           einfo ("%F%B: all input objects must be ELF for --embedded-relocs\n");
+
+         if (bfd_get_arch_size (abfd) != ${ELFSIZE})
+           einfo ("%F%B: all input objects must be ${ELFSIZE}-bit ELF for --embedded-relocs\n");
+
+          datasec = bfd_get_section_by_name (abfd, ".sdata");
+  
+          /* Note that we assume that the reloc_count field has already
+             been set up.  We could call bfd_get_reloc_upper_bound, but
+             that returns the size of a memory buffer rather than a reloc
+             count.  We do not want to call bfd_canonicalize_reloc,
+             because although it would always work it would force us to
+             read in the relocs into BFD canonical form, which would waste
+             a significant amount of time and memory.  */
+
+          if (datasec != NULL && datasec->reloc_count > 0)
+           {
+              asection *relsec;
+             relsec = bfd_make_section (abfd, ".rel.sdata");
+             if (relsec == NULL
+                 || ! bfd_set_section_flags (abfd, relsec,
+                                             (SEC_ALLOC
+                                              | SEC_LOAD
+                                              | SEC_HAS_CONTENTS
+                                              | SEC_IN_MEMORY))
+                  || ! bfd_set_section_alignment (abfd, relsec,
+                                                 (${ELFSIZE} == 32) ? 2 : 3)
+                 || ! bfd_set_section_size (abfd, relsec,
+                                            datasec->reloc_count
+                                            * ((${ELFSIZE} / 8) + 8)))
+               einfo ("%F%B: cannot create .rel.sdata section: %E\n");
+           }
+
+          /* Double check that all other data sections have no relocs,
+             as is required for embedded PIC code.  */
+          bfd_map_over_sections (abfd, mips_elf${ELFSIZE}_check_sections,
+                                (PTR) datasec);
+        }
+    }
+#endif /* SUPPORT_EMBEDDED_RELOCS */
+}
+
+#ifdef SUPPORT_EMBEDDED_RELOCS
+/* Check that of the data sections, only the .sdata section has
+   relocs.  This is called via bfd_map_over_sections.  */
+
+static void
+mips_elf${ELFSIZE}_check_sections (abfd, sec, sdatasec)
+     bfd *abfd;
+     asection *sec;
+     PTR sdatasec;
+{
+  if ((bfd_get_section_flags (abfd, sec) & SEC_CODE) == 0
+      && sec != (asection *) sdatasec
+      && sec->reloc_count != 0)
+    einfo ("%F%X: section %s has relocs; cannot use --embedded-relocs\n",
+          abfd, bfd_get_section_name (abfd, sec));
+}
+#endif /* SUPPORT_EMBEDDED_RELOCS */
+
+/* This function is called after the section sizes and offsets have
+   been set.  If we are generating embedded relocs, it calls a special
+   BFD backend routine to do the work.  */
+
+static void
+mips_elf${ELFSIZE}_after_allocation ()
+{
+  /* Call the standard elf routine.  */
+  after_allocation_default ();
+
+#ifdef SUPPORT_EMBEDDED_RELOCS
+  if (command_line.embedded_relocs && (! link_info.relocateable))
+    {
+      bfd *abfd;
+      
+      for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link_next)
+       {
+         asection *datasec, *relsec;
+         char *errmsg;
+
+         datasec = bfd_get_section_by_name (abfd, ".sdata");
+
+         if (datasec == NULL || datasec->reloc_count == 0)
+           continue;
+
+         relsec = bfd_get_section_by_name (abfd, ".rel.sdata");
+         ASSERT (relsec != NULL);
+
+         if (! bfd_mips_elf${ELFSIZE}_create_embedded_relocs (abfd,
+                                                              &link_info,
+                                                              datasec,
+                                                              relsec,
+                                                              &errmsg))
+           {
+             if (errmsg == NULL)
+               einfo ("%B%X: can not create runtime reloc information: %E\n",
+                      abfd);
+             else
+               einfo ("%X%B: can not create runtime reloc information: %s\n",
+                      abfd, errmsg);
+           }
+       }
+    }
+#endif /* SUPPORT_EMBEDDED_RELOCS */
+}
+
+EOF
+
+# We have our own after_open and after_allocation functions, but they call
+# the standard routines, so give them a different name.
+LDEMUL_AFTER_OPEN=mips_elf${ELFSIZE}_after_open
+LDEMUL_AFTER_ALLOCATION=mips_elf${ELFSIZE}_after_allocation