Applied Michael's Sokolov's patch to implement --embedded-relocs for m68k coff.

This commit is contained in:
Nick Clifton 2000-07-21 23:31:53 +00:00
parent f41603356d
commit 20bccb3485
7 changed files with 355 additions and 4 deletions

View File

@ -1,3 +1,9 @@
2000-07-27 Michael Sokolov <msokolov@ivan.Harhan.ORG>
* coff-m68k.c (bfd_m68k_coff_create_embedded_relocs): New function.
* bfd-in.h (bfd_m68k_coff_create_embedded_relocs): Add declaration.
* bfd-in2.h: Regenerate.
2000-07-21 Nick Clifton <nickc@cygnus.com>
* elf32-mips.c (_bfd_mips_elf_check_relocs): Detect out of

View File

@ -1,5 +1,5 @@
/* BFD back-end for Motorola 68000 COFF binaries.
Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 1999
Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 99, 2000
Free Software Foundation, Inc.
Written by Cygnus Support.
@ -419,6 +419,97 @@ m68kcoff_common_addend_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
#endif /* ! defined (coff_rtype_to_howto) */
#endif /* COFF_COMMON_ADDEND */
#if !defined ONLY_DECLARE_RELOCS && ! defined STATIC_RELOCS
/* Given a .data section and a .emreloc in-memory section, store
relocation information into the .emreloc section which can be
used at runtime to relocate the section. This is called by the
linker when the --embedded-relocs switch is used. This is called
after the add_symbols entry point has been called for all the
objects, and before the final_link entry point is called. */
boolean
bfd_m68k_coff_create_embedded_relocs (abfd, info, datasec, relsec, errmsg)
bfd *abfd;
struct bfd_link_info *info;
asection *datasec;
asection *relsec;
char **errmsg;
{
char *extsyms;
bfd_size_type symesz;
struct internal_reloc *irel, *irelend;
bfd_byte *p;
BFD_ASSERT (! info->relocateable);
*errmsg = NULL;
if (datasec->reloc_count == 0)
return true;
extsyms = obj_coff_external_syms (abfd);
symesz = bfd_coff_symesz (abfd);
irel = _bfd_coff_read_internal_relocs (abfd, datasec, true, NULL, false,
NULL);
irelend = irel + datasec->reloc_count;
relsec->contents = (bfd_byte *) bfd_alloc (abfd, datasec->reloc_count * 12);
if (relsec->contents == NULL)
return false;
p = relsec->contents;
for (; irel < irelend; irel++, p += 12)
{
asection *targetsec;
/* We are going to write a four byte longword into the runtime
reloc section. The longword will be the address in the data
section which must be relocated. It is followed by the name
of the target section NUL-padded or truncated to 8
characters. */
/* We can only relocate absolute longword relocs at run time. */
if (irel->r_type != R_RELLONG)
{
*errmsg = _("unsupported reloc type");
bfd_set_error (bfd_error_bad_value);
return false;
}
if (irel->r_symndx == -1)
targetsec = bfd_abs_section_ptr;
else
{
struct coff_link_hash_entry *h;
h = obj_coff_sym_hashes (abfd)[irel->r_symndx];
if (h == NULL)
{
struct internal_syment isym;
bfd_coff_swap_sym_in (abfd, extsyms + symesz * irel->r_symndx,
&isym);
targetsec = coff_section_from_bfd_index (abfd, isym.n_scnum);
}
else if (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
targetsec = h->root.u.def.section;
else
targetsec = NULL;
}
bfd_put_32 (abfd,
(irel->r_vaddr - datasec->vma + datasec->output_offset), p);
memset (p + 4, 0, 8);
strncpy (p + 4, targetsec->output_section->name, 8);
}
return true;
}
#endif /* neither ONLY_DECLARE_RELOCS not STATIC_RELOCS */
#define coff_bfd_is_local_label_name m68k_coff_is_local_label_name

View File

@ -1,3 +1,11 @@
2000-07-21 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.
2000-07-20 H.J. Lu <hjl@gnu.org>
* emultempl/elf32.em (longopts): Duplicate "disable-new-dtags"

View File

@ -601,7 +601,7 @@ em68kaux.c: $(srcdir)/emulparams/m68kaux.sh \
$(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}
$(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}

View File

@ -447,7 +447,7 @@ deffilep.c ldgram.c ldlex.c
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
TAR = gtar
GZIP_ENV = --best
SOURCES = $(ld_new_SOURCES) $(EXTRA_ld_new_SOURCES)
OBJECTS = $(ld_new_OBJECTS)
@ -1302,7 +1302,7 @@ em68kaux.c: $(srcdir)/emulparams/m68kaux.sh \
$(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}
$(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}

View File

@ -3,3 +3,4 @@ OUTPUT_FORMAT="coff-m68k"
TEXT_START_ADDR=0x1000000
TARGET_PAGE_SIZE=0x1000000
ARCH=m68k
TEMPLATE_NAME=m68kcoff

245
ld/emultempl/m68kcoff.em Normal file
View File

@ -0,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_DATA)
&& 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