+++ /dev/null
-# This shell script emits a C file. -*- C -*-
-# It does some substitutions.
-cat >em_${EMULATION_NAME}.c <<EOF
-/* This file is is generated by a shell script. DO NOT EDIT! */
-
-/* PowerPC/POWER emulation for the linker.
- Copyright (C) 1994 Free Software Foundation, Inc.
- Written by Ian Lance Taylor, Cygnus Support
-
-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., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/* This file is similar to generic.em. However, we need to build
- linker stubs to handle calls to different modules. A PowerPC call
- is emitted as a two instruction sequence:
- bl .{function}
- cror 31,31,31
-
- When linking, if the function symbol is defined and in the same
- module, we leave it alone (actually, if it is more than 26 bits
- away we should treat it as though it were in a different module).
- If the function symbol is not defined, we must construct a linker
- stub. We reroute the call to go to the linker stub instead, and we
- change the cror instruction to reload the TOC register value. The
- linker stub looks like this
- l r12,{function}(r2)
- st r2,20(r1)
- l r0,0(r12)
- l r2,4(r12)
- mtctr r0
- bcc
-
- Since we do not yet support dynamic linking, all function symbols
- are in the same module. However, we still need to create a stub
- for an undefined symbol.
-
- This is actually probably not correct for the PowerPC ABI.
- However, I do not have that ABI yet. */
-
-#define TARGET_IS_${EMULATION_NAME}
-
-#include "bfd.h"
-#include "sysdep.h"
-#include "bfdlink.h"
-
-/* FIXME! */
-#include "genlink.h"
-
-#include "ld.h"
-#include "config.h"
-#include "ldmain.h"
-#include "ldemul.h"
-#include "ldfile.h"
-#include "ldmisc.h"
-#include "ldexp.h"
-#include "ldlang.h"
-
-static void gld${EMULATION_NAME}_before_parse PARAMS ((void));
-static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
-static void gld${EMULATION_NAME}_create_output_section_statements
- PARAMS ((void));
-static void gld${EMULATION_NAME}_before_allocation PARAMS ((void));
-static boolean gld${EMULATION_NAME}_check_symbol
- PARAMS ((struct bfd_link_hash_entry *, PTR));
-
-static void
-gld${EMULATION_NAME}_before_parse()
-{
- ldfile_output_architecture = bfd_arch_${ARCH};
-}
-
-/* Section in which we build stubs. */
-
-static asection *stub_sec;
-
-/* Section in which we build TOC entries for stubs. */
-
-static asection *stub_toc_sec;
-
-/* This is called before the input files are opened. We create a new
- fake input file to hold the stub section. */
-
-static void
-gld${EMULATION_NAME}_create_output_section_statements ()
-{
- lang_input_statement_type *stub_file;
-
- stub_file = lang_add_input_file ("linker stubs",
- lang_input_file_is_fake_enum,
- (char *) NULL);
-
- stub_file->the_bfd = bfd_create ("linker stubs", output_bfd);
- if (stub_file->the_bfd == (bfd *) NULL
- || ! bfd_set_arch_mach (stub_file->the_bfd,
- bfd_get_arch (output_bfd),
- bfd_get_mach (output_bfd)))
- {
- einfo ("%X%P: can not create BFD: %E");
- return;
- }
-
- stub_sec = bfd_make_section_old_way (stub_file->the_bfd, ".text");
- stub_toc_sec = bfd_make_section_old_way (stub_file->the_bfd, ".toc");
- if (stub_sec == (asection *) NULL
- || stub_toc_sec == (asection *) NULL
- || ! bfd_set_section_flags (stub_file->the_bfd, stub_sec,
- (SEC_HAS_CONTENTS
- | SEC_ALLOC
- | SEC_LOAD
- | SEC_CODE
- | SEC_RELOC
- | SEC_IN_MEMORY))
- || ! bfd_set_section_flags (stub_file->the_bfd, stub_toc_sec,
- (SEC_HAS_CONTENTS
- | SEC_ALLOC
- | SEC_LOAD
- | SEC_DATA
- | SEC_RELOC
- | SEC_IN_MEMORY)))
- {
- einfo ("%X%P: can not create stub sections: %E");
- return;
- }
-
- ldlang_add_file (stub_file);
-}
-
-/* This is called after the input sections have been attached to the
- output sections but before the output section sizes have been set.
- We can identify the required stubs because they are undefined
- symbols beginning with ".". For each such symbol, we build a stub
- in the .text section. */
-
-static void
-gld${EMULATION_NAME}_before_allocation ()
-{
- bfd_link_hash_traverse (link_info.hash,
- gld${EMULATION_NAME}_check_symbol,
- (PTR) NULL);
-}
-
-/* If a particular symbol is undefined and starts with a ".", then we
- need to make a stub for it. */
-
-/*ARGSUSED*/
-static boolean
-gld${EMULATION_NAME}_check_symbol (h, info)
- struct bfd_link_hash_entry *h;
- PTR info;
-{
- bfd *stub_bfd;
- bfd_byte *p;
- arelent *r;
- struct bfd_link_hash_entry *hnew;
- asymbol *sym;
-
- if (h->type != bfd_link_hash_undefined
- || h->root.string[0] != '.')
- return true;
-
- stub_bfd = stub_sec->owner;
-
- /* Define this symbol to be the current location in stub_sec. */
- h->type = bfd_link_hash_defined;
- h->u.def.value = bfd_section_size (stub_bfd, stub_sec);
- h->u.def.section = stub_sec;
-
- /* We want to add this:
- LONG (0x81820000) lwz r12,{TOC index}(r2)
- LONG (0x90410014) stw r2,20(r1)
- LONG (0x800c0000) lwz r0,0(r12)
- LONG (0x804c0004) lwz r2,4(r12)
- LONG (0x7c0903a6) mtctr r0
- LONG (0x4e800420) bctr
- LONG (0) Traceback table
- LONG (0xc8000)
- LONG (0)
- */
-
- if (! bfd_set_section_size (stub_bfd, stub_sec,
- h->u.def.value + 9 * 4))
- {
- einfo ("%P%X: can not set section size: %E");
- return false;
- }
-
- stub_sec->contents = ((bfd_byte *)
- xrealloc ((PTR) stub_sec->contents,
- bfd_section_size (stub_bfd, stub_sec)));
- p = stub_sec->contents + h->u.def.value;
- bfd_put_32 (stub_bfd,
- (bfd_vma) 0x81820000 + bfd_section_size (stub_bfd, stub_toc_sec),
- p);
- p += 4;
- bfd_put_32 (stub_bfd, (bfd_vma) 0x90410014, p);
- p += 4;
- bfd_put_32 (stub_bfd, (bfd_vma) 0x800c0000, p);
- p += 4;
- bfd_put_32 (stub_bfd, (bfd_vma) 0x804c0004, p);
- p += 4;
- bfd_put_32 (stub_bfd, (bfd_vma) 0x7c0903a6, p);
- p += 4;
- bfd_put_32 (stub_bfd, (bfd_vma) 0x4e800420, p);
- p += 4;
- bfd_put_32 (stub_bfd, (bfd_vma) 0, p);
- p += 4;
- bfd_put_32 (stub_bfd, (bfd_vma) 0xc8000, p);
- p += 4;
- bfd_put_32 (stub_bfd, (bfd_vma) 0, p);
-
- /* Add an undefined symbol for the TOC reference. This is the name
- without the leading ".". */
- hnew = bfd_link_hash_lookup (link_info.hash, h->root.string + 1, true,
- false, true);
- if (hnew == (struct bfd_link_hash_entry *) NULL)
- einfo ("%P%F: bfd_link_hash_lookup failed: %E");
- if (hnew->type == bfd_link_hash_new)
- {
- hnew->type = bfd_link_hash_undefined;
- hnew->u.undef.abfd = stub_bfd;
- bfd_link_add_undef (link_info.hash, hnew);
- }
-
- /* Add a relocation entry for the TOC reference in the first
- instruction. */
- ++stub_sec->reloc_count;
- stub_sec->relocation = ((arelent *)
- xrealloc ((PTR) stub_sec->relocation,
- (stub_sec->reloc_count
- * sizeof (arelent))));
- r = &stub_sec->relocation[stub_sec->reloc_count - 1];
- r->sym_ptr_ptr = stub_toc_sec->symbol_ptr_ptr;
- r->address = h->u.def.value;
- if (stub_bfd->xvec->byteorder_big_p)
- r->address += 2;
- r->addend = 0;
- r->howto = bfd_reloc_type_lookup (stub_bfd, BFD_RELOC_PPC_TOC16);
- if (r->howto == (reloc_howto_type *) NULL)
- einfo ("%P%F: no howto for TOC reference: %E");
-
- /* Add a relocation entry in the TOC section. */
- ++stub_toc_sec->reloc_count;
- stub_toc_sec->relocation = ((arelent *)
- xrealloc ((PTR) stub_toc_sec->relocation,
- (stub_toc_sec->reloc_count
- * sizeof (arelent))));
- r = &stub_toc_sec->relocation[stub_toc_sec->reloc_count - 1];
-
- sym = bfd_make_empty_symbol (stub_bfd);
- sym->name = hnew->root.string;
- sym->value = 0;
- sym->flags = BSF_NO_FLAGS;
- sym->section = &bfd_und_section;
- sym->udata = NULL;
-
- /* FIXME! */
- ((struct generic_link_hash_entry *) hnew)->sym = sym;
-
- r->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
- *r->sym_ptr_ptr = sym;
- r->address = bfd_section_size (stub_bfd, stub_toc_sec);
- r->addend = 0;
- r->howto = bfd_reloc_type_lookup (stub_bfd, BFD_RELOC_32);
- if (r->howto == (reloc_howto_type *) NULL)
- einfo ("%P%F: no howto for TOC entry: %E");
-
- /* Add more space to the .toc section. */
- if (! bfd_set_section_size (stub_bfd, stub_toc_sec,
- bfd_section_size (stub_bfd, stub_toc_sec) + 4))
- {
- einfo ("%P%X: can not set section size: %E");
- return false;
- }
-
- stub_toc_sec->contents = ((bfd_byte *)
- xrealloc ((PTR) stub_toc_sec->contents,
- bfd_section_size (stub_bfd,
- stub_toc_sec)));
- bfd_put_32 (stub_bfd, (bfd_vma) 0,
- (stub_toc_sec->contents
- + bfd_section_size (stub_bfd, stub_toc_sec)
- - 4));
-
- return true;
-}
-
-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='s/["\\]/\\&/g
-s/$/\\n\\/
-1s/^/"/
-$s/$/n"/
-'
-
-cat >>em_${EMULATION_NAME}.c <<EOF
-{
- *isfile = 0;
-
- if (link_info.relocateable == true && config.build_constructors == true)
- return `sed "$sc" ldscripts/${EMULATION_NAME}.xu`;
- else if (link_info.relocateable == true)
- return `sed "$sc" ldscripts/${EMULATION_NAME}.xr`;
- else if (!config.text_read_only)
- return `sed "$sc" ldscripts/${EMULATION_NAME}.xbn`;
- else if (!config.magic_demand_paged)
- return `sed "$sc" ldscripts/${EMULATION_NAME}.xn`;
- else
- return `sed "$sc" ldscripts/${EMULATION_NAME}.x`;
-}
-EOF
-
-else
-# Scripts read from the filesystem.
-
-cat >>em_${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 >>em_${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,
- after_allocation_default,
- set_output_arch_default,
- ldemul_default_target,
- gld${EMULATION_NAME}_before_allocation,
- gld${EMULATION_NAME}_get_script,
- "${EMULATION_NAME}",
- "${OUTPUT_FORMAT}",
- 0,
- gld${EMULATION_NAME}_create_output_section_statements
-};
-EOF