133965Sjdp/* ldemul.c -- clearing house for ld emulation states 2218822Sdim Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 3218822Sdim 2001, 2002, 2003, 2005, 2007 460484Sobrien Free Software Foundation, Inc. 533965Sjdp 633965SjdpThis file is part of GLD, the Gnu Linker. 733965Sjdp 833965SjdpGLD is free software; you can redistribute it and/or modify 933965Sjdpit under the terms of the GNU General Public License as published by 1033965Sjdpthe Free Software Foundation; either version 2, or (at your option) 1133965Sjdpany later version. 1233965Sjdp 1333965SjdpGLD is distributed in the hope that it will be useful, 1433965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of 1533965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1633965SjdpGNU General Public License for more details. 1733965Sjdp 1833965SjdpYou should have received a copy of the GNU General Public License 1977298Sobrienalong with GLD; see the file COPYING. If not, write to the Free 20218822SdimSoftware Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 21218822Sdim02110-1301, USA. */ 2233965Sjdp 23218822Sdim#include "sysdep.h" 2433965Sjdp#include "bfd.h" 25130561Sobrien#include "getopt.h" 26218822Sdim#include "bfdlink.h" 2733965Sjdp 2833965Sjdp#include "ld.h" 2933965Sjdp#include "ldmisc.h" 3033965Sjdp#include "ldexp.h" 3133965Sjdp#include "ldlang.h" 3233965Sjdp#include "ldfile.h" 3377298Sobrien#include "ldemul.h" 3433965Sjdp#include "ldmain.h" 3533965Sjdp#include "ldemul-list.h" 3633965Sjdp 37218822Sdimstatic ld_emulation_xfer_type *ld_emulation; 3833965Sjdp 3933965Sjdpvoid 40130561Sobrienldemul_hll (char *name) 4133965Sjdp{ 4277298Sobrien ld_emulation->hll (name); 4333965Sjdp} 4433965Sjdp 4577298Sobrienvoid 46130561Sobrienldemul_syslib (char *name) 4733965Sjdp{ 4877298Sobrien ld_emulation->syslib (name); 4933965Sjdp} 5033965Sjdp 5133965Sjdpvoid 52130561Sobrienldemul_after_parse (void) 5333965Sjdp{ 5477298Sobrien ld_emulation->after_parse (); 5533965Sjdp} 5633965Sjdp 5733965Sjdpvoid 58130561Sobrienldemul_before_parse (void) 5933965Sjdp{ 6077298Sobrien ld_emulation->before_parse (); 6133965Sjdp} 6233965Sjdp 6333965Sjdpvoid 64130561Sobrienldemul_after_open (void) 6533965Sjdp{ 6633965Sjdp ld_emulation->after_open (); 6733965Sjdp} 6833965Sjdp 6977298Sobrienvoid 70130561Sobrienldemul_after_allocation (void) 7133965Sjdp{ 7277298Sobrien ld_emulation->after_allocation (); 7333965Sjdp} 7433965Sjdp 7577298Sobrienvoid 76130561Sobrienldemul_before_allocation (void) 7733965Sjdp{ 78218822Sdim ld_emulation->before_allocation (); 7933965Sjdp} 8033965Sjdp 8133965Sjdpvoid 82130561Sobrienldemul_set_output_arch (void) 8333965Sjdp{ 8477298Sobrien ld_emulation->set_output_arch (); 8533965Sjdp} 8633965Sjdp 8733965Sjdpvoid 88130561Sobrienldemul_finish (void) 8933965Sjdp{ 90218822Sdim ld_emulation->finish (); 9133965Sjdp} 9233965Sjdp 9333965Sjdpvoid 94130561Sobrienldemul_set_symbols (void) 9533965Sjdp{ 9633965Sjdp if (ld_emulation->set_symbols) 9777298Sobrien ld_emulation->set_symbols (); 9833965Sjdp} 9933965Sjdp 10033965Sjdpvoid 101130561Sobrienldemul_create_output_section_statements (void) 10233965Sjdp{ 10333965Sjdp if (ld_emulation->create_output_section_statements) 10477298Sobrien ld_emulation->create_output_section_statements (); 10533965Sjdp} 10633965Sjdp 10733965Sjdpchar * 108130561Sobrienldemul_get_script (int *isfile) 10933965Sjdp{ 11077298Sobrien return ld_emulation->get_script (isfile); 11133965Sjdp} 11233965Sjdp 113130561Sobrienbfd_boolean 114130561Sobrienldemul_open_dynamic_archive (const char *arch, search_dirs_type *search, 115130561Sobrien lang_input_statement_type *entry) 11633965Sjdp{ 11733965Sjdp if (ld_emulation->open_dynamic_archive) 11833965Sjdp return (*ld_emulation->open_dynamic_archive) (arch, search, entry); 119130561Sobrien return FALSE; 12033965Sjdp} 12133965Sjdp 122130561Sobrienbfd_boolean 123218822Sdimldemul_place_orphan (asection *s) 12433965Sjdp{ 12533965Sjdp if (ld_emulation->place_orphan) 126218822Sdim return (*ld_emulation->place_orphan) (s); 127130561Sobrien return FALSE; 12833965Sjdp} 12933965Sjdp 130130561Sobrienvoid 131130561Sobrienldemul_add_options (int ns, char **shortopts, int nl, 132130561Sobrien struct option **longopts, int nrl, 133130561Sobrien struct option **really_longopts) 13433965Sjdp{ 135130561Sobrien if (ld_emulation->add_options) 136130561Sobrien (*ld_emulation->add_options) (ns, shortopts, nl, longopts, 137130561Sobrien nrl, really_longopts); 138130561Sobrien} 139130561Sobrien 140130561Sobrienbfd_boolean 141130561Sobrienldemul_handle_option (int optc) 142130561Sobrien{ 143130561Sobrien if (ld_emulation->handle_option) 144130561Sobrien return (*ld_emulation->handle_option) (optc); 145130561Sobrien return FALSE; 146130561Sobrien} 147130561Sobrien 148130561Sobrienbfd_boolean 149130561Sobrienldemul_parse_args (int argc, char **argv) 150130561Sobrien{ 15177298Sobrien /* Try and use the emulation parser if there is one. */ 15233965Sjdp if (ld_emulation->parse_args) 153130561Sobrien return (*ld_emulation->parse_args) (argc, argv); 154130561Sobrien return FALSE; 15533965Sjdp} 15633965Sjdp 15733965Sjdp/* Let the emulation code handle an unrecognized file. */ 15833965Sjdp 159130561Sobrienbfd_boolean 160130561Sobrienldemul_unrecognized_file (lang_input_statement_type *entry) 16133965Sjdp{ 16233965Sjdp if (ld_emulation->unrecognized_file) 16333965Sjdp return (*ld_emulation->unrecognized_file) (entry); 164130561Sobrien return FALSE; 16533965Sjdp} 16633965Sjdp 16760484Sobrien/* Let the emulation code handle a recognized file. */ 16860484Sobrien 169130561Sobrienbfd_boolean 170130561Sobrienldemul_recognized_file (lang_input_statement_type *entry) 17160484Sobrien{ 17260484Sobrien if (ld_emulation->recognized_file) 17360484Sobrien return (*ld_emulation->recognized_file) (entry); 174130561Sobrien return FALSE; 17560484Sobrien} 17660484Sobrien 17733965Sjdpchar * 178130561Sobrienldemul_choose_target (int argc, char **argv) 17933965Sjdp{ 18089857Sobrien return ld_emulation->choose_target (argc, argv); 18133965Sjdp} 18233965Sjdp 18389857Sobrien 18433965Sjdp/* The default choose_target function. */ 18533965Sjdp 18633965Sjdpchar * 187130561Sobrienldemul_default_target (int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) 18833965Sjdp{ 18933965Sjdp char *from_outside = getenv (TARGET_ENVIRON); 19077298Sobrien if (from_outside != (char *) NULL) 19133965Sjdp return from_outside; 19233965Sjdp return ld_emulation->target_name; 19333965Sjdp} 19433965Sjdp 19577298Sobrienvoid 196130561Sobrienafter_parse_default (void) 19733965Sjdp{ 19833965Sjdp} 19933965Sjdp 20033965Sjdpvoid 201130561Sobrienafter_open_default (void) 20233965Sjdp{ 20333965Sjdp} 20433965Sjdp 20533965Sjdpvoid 206130561Sobrienafter_allocation_default (void) 20733965Sjdp{ 20833965Sjdp} 20933965Sjdp 21033965Sjdpvoid 211130561Sobrienbefore_allocation_default (void) 21233965Sjdp{ 213218822Sdim if (!link_info.relocatable) 214218822Sdim strip_excluded_output_sections (); 21533965Sjdp} 21633965Sjdp 21733965Sjdpvoid 218218822Sdimfinish_default (void) 219218822Sdim{ 220218822Sdim if (!link_info.relocatable) 221218822Sdim _bfd_fix_excluded_sec_syms (output_bfd, &link_info); 222218822Sdim} 223218822Sdim 224218822Sdimvoid 225130561Sobrienset_output_arch_default (void) 22633965Sjdp{ 22777298Sobrien /* Set the output architecture and machine if possible. */ 22877298Sobrien bfd_set_arch_mach (output_bfd, 22977298Sobrien ldfile_output_architecture, ldfile_output_machine); 23033965Sjdp} 23133965Sjdp 23233965Sjdpvoid 233130561Sobriensyslib_default (char *ignore ATTRIBUTE_UNUSED) 23433965Sjdp{ 23560484Sobrien info_msg (_("%S SYSLIB ignored\n")); 23633965Sjdp} 23733965Sjdp 23833965Sjdpvoid 239130561Sobrienhll_default (char *ignore ATTRIBUTE_UNUSED) 24033965Sjdp{ 24160484Sobrien info_msg (_("%S HLL ignored\n")); 24233965Sjdp} 24333965Sjdp 24433965Sjdpld_emulation_xfer_type *ld_emulations[] = { EMULATION_LIST }; 24533965Sjdp 24633965Sjdpvoid 247130561Sobrienldemul_choose_mode (char *target) 24833965Sjdp{ 24977298Sobrien ld_emulation_xfer_type **eptr = ld_emulations; 25077298Sobrien /* Ignore "gld" prefix. */ 25177298Sobrien if (target[0] == 'g' && target[1] == 'l' && target[2] == 'd') 25277298Sobrien target += 3; 25377298Sobrien for (; *eptr; eptr++) 25477298Sobrien { 25577298Sobrien if (strcmp (target, (*eptr)->emulation_name) == 0) 25677298Sobrien { 25777298Sobrien ld_emulation = *eptr; 25877298Sobrien return; 25977298Sobrien } 26077298Sobrien } 26177298Sobrien einfo (_("%P: unrecognised emulation mode: %s\n"), target); 26277298Sobrien einfo (_("Supported emulations: ")); 26377298Sobrien ldemul_list_emulations (stderr); 26477298Sobrien einfo ("%F\n"); 26533965Sjdp} 26633965Sjdp 26733965Sjdpvoid 268130561Sobrienldemul_list_emulations (FILE *f) 26933965Sjdp{ 27033965Sjdp ld_emulation_xfer_type **eptr = ld_emulations; 271130561Sobrien bfd_boolean first = TRUE; 27233965Sjdp 27333965Sjdp for (; *eptr; eptr++) 27433965Sjdp { 27533965Sjdp if (first) 276130561Sobrien first = FALSE; 27733965Sjdp else 27833965Sjdp fprintf (f, " "); 27933965Sjdp fprintf (f, "%s", (*eptr)->emulation_name); 28033965Sjdp } 28133965Sjdp} 28260484Sobrien 28360484Sobrienvoid 284130561Sobrienldemul_list_emulation_options (FILE *f) 28560484Sobrien{ 28677298Sobrien ld_emulation_xfer_type **eptr; 28760484Sobrien int options_found = 0; 28877298Sobrien 28977298Sobrien for (eptr = ld_emulations; *eptr; eptr++) 29060484Sobrien { 29177298Sobrien ld_emulation_xfer_type *emul = *eptr; 29277298Sobrien 29360484Sobrien if (emul->list_options) 29460484Sobrien { 29560484Sobrien fprintf (f, "%s: \n", emul->emulation_name); 29677298Sobrien 29760484Sobrien emul->list_options (f); 29860484Sobrien 29960484Sobrien options_found = 1; 30060484Sobrien } 30160484Sobrien } 30277298Sobrien 30360484Sobrien if (! options_found) 30460484Sobrien fprintf (f, _(" no emulation specific options.\n")); 30560484Sobrien} 30660484Sobrien 30760484Sobrienint 308130561Sobrienldemul_find_potential_libraries (char *name, lang_input_statement_type *entry) 30960484Sobrien{ 31060484Sobrien if (ld_emulation->find_potential_libraries) 31160484Sobrien return ld_emulation->find_potential_libraries (name, entry); 31260484Sobrien 31360484Sobrien return 0; 31460484Sobrien} 315104834Sobrien 316104834Sobrienstruct bfd_elf_version_expr * 317130561Sobrienldemul_new_vers_pattern (struct bfd_elf_version_expr *entry) 318104834Sobrien{ 319104834Sobrien if (ld_emulation->new_vers_pattern) 320104834Sobrien entry = (*ld_emulation->new_vers_pattern) (entry); 321104834Sobrien return entry; 322104834Sobrien} 323