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