160484Sobrien# This shell script emits a C file. -*- C -*- 260484Sobrien# It does some substitutions. 360484Sobriencat >e${EMULATION_NAME}.c <<EOF 460484Sobrien/* This file is is generated by a shell script. DO NOT EDIT! */ 560484Sobrien 660484Sobrien/* emulate the original gld for the given ${EMULATION_NAME} 7130561Sobrien Copyright 1991, 1993, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 8218822Sdim 2004, 2005, 2007 Free Software Foundation, Inc. 960484Sobrien Written by Steve Chamberlain steve@cygnus.com 1060484Sobrien 1160484SobrienThis file is part of GLD, the Gnu Linker. 1260484Sobrien 1360484SobrienThis program is free software; you can redistribute it and/or modify 1460484Sobrienit under the terms of the GNU General Public License as published by 1560484Sobrienthe Free Software Foundation; either version 2 of the License, or 1660484Sobrien(at your option) any later version. 1760484Sobrien 1860484SobrienThis program is distributed in the hope that it will be useful, 1960484Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of 2060484SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 2160484SobrienGNU General Public License for more details. 2260484Sobrien 2360484SobrienYou should have received a copy of the GNU General Public License 2460484Sobrienalong with this program; if not, write to the Free Software 25218822SdimFoundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 2660484Sobrien 2760484Sobrien#define TARGET_IS_${EMULATION_NAME} 2860484Sobrien 29218822Sdim#include "sysdep.h" 3060484Sobrien#include "bfd.h" 3160484Sobrien#include "bfdlink.h" 3260484Sobrien#include "getopt.h" 3360484Sobrien 3460484Sobrien#include "ld.h" 3560484Sobrien#include "ldmain.h" 3660484Sobrien#include "ldmisc.h" 3760484Sobrien 3860484Sobrien#include "ldexp.h" 3960484Sobrien#include "ldlang.h" 4077298Sobrien#include "ldfile.h" 4177298Sobrien#include "ldemul.h" 4260484Sobrien 43130561Sobrien/* If TRUE, then interworking stubs which support calls to old, 44130561Sobrien non-interworking aware ARM code should be generated. */ 4560484Sobrien 4660484Sobrienstatic int support_old_code = 0; 4760484Sobrienstatic char * thumb_entry_symbol = NULL; 4860484Sobrien 4960484Sobrien#define OPTION_SUPPORT_OLD_CODE 300 5060484Sobrien#define OPTION_THUMB_ENTRY 301 5160484Sobrien 52130561Sobrienstatic void 53130561Sobriengld${EMULATION_NAME}_add_options 54130561Sobrien (int ns ATTRIBUTE_UNUSED, char **shortopts ATTRIBUTE_UNUSED, int nl, 55130561Sobrien struct option **longopts, int nrl ATTRIBUTE_UNUSED, 56130561Sobrien struct option **really_longopts ATTRIBUTE_UNUSED) 5760484Sobrien{ 58130561Sobrien static const struct option xtra_long[] = { 59130561Sobrien {"support-old-code", no_argument, NULL, OPTION_SUPPORT_OLD_CODE}, 60130561Sobrien {"thumb-entry", required_argument, NULL, OPTION_THUMB_ENTRY}, 61130561Sobrien {NULL, no_argument, NULL, 0} 62130561Sobrien }; 6360484Sobrien 64130561Sobrien *longopts = xrealloc (*longopts, 65130561Sobrien nl * sizeof (struct option) + sizeof (xtra_long)); 66130561Sobrien memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long)); 67130561Sobrien} 68130561Sobrien 6960484Sobrienstatic void 70130561Sobriengld${EMULATION_NAME}_list_options (FILE *file) 7160484Sobrien{ 7260484Sobrien fprintf (file, _(" --support-old-code Support interworking with old code\n")); 7360484Sobrien fprintf (file, _(" --thumb-entry=<sym> Set the entry point to be Thumb symbol <sym>\n")); 7460484Sobrien} 7560484Sobrien 76130561Sobrienstatic bfd_boolean 77130561Sobriengld${EMULATION_NAME}_handle_option (int optc) 7860484Sobrien{ 7960484Sobrien switch (optc) 8060484Sobrien { 8160484Sobrien default: 82130561Sobrien return FALSE; 8360484Sobrien 8460484Sobrien case OPTION_SUPPORT_OLD_CODE: 8560484Sobrien support_old_code = 1; 8660484Sobrien break; 8760484Sobrien 8860484Sobrien case OPTION_THUMB_ENTRY: 8960484Sobrien thumb_entry_symbol = optarg; 9060484Sobrien break; 9160484Sobrien } 92130561Sobrien 93130561Sobrien return TRUE; 9460484Sobrien} 9560484Sobrien 9660484Sobrienstatic void 97130561Sobriengld${EMULATION_NAME}_before_parse (void) 9860484Sobrien{ 9960484Sobrien#ifndef TARGET_ /* I.e., if not generic. */ 100130561Sobrien ldfile_set_output_arch ("`echo ${ARCH}`", bfd_arch_unknown); 10160484Sobrien#endif /* not TARGET_ */ 10260484Sobrien} 10360484Sobrien 10460484Sobrien/* This is called after the sections have been attached to output 10560484Sobrien sections, but before any sizes or addresses have been set. */ 10660484Sobrien 10760484Sobrienstatic void 108130561Sobriengld${EMULATION_NAME}_before_allocation (void) 10960484Sobrien{ 11060484Sobrien /* we should be able to set the size of the interworking stub section */ 11160484Sobrien 11260484Sobrien /* Here we rummage through the found bfds to collect glue information */ 11360484Sobrien /* FIXME: should this be based on a command line option? krk@cygnus.com */ 11460484Sobrien { 11560484Sobrien LANG_FOR_EACH_INPUT_STATEMENT (is) 11660484Sobrien { 11760484Sobrien if (! bfd_arm_process_before_allocation 11860484Sobrien (is->the_bfd, & link_info, support_old_code)) 11960484Sobrien { 12060484Sobrien /* xgettext:c-format */ 12160484Sobrien einfo (_("Errors encountered processing file %s"), is->filename); 12260484Sobrien } 12360484Sobrien } 12460484Sobrien } 12560484Sobrien 12660484Sobrien /* We have seen it all. Allocate it, and carry on */ 12760484Sobrien bfd_arm_allocate_interworking_sections (& link_info); 128218822Sdim 129218822Sdim before_allocation_default (); 13060484Sobrien} 13160484Sobrien 13260484Sobrienstatic void 133130561Sobriengld${EMULATION_NAME}_after_open (void) 13460484Sobrien{ 13560484Sobrien if (strstr (bfd_get_target (output_bfd), "arm") == NULL) 13660484Sobrien { 13760484Sobrien /* The arm backend needs special fields in the output hash structure. 13860484Sobrien These will only be created if the output format is an arm format, 13960484Sobrien hence we do not support linking and changing output formats at the 14060484Sobrien same time. Use a link followed by objcopy to change output formats. */ 14160484Sobrien einfo ("%F%X%P: error: cannot change output format whilst linking ARM binaries\n"); 14260484Sobrien return; 14360484Sobrien } 144130561Sobrien 14560484Sobrien { 14660484Sobrien LANG_FOR_EACH_INPUT_STATEMENT (is) 14760484Sobrien { 14860484Sobrien if (bfd_arm_get_bfd_for_interworking (is->the_bfd, & link_info)) 14960484Sobrien break; 15060484Sobrien } 15160484Sobrien } 15260484Sobrien} 15360484Sobrien 15460484Sobrienstatic void 155130561Sobriengld${EMULATION_NAME}_finish (void) 15660484Sobrien{ 157218822Sdim if (thumb_entry_symbol != NULL) 158218822Sdim { 159218822Sdim struct bfd_link_hash_entry * h; 16060484Sobrien 161218822Sdim h = bfd_link_hash_lookup (link_info.hash, thumb_entry_symbol, 162218822Sdim FALSE, FALSE, TRUE); 16360484Sobrien 164218822Sdim if (h != (struct bfd_link_hash_entry *) NULL 165218822Sdim && (h->type == bfd_link_hash_defined 166218822Sdim || h->type == bfd_link_hash_defweak) 167218822Sdim && h->u.def.section->output_section != NULL) 168218822Sdim { 169218822Sdim static char buffer[32]; 170218822Sdim bfd_vma val; 171130561Sobrien 172218822Sdim /* Special procesing is required for a Thumb entry symbol. The 173218822Sdim bottom bit of its address must be set. */ 174218822Sdim val = (h->u.def.value 175218822Sdim + bfd_get_section_vma (output_bfd, 176218822Sdim h->u.def.section->output_section) 177218822Sdim + h->u.def.section->output_offset); 178130561Sobrien 179218822Sdim val |= 1; 180130561Sobrien 181218822Sdim /* Now convert this value into a string and store it in entry_symbol 182218822Sdim where the lang_finish() function will pick it up. */ 183218822Sdim buffer[0] = '0'; 184218822Sdim buffer[1] = 'x'; 18560484Sobrien 186218822Sdim sprintf_vma (buffer + 2, val); 187130561Sobrien 188218822Sdim if (entry_symbol.name != NULL && entry_from_cmdline) 189218822Sdim einfo (_("%P: warning: '--thumb-entry %s' is overriding '-e %s'\n"), 190218822Sdim thumb_entry_symbol, entry_symbol.name); 191218822Sdim entry_symbol.name = buffer; 192218822Sdim } 193218822Sdim else 194218822Sdim einfo (_("%P: warning: connot find thumb start symbol %s\n"), 195218822Sdim thumb_entry_symbol); 196218822Sdim } 19760484Sobrien 198218822Sdim finish_default (); 19960484Sobrien} 20060484Sobrien 20160484Sobrienstatic char * 202130561Sobriengld${EMULATION_NAME}_get_script (int *isfile) 20360484SobrienEOF 20460484Sobrien 20560484Sobrienif test -n "$COMPILE_IN" 20660484Sobrienthen 20760484Sobrien# Scripts compiled in. 20860484Sobrien 20960484Sobrien# sed commands to quote an ld script as a C string. 21060484Sobriensc="-f stringify.sed" 21160484Sobrien 21260484Sobriencat >>e${EMULATION_NAME}.c <<EOF 213130561Sobrien{ 21460484Sobrien *isfile = 0; 21560484Sobrien 216130561Sobrien if (link_info.relocatable && config.build_constructors) 21760484Sobrien return 21860484SobrienEOF 219130561Sobriensed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c 220130561Sobrienecho ' ; else if (link_info.relocatable) return' >> e${EMULATION_NAME}.c 221130561Sobriensed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c 222130561Sobrienecho ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c 223130561Sobriensed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c 224130561Sobrienecho ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c 225130561Sobriensed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c 226130561Sobrienecho ' ; else return' >> e${EMULATION_NAME}.c 227130561Sobriensed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c 228130561Sobrienecho '; }' >> e${EMULATION_NAME}.c 22960484Sobrien 23060484Sobrienelse 23160484Sobrien# Scripts read from the filesystem. 23260484Sobrien 23360484Sobriencat >>e${EMULATION_NAME}.c <<EOF 234130561Sobrien{ 23560484Sobrien *isfile = 1; 23660484Sobrien 237130561Sobrien if (link_info.relocatable && config.build_constructors) 23860484Sobrien return "ldscripts/${EMULATION_NAME}.xu"; 239130561Sobrien else if (link_info.relocatable) 24060484Sobrien return "ldscripts/${EMULATION_NAME}.xr"; 24160484Sobrien else if (!config.text_read_only) 24260484Sobrien return "ldscripts/${EMULATION_NAME}.xbn"; 24360484Sobrien else if (!config.magic_demand_paged) 24460484Sobrien return "ldscripts/${EMULATION_NAME}.xn"; 24560484Sobrien else 24660484Sobrien return "ldscripts/${EMULATION_NAME}.x"; 24760484Sobrien} 24860484SobrienEOF 24960484Sobrien 25060484Sobrienfi 25160484Sobrien 25260484Sobriencat >>e${EMULATION_NAME}.c <<EOF 25360484Sobrien 254130561Sobrienstruct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = 25560484Sobrien{ 25660484Sobrien gld${EMULATION_NAME}_before_parse, 25760484Sobrien syslib_default, 25860484Sobrien hll_default, 25960484Sobrien after_parse_default, 26060484Sobrien gld${EMULATION_NAME}_after_open, 26160484Sobrien after_allocation_default, 26260484Sobrien set_output_arch_default, 26360484Sobrien ldemul_default_target, 26460484Sobrien gld${EMULATION_NAME}_before_allocation, 26560484Sobrien gld${EMULATION_NAME}_get_script, 26660484Sobrien "${EMULATION_NAME}", 26760484Sobrien "${OUTPUT_FORMAT}", 26860484Sobrien gld${EMULATION_NAME}_finish, 26960484Sobrien NULL, /* create output section statements */ 27060484Sobrien NULL, /* open dynamic archive */ 27160484Sobrien NULL, /* place orphan */ 27260484Sobrien NULL, /* set symbols */ 273130561Sobrien NULL, /* parse_args */ 274130561Sobrien gld${EMULATION_NAME}_add_options, 275130561Sobrien gld${EMULATION_NAME}_handle_option, 27660484Sobrien NULL, /* unrecognised file */ 27760484Sobrien gld${EMULATION_NAME}_list_options, 27860484Sobrien NULL, /* recognized file */ 279104834Sobrien NULL, /* find_potential_libraries */ 280104834Sobrien NULL /* new_vers_pattern */ 28160484Sobrien}; 28260484SobrienEOF 283