PATCH to ld: embedded relocs for m68k COFF as discussed with Ian

Michael Sokolov msokolov@ivan.Harhan.ORG
Thu Jun 8 19:08:00 GMT 2000


This patch and the previous one to BFD implement --embedded-relocs for m68k
COFF along the lines I discussed earlier today with Ian Lance Taylor. See that
discussion for justification.

The previous patch to BFD is a prerequisite for this one.

Nick, please comment on this patch. If you approve it, I will make the next one
doing the same for ELF. I will also make my post-linker tools grok the relocs
in the format generated here, and John can easily do the same with his. If you
reject my patch on the basis of accepting John's instead, that's fine with me
too. If you reject it on some other basis, let's work on getting it into
acceptable shape. I want --embedded-relocs.

--
Michael Sokolov		Harhan Engineering Laboratory
Public Service Agent	International Free Computing Task Force
			International Engineering and Science Task Force
			615 N GOOD LATIMER EXPY STE #4
			DALLAS TX 75204-5852 USA

Phone: +1-214-824-7693 (Harhan Eng Lab office)
E-mail: msokolov@ivan.Harhan.ORG (ARPA TCP/SMTP) (UUCP coming soon)

2000-06-08  Michael Sokolov  <msokolov@ivan.Harhan.ORG>

	* emultempl/m68kcoff.em: New file.
	* emulparams/m68kcoff.sh (TEMPLATE_NAME): Use m68kcoff template.
	* Makefile.am (em68kcoff.c): Depend on m68kcoff.em rather than
	generic.em.
	* Makefile.in: Regenerate.

Index: Makefile.am
===================================================================
RCS file: /cvs/src/src/ld/Makefile.am,v
retrieving revision 1.31
diff -c -3 -p -r1.31 Makefile.am
*** Makefile.am	2000/05/26 14:14:21	1.31
--- Makefile.am	2000/06/09 00:46:34
*************** em68kaux.c: $(srcdir)/emulparams/m68kaux
*** 567,573 ****
    $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/m68kaux.sc ${GEN_DEPENDS}
  	${GENSCRIPTS} m68kaux "$(tdir_m68kaux)"
  em68kcoff.c: $(srcdir)/emulparams/m68kcoff.sh \
!   $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/m68kcoff.sc ${GEN_DEPENDS}
  	${GENSCRIPTS} m68kcoff "$(tdir_m68kcoff)"
  em68kelf.c: $(srcdir)/emulparams/m68kelf.sh \
    $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
--- 567,573 ----
    $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/m68kaux.sc ${GEN_DEPENDS}
  	${GENSCRIPTS} m68kaux "$(tdir_m68kaux)"
  em68kcoff.c: $(srcdir)/emulparams/m68kcoff.sh \
!   $(srcdir)/emultempl/m68kcoff.em $(srcdir)/scripttempl/m68kcoff.sc ${GEN_DEPENDS}
  	${GENSCRIPTS} m68kcoff "$(tdir_m68kcoff)"
  em68kelf.c: $(srcdir)/emulparams/m68kelf.sh \
    $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
Index: emulparams/m68kcoff.sh
===================================================================
RCS file: /cvs/src/src/ld/emulparams/m68kcoff.sh,v
retrieving revision 1.1.1.1
diff -c -3 -p -r1.1.1.1 m68kcoff.sh
*** m68kcoff.sh	1999/05/03 07:29:07	1.1.1.1
--- m68kcoff.sh	2000/06/09 00:46:34
*************** OUTPUT_FORMAT="coff-m68k"
*** 3,5 ****
--- 3,6 ----
  TEXT_START_ADDR=0x1000000
  TARGET_PAGE_SIZE=0x1000000
  ARCH=m68k
+ TEMPLATE_NAME=m68kcoff
*** /dev/null	Thu Jun  8 19:15:04 2000
--- emultempl/m68kcoff.em	Thu Jun  8 19:30:54 2000
***************
*** 0 ****
--- 1,245 ----
+ # This shell script emits a C file. -*- C -*-
+ # It does some substitutions.
+ cat >e${EMULATION_NAME}.c <<EOF
+ /* This file is is generated by a shell script.  DO NOT EDIT! */
+ 
+ /* Handle embedded relocs for m68k.
+    Copyright (C) 2000 Free Software Foundation, Inc.
+    Written by Michael Sokolov <msokolov@ivan.Harhan.ORG>, based on generic.em
+    by Steve Chamberlain <steve@cygnus.com>, embedded relocs code based on
+    mipsecoff.em by Ian Lance Taylor <ian@cygnus.com>.
+ 
+ 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.  */
+ 
+ #define TARGET_IS_${EMULATION_NAME}
+ 
+ #include "bfd.h"
+ #include "sysdep.h"
+ #include "bfdlink.h"
+ 
+ #include "ld.h"
+ #include "ldmain.h"
+ #include "ldemul.h"
+ #include "ldfile.h"
+ #include "ldmisc.h"
+ 
+ static void gld${EMULATION_NAME}_before_parse PARAMS ((void));
+ static void gld${EMULATION_NAME}_after_open PARAMS ((void));
+ static void check_sections PARAMS ((bfd *, asection *, PTR));
+ static void gld${EMULATION_NAME}_after_allocation PARAMS ((void));
+ static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
+ 
+ static void
+ gld${EMULATION_NAME}_before_parse()
+ {
+ #ifndef TARGET_			/* I.e., if not generic.  */
+   ldfile_set_output_arch ("`echo ${ARCH}`");
+ #endif /* not TARGET_ */
+ }
+ 
+ /* This function is run after all the input files have been opened.
+    We create a .emreloc section for each input file with a non zero
+    .data section.  The BFD backend will fill in these sections with
+    magic numbers which can be used to relocate the data section at run
+    time.  */
+ 
+ static void
+ gld${EMULATION_NAME}_after_open ()
+ {
+   bfd *abfd;
+ 
+   if (! command_line.embedded_relocs
+       || link_info.relocateable)
+     return;
+ 
+   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 COFF. It
+          better be, as we are directly calling a COFF backend function.  */
+       if (bfd_get_flavour (abfd) != bfd_target_coff_flavour)
+ 	einfo ("%F%B: all input objects must be COFF for --embedded-relocs\n");
+ 
+       datasec = bfd_get_section_by_name (abfd, ".data");
+ 
+       /* 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, ".emreloc");
+ 	  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, 2)
+ 	      || ! bfd_set_section_size (abfd, relsec,
+ 					 datasec->reloc_count * 12))
+ 	    einfo ("%F%B: can not create .emreloc section: %E\n");
+ 	}
+ 
+       /* Double check that all other data sections are empty, as is
+          required for embedded PIC code.  */
+       bfd_map_over_sections (abfd, check_sections, (PTR) datasec);
+     }
+ }
+ 
+ /* Check that of the data sections, only the .data section has
+    relocs.  This is called via bfd_map_over_sections.  */
+ 
+ static void
+ check_sections (abfd, sec, datasec)
+      bfd *abfd;
+      asection *sec;
+      PTR datasec;
+ {
+   if ((bfd_get_section_flags (abfd, sec) & SEC_CODE) == 0
+       && sec != (asection *) datasec
+       && sec->reloc_count != 0)
+     einfo ("%B%X: section %s has relocs; can not use --embedded-relocs\n",
+ 	   abfd, bfd_get_section_name (abfd, sec));
+ }
+ 
+ /* 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
+ gld${EMULATION_NAME}_after_allocation ()
+ {
+   bfd *abfd;
+ 
+   if (! command_line.embedded_relocs
+       || link_info.relocateable)
+     return;
+ 
+   for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link_next)
+     {
+       asection *datasec, *relsec;
+       char *errmsg;
+ 
+       datasec = bfd_get_section_by_name (abfd, ".data");
+ 
+       if (datasec == NULL || datasec->reloc_count == 0)
+ 	continue;
+ 
+       relsec = bfd_get_section_by_name (abfd, ".emreloc");
+       ASSERT (relsec != NULL);
+ 
+       if (! bfd_m68k_coff_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);
+ 	}
+     }
+ }
+ 
+ static char *
+ gld${EMULATION_NAME}_get_script(isfile)
+      int *isfile;
+ EOF
+ 
+ if test -n "$COMPILE_IN"
+ then
+ # Scripts compiled in.
+ 
+ # sed commands to quote an ld script as a C string.
+ sc="-f stringify.sed"
+ 
+ cat >>e${EMULATION_NAME}.c <<EOF
+ {			     
+   *isfile = 0;
+ 
+   if (link_info.relocateable == true && config.build_constructors == true)
+     return
+ EOF
+ sed $sc ldscripts/${EMULATION_NAME}.xu                     >> e${EMULATION_NAME}.c
+ echo '  ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c
+ sed $sc ldscripts/${EMULATION_NAME}.xr                     >> e${EMULATION_NAME}.c
+ echo '  ; else if (!config.text_read_only) return'         >> e${EMULATION_NAME}.c
+ sed $sc ldscripts/${EMULATION_NAME}.xbn                    >> e${EMULATION_NAME}.c
+ echo '  ; else if (!config.magic_demand_paged) return'     >> e${EMULATION_NAME}.c
+ sed $sc ldscripts/${EMULATION_NAME}.xn                     >> e${EMULATION_NAME}.c
+ echo '  ; else return'                                     >> e${EMULATION_NAME}.c
+ sed $sc ldscripts/${EMULATION_NAME}.x                      >> e${EMULATION_NAME}.c
+ echo '; }'                                                 >> e${EMULATION_NAME}.c
+ 
+ else
+ # Scripts read from the filesystem.
+ 
+ cat >>e${EMULATION_NAME}.c <<EOF
+ {			     
+   *isfile = 1;
+ 
+   if (link_info.relocateable == true && config.build_constructors == true)
+     return "ldscripts/${EMULATION_NAME}.xu";
+   else if (link_info.relocateable == true)
+     return "ldscripts/${EMULATION_NAME}.xr";
+   else if (!config.text_read_only)
+     return "ldscripts/${EMULATION_NAME}.xbn";
+   else if (!config.magic_demand_paged)
+     return "ldscripts/${EMULATION_NAME}.xn";
+   else
+     return "ldscripts/${EMULATION_NAME}.x";
+ }
+ EOF
+ 
+ fi
+ 
+ cat >>e${EMULATION_NAME}.c <<EOF
+ 
+ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = 
+ {
+   gld${EMULATION_NAME}_before_parse,
+   syslib_default,
+   hll_default,
+   after_parse_default,
+   gld${EMULATION_NAME}_after_open,
+   gld${EMULATION_NAME}_after_allocation,
+   set_output_arch_default,
+   ldemul_default_target,
+   before_allocation_default,
+   gld${EMULATION_NAME}_get_script,
+   "${EMULATION_NAME}",
+   "${OUTPUT_FORMAT}",
+   NULL,	/* finish */
+   NULL,	/* create output section statements */
+   NULL,	/* open dynamic archive */
+   NULL,	/* place orphan */
+   NULL,	/* set symbols */
+   NULL,	/* parse args */
+   NULL,	/* unrecognized file */
+   NULL,	/* list options */
+   NULL,	/* recognized file */
+   NULL 	/* find_potential_libraries */
+ };
+ EOF


More information about the Binutils mailing list