# This shell script emits a C file. -*- C -*- # Copyright 2003, 2005, 2006, 2007, 2009 Free Software Foundation, Inc. # # This file is part of the GNU Binutils. # # 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 3 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., 51 Franklin Street - Fifth Floor, Boston, # MA 02110-1301, USA. # # This file is sourced from elf32.em, and defines extra e2k-elf # specific routines. # # Define some shell vars to insert bits of code into the standard elf # parse_args and list_options functions. # fragment <arch_info. */ { char *arch_name = xmalloc (strlen (optarg) + 4); sprintf (arch_name, "%s:%s", optarg, "'$MACHINE'"); ldfile_set_output_arch (arch_name, bfd_arch_e2k); arch_set_via_cmdline = TRUE; free (arch_name); } /* Save architecture and machine values obtained two lines above in order to be able to restore them later in set_output_arch method. */ cmdline_output_architecture = ldfile_output_architecture; cmdline_output_machine = ldfile_output_machine; break; case OPTION_RELAXED_E2K_MACHINE_CHECK: relaxed_e2k_machine_check = TRUE; break; case OPTION_LINK_MIXED_EIR: if ((optarg[0] != '\''1'\'' && optarg[0] != '\''2'\'' && optarg[0] != '\''3'\'') || optarg[1] != '\''\0'\'') einfo (_("%P%F: invalid value for '\''--link-mixed-eir'\'' option: '\''%s'\''\n"), optarg); link_mixed_eir = optarg[0] - '\''0'\''; break; case OPTION_OLD_E_MACHINE: output_new_e_machine = FALSE; break; case OPTION_NEW_PM_SEMANTICS: break; case OPTION_MARK_REGULAR_OBJECTS: mark_objects = TRUE; break; case OPTION_START_REGULAR_OBJECTS: inside_marked_objects = TRUE; break; case OPTION_END_REGULAR_OBJECTS: inside_marked_objects = FALSE; break; case OPTION_BINARY_EIR_OUTPUT: break; case OPTION_SIMULATE: simulate = 1; break; case OPTION_IGNORE_PURE_EIR_FILES: ignore_pure_eir_files = TRUE; break; case 1: /* Beware that this macro becomes part of emulation-specific "handle_ option ()" method. Returning TRUE for a filename below prevents parse_args () in ld/lexsup.c from adding it as an input file. */ if (!mark_objects || inside_marked_objects) return FALSE; { bfd_boolean ret = FALSE; bfd *abfd = bfd_openr (optarg, "default"); if (abfd == NULL) return FALSE; /* My goal is to prevent relocatable objects not surrounded by "--{start,end}-regular-objects" options from being included into the final link. As you remember such a situation emerges if an object is passed via "-Wl,f.o". This should apply neither to static nor to shared libraries explicitly passed by their filenames (i.e. not via -l option). Indeed, one may need to fetch some objects from the former in case the mixed EIR contained in them has not been linked into total EIR at "--link-mixed-eir=2" stage, while the latter never take part in EIR linkage at all. It was Bug #81255 that made me revisit the latter case. */ if (bfd_check_format (abfd, bfd_object) && (bfd_get_flavour (abfd) != bfd_target_elf_flavour || elf_elfheader (abfd)->e_type != ET_DYN)) ret = TRUE; bfd_close (abfd); return ret; } break; ' fragment <=1 && link_mixed_eir <= 3) link_info.export_dynamic = FALSE; /* LINK_MIXED_EIR should be available by the time we open each input file. */ _bfd_e2k_elf_after_parse (link_mixed_eir); gld${EMULATION_NAME}_after_parse (); } static bfd_boolean gld${EMULATION_NAME}_load_symbols (lang_input_statement_type *); static bfd_boolean pure_eir_finder (bfd *abfd ATTRIBUTE_UNUSED, asection *section, void *ptr ATTRIBUTE_UNUSED) { return strcmp (section->name, ".pack_pure_eir") == 0; } static bfd_boolean e2k_recognized_file (lang_input_statement_type *entry) { if (link_mixed_eir != 0 && (entry->the_bfd->flags & DYNAMIC) != 0) return TRUE; if (ignore_pure_eir_files && bfd_sections_find_if (entry->the_bfd, pure_eir_finder, NULL)) return TRUE; /* Otherwise, the standard implementation from 'elf32.em' will do. */ return gld${EMULATION_NAME}_load_symbols (entry); } static bfd_boolean e2k_allow_dynamic_entries_in_relocatable_link (void) { if (link_mixed_eir != 0) return TRUE; return FALSE; } /* This is called after the input files have been opened. TODO: some of the parameters below could be probably set via e2k_create_output_section_statements () which doesn't exist at present . . . */ static void e2k_after_open (void) { /* Hash table has been already allocated by the time I call this function (see the end of 'open_output ()' in 'ldlang.c'. */ _bfd_e2k_elf_after_open (e2k_ipd, e2k_is_x86app, e2k_is_4mpages, arch_set_via_cmdline, restrict_to_arch, relaxed_e2k_machine_check, output_new_e_machine, simulate); gld${EMULATION_NAME}_after_open (); } static char * gld${EMULATION_NAME}_get_script (int *); static char * e2k_get_script (int *isfile) { if (link_mixed_eir == 2) { *isfile = 0; return ("SECTIONS\n" "{\n" "\t.pack_pure_eir : { *(.pack_pure_eir) }\n" "\t.pack_mixed_eir : { *(.pack_mixed_eir) }\n" "\t/DISCARD/ : { *(*) }\n" "}\n"); } return gld${EMULATION_NAME}_get_script (isfile); } static void e2k_set_output_arch (void) { EOF if test -z "$KPDA"; then if test "$MACHINE" = "64"; then fragment <section_alignment = 17; } lang_add_section (&os->children, s, NULL, os); return os; } static const char * dsp_output_section_name (const char *sec_name) { int is_text; int sid; const char *c; static char os_name[32]; if (! (is_text = CONST_STRNEQ (sec_name, ".dsp_text")) && ! CONST_STRNEQ (sec_name, ".dsp_data") && ! CONST_STRNEQ (sec_name, ".dsp_rodata") && ! CONST_STRNEQ (sec_name, ".dsp_bss") && ! CONST_STRNEQ (sec_name, "DSP_COMMON")) return NULL; c = sec_name; while (*c != '\0' && ! ISDIGIT (*c)) c++; if (! ISDIGIT (*c) || !ISDIGIT (c[1]) || c[2] != '\0') return NULL; sid = 10 * (c[0] - '0') + (c[1] - '0'); if (sid >= 16) return NULL; sprintf (os_name, "%s%02d", is_text ? ".dsp_text" : ".dsp_data", sid); return xstrdup (os_name); } static lang_output_section_statement_type * ${LDEMUL_PLACE_ORPHAN} (asection *s, const char *secname, int constraint) { struct _bfd_e2k_elf_link_hash_table *htab; htab = _bfd_e2k_elf_hash_table (&link_info); if (e2k_dsp_linux_mode && htab->have_dsp_output) { const char *os_name = dsp_output_section_name (s->name); if (os_name) return place_dsp_section (s, os_name); } return gld${EMULATION_NAME}_place_orphan (s, secname, constraint); } EOF fi if test -n "$LDEMUL_AFTER_ALLOCATION" ; then fragment <type = bfd_link_hash_defined; h->u.def.value = value; h->u.def.section = section; } static void ${LDEMUL_AFTER_ALLOCATION} (void) { unsigned int i; struct _bfd_e2k_elf_link_hash_table *htab; htab = _bfd_e2k_elf_hash_table (&link_info); /* We don't need any segment map tuning when using a hand-made linker script for producing an executable to be loaded with BOOT. */ if (!e2k_dsp_linux_mode || !htab->have_dsp_output) { gld${EMULATION_NAME}_after_allocation (); return; } /* The call of this function currently undoes all my attempts to assign VMA addresses to DSP sections . . . */ gld${EMULATION_NAME}_after_allocation (); for (i = 0; i < 16; i++) { static char os_name[64], sym_name[64]; lang_output_section_statement_type *os; bfd_vma true_vma; true_vma = (bfd_get_section_by_name (link_info.output_bfd, ".dsp_mem")->vma + 32 * 1024 * i); sprintf (os_name, ".dsp_text%02d",i); os = lang_output_section_find (os_name); if (os && os->bfd_section) { os->bfd_section->vma = true_vma; sprintf (sym_name, "__DSP%02d_CODE_BEGIN_VMA", i); define_dsp_symbol (sym_name, os->bfd_section, 0); sprintf (sym_name, "__DSP%02d_CODE_BEGIN_LMA", i); define_dsp_symbol (sym_name, bfd_abs_section_ptr, os->bfd_section->lma); sprintf (sym_name, "__DSP%02d_CODE_END_LMA", i); define_dsp_symbol (sym_name, bfd_abs_section_ptr, (os->bfd_section->lma + os->bfd_section->size)); } true_vma = (bfd_get_section_by_name (link_info.output_bfd, ".dsp_mem")->vma + (512 + 128 * i) * 1024); sprintf (os_name, ".dsp_data%02d", i); os = lang_output_section_find (os_name); if (os && os->bfd_section) { os->bfd_section->vma = true_vma ; sprintf (sym_name, "__DSP%02d_DATA_BEGIN_VMA", i); define_dsp_symbol (sym_name, os->bfd_section, 0); sprintf (sym_name, "__DSP%02d_DATA_BEGIN_LMA", i); define_dsp_symbol (sym_name, bfd_abs_section_ptr, os->bfd_section->lma); sprintf (sym_name, "__DSP%02d_DATA_END_LMA", i); define_dsp_symbol (sym_name, bfd_abs_section_ptr, (os->bfd_section->lma + os->bfd_section->size)); } } } EOF fi LDEMUL_GET_SCRIPT=e2k_get_script LDEMUL_AFTER_PARSE=e2k_after_parse LDEMUL_RECOGNIZED_FILE=e2k_recognized_file LDEMUL_ALLOW_DYNAMIC_ENTRIES_IN_RELOCATABLE_LINK=\ e2k_allow_dynamic_entries_in_relocatable_link LDEMUL_AFTER_OPEN=e2k_after_open LDEMUL_SET_OUTPUT_ARCH=e2k_set_output_arch