1# This shell script emits a C file. -*- C -*- 2# Copyright 2003, 2005, 2007 Free Software Foundation, Inc. 3# 4# This file is part of GLD, the Gnu Linker. 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 2 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, MA 02110-1301, USA. 19# 20 21# This file is sourced from elf32.em, and defines extra powerpc32-elf 22# specific routines. 23# 24cat >>e${EMULATION_NAME}.c <<EOF 25 26#include "libbfd.h" 27#include "elf32-ppc.h" 28 29extern const bfd_target bfd_elf32_powerpc_vec; 30extern const bfd_target bfd_elf32_powerpcle_vec; 31extern const bfd_target bfd_elf32_powerpc_vxworks_vec; 32 33static inline int 34is_ppc_elf32_vec(const bfd_target * vec) 35{ 36 return (vec == &bfd_elf32_powerpc_vec 37 || vec == &bfd_elf32_powerpc_vxworks_vec 38 || vec == &bfd_elf32_powerpcle_vec); 39} 40 41/* Whether to run tls optimization. */ 42static int notlsopt = 0; 43 44/* Whether to emit symbols for stubs. */ 45static int emit_stub_syms = 0; 46 47/* Chooses the correct place for .plt and .got. */ 48static enum ppc_elf_plt_type plt_style = PLT_UNSET; 49static int old_got = 0; 50 51static void 52ppc_after_open (void) 53{ 54 if (is_ppc_elf32_vec (link_info.hash->creator)) 55 { 56 int new_plt; 57 int keep_new; 58 unsigned int num_plt; 59 unsigned int num_got; 60 lang_output_section_statement_type *os; 61 lang_output_section_statement_type *plt_os[2]; 62 lang_output_section_statement_type *got_os[2]; 63 64 emit_stub_syms |= link_info.emitrelocations; 65 new_plt = ppc_elf_select_plt_layout (output_bfd, &link_info, plt_style, 66 emit_stub_syms); 67 if (new_plt < 0) 68 einfo ("%X%P: select_plt_layout problem %E\n"); 69 70 num_got = 0; 71 num_plt = 0; 72 for (os = &lang_output_section_statement.head->output_section_statement; 73 os != NULL; 74 os = os->next) 75 { 76 if (os->constraint == SPECIAL && strcmp (os->name, ".plt") == 0) 77 { 78 if (num_plt < 2) 79 plt_os[num_plt] = os; 80 ++num_plt; 81 } 82 if (os->constraint == SPECIAL && strcmp (os->name, ".got") == 0) 83 { 84 if (num_got < 2) 85 got_os[num_got] = os; 86 ++num_got; 87 } 88 } 89 90 keep_new = new_plt == 1 ? 0 : -1; 91 if (num_plt == 2) 92 { 93 plt_os[0]->constraint = keep_new; 94 plt_os[1]->constraint = ~keep_new; 95 } 96 if (num_got == 2) 97 { 98 if (old_got) 99 keep_new = -1; 100 got_os[0]->constraint = keep_new; 101 got_os[1]->constraint = ~keep_new; 102 } 103 } 104 105 gld${EMULATION_NAME}_after_open (); 106} 107 108static void 109ppc_before_allocation (void) 110{ 111 if (is_ppc_elf32_vec (link_info.hash->creator)) 112 { 113 if (ppc_elf_tls_setup (output_bfd, &link_info) && !notlsopt) 114 { 115 if (!ppc_elf_tls_optimize (output_bfd, &link_info)) 116 { 117 einfo ("%X%P: TLS problem %E\n"); 118 return; 119 } 120 } 121 } 122 123 gld${EMULATION_NAME}_before_allocation (); 124 125 /* Turn on relaxation if executable sections have addresses that 126 might make branches overflow. */ 127 if (!command_line.relax) 128 { 129 bfd_vma low = (bfd_vma) -1; 130 bfd_vma high = 0; 131 asection *o; 132 133 /* Run lang_size_sections (if not already done). */ 134 if (expld.phase != lang_mark_phase_enum) 135 { 136 expld.phase = lang_mark_phase_enum; 137 expld.dataseg.phase = exp_dataseg_none; 138 one_lang_size_sections_pass (NULL, FALSE); 139 lang_reset_memory_regions (); 140 } 141 142 for (o = output_bfd->sections; o != NULL; o = o->next) 143 { 144 if ((o->flags & (SEC_ALLOC | SEC_CODE)) != (SEC_ALLOC | SEC_CODE)) 145 continue; 146 if (o->rawsize == 0) 147 continue; 148 if (low > o->vma) 149 low = o->vma; 150 if (high < o->vma + o->rawsize - 1) 151 high = o->vma + o->rawsize - 1; 152 } 153 if (high > low && high - low > (1 << 25) - 1) 154 command_line.relax = TRUE; 155 } 156} 157 158EOF 159 160if grep -q 'ld_elf32_spu_emulation' ldemul-list.h; then 161 cat >>e${EMULATION_NAME}.c <<EOF 162/* Special handling for embedded SPU executables. */ 163extern bfd_boolean embedded_spu_file (lang_input_statement_type *, const char *); 164static bfd_boolean gld${EMULATION_NAME}_load_symbols (lang_input_statement_type *); 165 166static bfd_boolean 167ppc_recognized_file (lang_input_statement_type *entry) 168{ 169 if (embedded_spu_file (entry, "-m32")) 170 return TRUE; 171 172 return gld${EMULATION_NAME}_load_symbols (entry); 173} 174 175EOF 176LDEMUL_RECOGNIZED_FILE=ppc_recognized_file 177fi 178 179# Define some shell vars to insert bits of code into the standard elf 180# parse_args and list_options functions. 181# 182PARSE_AND_LIST_PROLOGUE=' 183#define OPTION_NO_TLS_OPT 301 184#define OPTION_NEW_PLT 302 185#define OPTION_OLD_PLT 303 186#define OPTION_OLD_GOT 304 187#define OPTION_STUBSYMS 305 188' 189 190PARSE_AND_LIST_LONGOPTS=' 191 { "emit-stub-syms", no_argument, NULL, OPTION_STUBSYMS }, 192 { "no-tls-optimize", no_argument, NULL, OPTION_NO_TLS_OPT }, 193 { "secure-plt", no_argument, NULL, OPTION_NEW_PLT }, 194 { "bss-plt", no_argument, NULL, OPTION_OLD_PLT }, 195 { "sdata-got", no_argument, NULL, OPTION_OLD_GOT }, 196' 197 198PARSE_AND_LIST_OPTIONS=' 199 fprintf (file, _("\ 200 --emit-stub-syms Label linker stubs with a symbol.\n\ 201 --no-tls-optimize Don'\''t try to optimize TLS accesses.\n\ 202 --secure-plt Use new-style PLT if possible.\n\ 203 --bss-plt Force old-style BSS PLT.\n\ 204 --sdata-got Force GOT location just before .sdata.\n" 205 )); 206' 207 208PARSE_AND_LIST_ARGS_CASES=' 209 case OPTION_STUBSYMS: 210 emit_stub_syms = 1; 211 break; 212 213 case OPTION_NO_TLS_OPT: 214 notlsopt = 1; 215 break; 216 217 case OPTION_NEW_PLT: 218 plt_style = PLT_NEW; 219 break; 220 221 case OPTION_OLD_PLT: 222 plt_style = PLT_OLD; 223 break; 224 225 case OPTION_OLD_GOT: 226 old_got = 1; 227 break; 228' 229 230# Put these extra ppc32elf routines in ld_${EMULATION_NAME}_emulation 231# 232LDEMUL_AFTER_OPEN=ppc_after_open 233LDEMUL_BEFORE_ALLOCATION=ppc_before_allocation 234