xref: /netbsd-src/external/gpl3/binutils.old/dist/ld/ldemul.c (revision e992f068c547fd6e84b3f104dc2340adcc955732)
1 /* ldemul.c -- clearing house for ld emulation states
2    Copyright (C) 1991-2022 Free Software Foundation, Inc.
3 
4    This file is part of the GNU Binutils.
5 
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10 
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19    MA 02110-1301, USA.  */
20 
21 #include "sysdep.h"
22 #include "bfd.h"
23 #include "getopt.h"
24 #include "bfdlink.h"
25 #include "ctf-api.h"
26 
27 #include "ld.h"
28 #include "ldmisc.h"
29 #include "ldexp.h"
30 #include "ldlang.h"
31 #include "ldfile.h"
32 #include "ldemul.h"
33 #include "ldmain.h"
34 #include "ldemul-list.h"
35 
36 static ld_emulation_xfer_type *ld_emulation;
37 
38 void
ldemul_hll(char * name)39 ldemul_hll (char *name)
40 {
41   ld_emulation->hll (name);
42 }
43 
44 void
ldemul_syslib(char * name)45 ldemul_syslib (char *name)
46 {
47   ld_emulation->syslib (name);
48 }
49 
50 void
ldemul_after_parse(void)51 ldemul_after_parse (void)
52 {
53   ld_emulation->after_parse ();
54 }
55 
56 void
ldemul_before_parse(void)57 ldemul_before_parse (void)
58 {
59   ld_emulation->before_parse ();
60 }
61 
62 void
ldemul_before_plugin_all_symbols_read(void)63 ldemul_before_plugin_all_symbols_read (void)
64 {
65   if (ld_emulation->before_plugin_all_symbols_read)
66     ld_emulation->before_plugin_all_symbols_read ();
67 }
68 
69 void
ldemul_after_open(void)70 ldemul_after_open (void)
71 {
72   ld_emulation->after_open ();
73 }
74 
75 void
ldemul_after_check_relocs(void)76 ldemul_after_check_relocs (void)
77 {
78   ld_emulation->after_check_relocs ();
79 }
80 
81 void
ldemul_before_place_orphans(void)82 ldemul_before_place_orphans (void)
83 {
84   ld_emulation->before_place_orphans ();
85 }
86 
87 void
ldemul_after_allocation(void)88 ldemul_after_allocation (void)
89 {
90   ld_emulation->after_allocation ();
91 }
92 
93 void
ldemul_before_allocation(void)94 ldemul_before_allocation (void)
95 {
96   ld_emulation->before_allocation ();
97 }
98 
99 void
ldemul_set_output_arch(void)100 ldemul_set_output_arch (void)
101 {
102   ld_emulation->set_output_arch ();
103 }
104 
105 void
ldemul_finish(void)106 ldemul_finish (void)
107 {
108   ld_emulation->finish ();
109 }
110 
111 void
ldemul_set_symbols(void)112 ldemul_set_symbols (void)
113 {
114   if (ld_emulation->set_symbols)
115     ld_emulation->set_symbols ();
116 }
117 
118 void
ldemul_create_output_section_statements(void)119 ldemul_create_output_section_statements (void)
120 {
121   if (ld_emulation->create_output_section_statements)
122     ld_emulation->create_output_section_statements ();
123 }
124 
125 char *
ldemul_get_script(int * isfile)126 ldemul_get_script (int *isfile)
127 {
128   return ld_emulation->get_script (isfile);
129 }
130 
131 bool
ldemul_open_dynamic_archive(const char * arch,search_dirs_type * search,lang_input_statement_type * entry)132 ldemul_open_dynamic_archive (const char *arch, search_dirs_type *search,
133 			     lang_input_statement_type *entry)
134 {
135   if (ld_emulation->open_dynamic_archive)
136     return (*ld_emulation->open_dynamic_archive) (arch, search, entry);
137   return false;
138 }
139 
140 lang_output_section_statement_type *
ldemul_place_orphan(asection * s,const char * name,int constraint)141 ldemul_place_orphan (asection *s, const char *name, int constraint)
142 {
143   if (ld_emulation->place_orphan)
144     return (*ld_emulation->place_orphan) (s, name, constraint);
145   return NULL;
146 }
147 
148 void
ldemul_add_options(int ns,char ** shortopts,int nl,struct option ** longopts,int nrl,struct option ** really_longopts)149 ldemul_add_options (int ns, char **shortopts, int nl,
150 		    struct option **longopts, int nrl,
151 		    struct option **really_longopts)
152 {
153   if (ld_emulation->add_options)
154     (*ld_emulation->add_options) (ns, shortopts, nl, longopts,
155 				  nrl, really_longopts);
156 }
157 
158 bool
ldemul_handle_option(int optc)159 ldemul_handle_option (int optc)
160 {
161   if (ld_emulation->handle_option)
162     return (*ld_emulation->handle_option) (optc);
163   return false;
164 }
165 
166 bool
ldemul_parse_args(int argc,char ** argv)167 ldemul_parse_args (int argc, char **argv)
168 {
169   /* Try and use the emulation parser if there is one.  */
170   if (ld_emulation->parse_args)
171     return (*ld_emulation->parse_args) (argc, argv);
172   return false;
173 }
174 
175 /* Let the emulation code handle an unrecognized file.  */
176 
177 bool
ldemul_unrecognized_file(lang_input_statement_type * entry)178 ldemul_unrecognized_file (lang_input_statement_type *entry)
179 {
180   if (ld_emulation->unrecognized_file)
181     return (*ld_emulation->unrecognized_file) (entry);
182   return false;
183 }
184 
185 /* Let the emulation code handle a recognized file.  */
186 
187 bool
ldemul_recognized_file(lang_input_statement_type * entry)188 ldemul_recognized_file (lang_input_statement_type *entry)
189 {
190   if (ld_emulation->recognized_file)
191     return (*ld_emulation->recognized_file) (entry);
192   return false;
193 }
194 
195 char *
ldemul_choose_target(int argc,char ** argv)196 ldemul_choose_target (int argc, char **argv)
197 {
198   return ld_emulation->choose_target (argc, argv);
199 }
200 
201 
202 /* The default choose_target function.  */
203 
204 char *
ldemul_default_target(int argc ATTRIBUTE_UNUSED,char ** argv ATTRIBUTE_UNUSED)205 ldemul_default_target (int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED)
206 {
207   char *from_outside = getenv (TARGET_ENVIRON);
208   if (from_outside != (char *) NULL)
209     return from_outside;
210   return ld_emulation->target_name;
211 }
212 
213 /* If the entry point was not specified as an address, then add the
214    symbol as undefined.  This will cause ld to extract an archive
215    element defining the entry if ld is linking against such an archive.
216 
217    We don't do this when generating shared libraries unless given -e
218    on the command line, because most shared libs are not designed to
219    be run as an executable.  However, some are, eg. glibc ld.so and
220    may rely on the default linker script supplying ENTRY.  So we can't
221    remove the ENTRY from the script, but would rather not insert
222    undefined _start syms.  */
223 
224 void
after_parse_default(void)225 after_parse_default (void)
226 {
227   if (entry_symbol.name != NULL
228       && (bfd_link_executable (&link_info) || entry_from_cmdline))
229     {
230       bool is_vma = false;
231 
232       if (entry_from_cmdline)
233 	{
234 	  const char *send;
235 
236 	  bfd_scan_vma (entry_symbol.name, &send, 0);
237 	  is_vma = *send == '\0';
238 	}
239       if (!is_vma)
240 	ldlang_add_undef (entry_symbol.name, entry_from_cmdline);
241     }
242   if (link_info.maxpagesize == 0)
243     link_info.maxpagesize = bfd_emul_get_maxpagesize (default_target);
244   if (link_info.commonpagesize == 0)
245     link_info.commonpagesize = bfd_emul_get_commonpagesize (default_target);
246 }
247 
248 void
after_open_default(void)249 after_open_default (void)
250 {
251   link_info.big_endian = true;
252 
253   if (bfd_big_endian (link_info.output_bfd))
254     ;
255   else if (bfd_little_endian (link_info.output_bfd))
256     link_info.big_endian = false;
257   else
258     {
259       if (command_line.endian == ENDIAN_BIG)
260 	;
261       else if (command_line.endian == ENDIAN_LITTLE)
262 	link_info.big_endian = false;
263       else if (command_line.endian == ENDIAN_UNSET)
264 	{
265 	  LANG_FOR_EACH_INPUT_STATEMENT (s)
266 	    if (s->the_bfd != NULL)
267 	      {
268 		if (bfd_little_endian (s->the_bfd))
269 		  link_info.big_endian = false;
270 		break;
271 	      }
272 	}
273     }
274 }
275 
276 void
after_check_relocs_default(void)277 after_check_relocs_default (void)
278 {
279 }
280 
281 void
before_place_orphans_default(void)282 before_place_orphans_default (void)
283 {
284 }
285 
286 void
after_allocation_default(void)287 after_allocation_default (void)
288 {
289   lang_relax_sections (false);
290 }
291 
292 void
before_allocation_default(void)293 before_allocation_default (void)
294 {
295   if (!bfd_link_relocatable (&link_info))
296     strip_excluded_output_sections ();
297 }
298 
299 void
finish_default(void)300 finish_default (void)
301 {
302   if (!bfd_link_relocatable (&link_info))
303     _bfd_fix_excluded_sec_syms (link_info.output_bfd, &link_info);
304 }
305 
306 void
set_output_arch_default(void)307 set_output_arch_default (void)
308 {
309   /* Set the output architecture and machine if possible.  */
310   bfd_set_arch_mach (link_info.output_bfd,
311 		     ldfile_output_architecture, ldfile_output_machine);
312 }
313 
314 void
syslib_default(char * ignore ATTRIBUTE_UNUSED)315 syslib_default (char *ignore ATTRIBUTE_UNUSED)
316 {
317   info_msg (_("%pS SYSLIB ignored\n"), NULL);
318 }
319 
320 void
hll_default(char * ignore ATTRIBUTE_UNUSED)321 hll_default (char *ignore ATTRIBUTE_UNUSED)
322 {
323   info_msg (_("%pS HLL ignored\n"), NULL);
324 }
325 
326 ld_emulation_xfer_type *ld_emulations[] = { EMULATION_LIST };
327 
328 void
ldemul_choose_mode(char * target)329 ldemul_choose_mode (char *target)
330 {
331   ld_emulation_xfer_type **eptr = ld_emulations;
332   /* Ignore "gld" prefix.  */
333   if (target[0] == 'g' && target[1] == 'l' && target[2] == 'd')
334     target += 3;
335   for (; *eptr; eptr++)
336     {
337       if (strcmp (target, (*eptr)->emulation_name) == 0)
338 	{
339 	  ld_emulation = *eptr;
340 	  return;
341 	}
342     }
343   einfo (_("%P: unrecognised emulation mode: %s\n"), target);
344   einfo (_("Supported emulations: "));
345   ldemul_list_emulations (stderr);
346   einfo ("%F\n");
347 }
348 
349 void
ldemul_list_emulations(FILE * f)350 ldemul_list_emulations (FILE *f)
351 {
352   ld_emulation_xfer_type **eptr = ld_emulations;
353   bool first = true;
354 
355   for (; *eptr; eptr++)
356     {
357       if (first)
358 	first = false;
359       else
360 	fprintf (f, " ");
361       fprintf (f, "%s", (*eptr)->emulation_name);
362     }
363 }
364 
365 void
ldemul_list_emulation_options(FILE * f)366 ldemul_list_emulation_options (FILE *f)
367 {
368   ld_emulation_xfer_type **eptr;
369   int options_found = 0;
370 
371   for (eptr = ld_emulations; *eptr; eptr++)
372     {
373       ld_emulation_xfer_type *emul = *eptr;
374 
375       if (emul->list_options)
376 	{
377 	  fprintf (f, "%s: \n", emul->emulation_name);
378 
379 	  emul->list_options (f);
380 
381 	  options_found = 1;
382 	}
383     }
384 
385   if (!options_found)
386     fprintf (f, _("  no emulation specific options.\n"));
387 }
388 
389 int
ldemul_find_potential_libraries(char * name,lang_input_statement_type * entry)390 ldemul_find_potential_libraries (char *name, lang_input_statement_type *entry)
391 {
392   if (ld_emulation->find_potential_libraries)
393     return ld_emulation->find_potential_libraries (name, entry);
394 
395   return 0;
396 }
397 
398 struct bfd_elf_version_expr *
ldemul_new_vers_pattern(struct bfd_elf_version_expr * entry)399 ldemul_new_vers_pattern (struct bfd_elf_version_expr *entry)
400 {
401   if (ld_emulation->new_vers_pattern)
402     entry = (*ld_emulation->new_vers_pattern) (entry);
403   return entry;
404 }
405 
406 void
ldemul_extra_map_file_text(bfd * abfd,struct bfd_link_info * info,FILE * mapf)407 ldemul_extra_map_file_text (bfd *abfd, struct bfd_link_info *info, FILE *mapf)
408 {
409   if (ld_emulation->extra_map_file_text)
410     ld_emulation->extra_map_file_text (abfd, info, mapf);
411 }
412 
413 int
ldemul_emit_ctf_early(void)414 ldemul_emit_ctf_early (void)
415 {
416   if (ld_emulation->emit_ctf_early)
417     return ld_emulation->emit_ctf_early ();
418   /* If the emulation doesn't know if it wants to emit CTF early, it is going
419      to do so.  */
420   return 1;
421 }
422 
423 void
ldemul_acquire_strings_for_ctf(struct ctf_dict * ctf_output,struct elf_strtab_hash * symstrtab)424 ldemul_acquire_strings_for_ctf (struct ctf_dict *ctf_output,
425 				struct elf_strtab_hash *symstrtab)
426 {
427   if (ld_emulation->acquire_strings_for_ctf)
428     ld_emulation->acquire_strings_for_ctf (ctf_output, symstrtab);
429 }
430 
431 void
ldemul_new_dynsym_for_ctf(struct ctf_dict * ctf_output,int symidx,struct elf_internal_sym * sym)432 ldemul_new_dynsym_for_ctf (struct ctf_dict *ctf_output, int symidx,
433 			   struct elf_internal_sym *sym)
434 {
435   if (ld_emulation->new_dynsym_for_ctf)
436     ld_emulation->new_dynsym_for_ctf (ctf_output, symidx, sym);
437 }
438 
439 bool
ldemul_print_symbol(struct bfd_link_hash_entry * hash_entry,void * ptr)440 ldemul_print_symbol (struct bfd_link_hash_entry *hash_entry, void *ptr)
441 {
442   if (ld_emulation->print_symbol)
443     return ld_emulation->print_symbol (hash_entry, ptr);
444   return print_one_symbol (hash_entry, ptr);
445 }
446