1# This shell script emits a C file. -*- C -*- 2# Copyright (C) 2003-2014 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 22# This file is sourced from elf32.em, and defines extra powerpc32-elf 23# specific routines. 24# 25fragment <<EOF 26 27#include "libbfd.h" 28#include "elf32-ppc.h" 29#include "ldlex.h" 30#include "ldlang.h" 31 32#define is_ppc_elf(bfd) \ 33 (bfd_get_flavour (bfd) == bfd_target_elf_flavour \ 34 && elf_object_id (bfd) == PPC32_ELF_DATA) 35 36/* Whether to run tls optimization. */ 37static int notlsopt = 0; 38 39/* Choose the correct place for .got. */ 40static int old_got = 0; 41 42static bfd_vma pagesize = 0; 43 44static struct ppc_elf_params params = { PLT_UNSET, -1, 0, 0, 0, 0 }; 45 46static void 47ppc_after_open_output (void) 48{ 49 if (params.emit_stub_syms < 0) 50 params.emit_stub_syms = link_info.emitrelocations || link_info.shared; 51 if (pagesize == 0) 52 pagesize = config.commonpagesize; 53 params.pagesize_p2 = bfd_log2 (pagesize); 54 ppc_elf_link_params (&link_info, ¶ms); 55} 56 57EOF 58 59# No --secure-plt, --bss-plt, or --sdata-got for vxworks. 60if test -z "$VXWORKS_BASE_EM_FILE" ; then 61 fragment <<EOF 62static void 63ppc_after_open (void) 64{ 65 if (is_ppc_elf (link_info.output_bfd)) 66 { 67 int new_plt; 68 int keep_new; 69 unsigned int num_plt; 70 unsigned int num_got; 71 lang_output_section_statement_type *os; 72 lang_output_section_statement_type *plt_os[2]; 73 lang_output_section_statement_type *got_os[2]; 74 75 new_plt = ppc_elf_select_plt_layout (link_info.output_bfd, &link_info); 76 if (new_plt < 0) 77 einfo ("%X%P: select_plt_layout problem %E\n"); 78 79 num_got = 0; 80 num_plt = 0; 81 for (os = &lang_output_section_statement.head->output_section_statement; 82 os != NULL; 83 os = os->next) 84 { 85 if (os->constraint == SPECIAL && strcmp (os->name, ".plt") == 0) 86 { 87 if (num_plt < 2) 88 plt_os[num_plt] = os; 89 ++num_plt; 90 } 91 if (os->constraint == SPECIAL && strcmp (os->name, ".got") == 0) 92 { 93 if (num_got < 2) 94 got_os[num_got] = os; 95 ++num_got; 96 } 97 } 98 99 keep_new = new_plt == 1 ? 0 : -1; 100 if (num_plt == 2) 101 { 102 plt_os[0]->constraint = keep_new; 103 plt_os[1]->constraint = ~keep_new; 104 } 105 if (num_got == 2) 106 { 107 if (old_got) 108 keep_new = -1; 109 got_os[0]->constraint = keep_new; 110 got_os[1]->constraint = ~keep_new; 111 } 112 } 113 114 gld${EMULATION_NAME}_after_open (); 115} 116 117EOF 118fi 119fragment <<EOF 120static void 121ppc_before_allocation (void) 122{ 123 if (is_ppc_elf (link_info.output_bfd)) 124 { 125 if (ppc_elf_tls_setup (link_info.output_bfd, &link_info) 126 && !notlsopt) 127 { 128 if (!ppc_elf_tls_optimize (link_info.output_bfd, &link_info)) 129 { 130 einfo ("%X%P: TLS problem %E\n"); 131 return; 132 } 133 } 134 } 135 136 gld${EMULATION_NAME}_before_allocation (); 137 138 ppc_elf_maybe_strip_sdata_syms (&link_info); 139 140 if (RELAXATION_ENABLED) 141 params.branch_trampolines = 1; 142 143 /* Turn on relaxation if executable sections have addresses that 144 might make branches overflow. */ 145 else if (!RELAXATION_DISABLED_BY_USER) 146 { 147 bfd_vma low = (bfd_vma) -1; 148 bfd_vma high = 0; 149 asection *o; 150 151 /* Run lang_size_sections (if not already done). */ 152 if (expld.phase != lang_mark_phase_enum) 153 { 154 expld.phase = lang_mark_phase_enum; 155 expld.dataseg.phase = exp_dataseg_none; 156 one_lang_size_sections_pass (NULL, FALSE); 157 lang_reset_memory_regions (); 158 } 159 160 for (o = link_info.output_bfd->sections; o != NULL; o = o->next) 161 { 162 if ((o->flags & (SEC_ALLOC | SEC_CODE)) != (SEC_ALLOC | SEC_CODE)) 163 continue; 164 if (o->rawsize == 0) 165 continue; 166 if (low > o->vma) 167 low = o->vma; 168 if (high < o->vma + o->rawsize - 1) 169 high = o->vma + o->rawsize - 1; 170 } 171 if (high > low && high - low > (1 << 25) - 1) 172 params.branch_trampolines = 1; 173 } 174 175 if (params.ppc476_workaround || params.branch_trampolines) 176 ENABLE_RELAXATION; 177} 178 179/* Replaces default zero fill padding in executable sections with 180 "ba 0" instructions. This works around the ppc476 icache bug if we 181 have a function pointer tail call near the end of a page, some 182 small amount of padding, then the function called at the beginning 183 of the next page. If the "ba 0" is ever executed we should hit a 184 segv, so it's almost as good as an illegal instruction (zero). */ 185 186static void 187no_zero_padding (lang_statement_union_type *l) 188{ 189 if (l->header.type == lang_padding_statement_enum 190 && l->padding_statement.size != 0 191 && l->padding_statement.output_section != NULL 192 && (l->padding_statement.output_section->flags & SEC_CODE) != 0 193 && l->padding_statement.fill->size == 0) 194 { 195 struct _ppc_fill_type 196 { 197 size_t size; 198 unsigned char data[4]; 199 }; 200 static struct _ppc_fill_type fill_be = { 4, {0x48, 0, 0, 2} }; 201 static struct _ppc_fill_type fill_le = { 4, {2, 0, 0, 0x48} }; 202 203 if (bfd_big_endian (link_info.output_bfd)) 204 l->padding_statement.fill = (struct _fill_type *) &fill_be; 205 else 206 l->padding_statement.fill = (struct _fill_type *) &fill_le; 207 } 208} 209 210static void 211ppc_finish (void) 212{ 213 if (params.ppc476_workaround) 214 lang_for_each_statement (no_zero_padding); 215 finish_default (); 216} 217 218EOF 219 220if grep -q 'ld_elf32_spu_emulation' ldemul-list.h; then 221 fragment <<EOF 222/* Special handling for embedded SPU executables. */ 223extern bfd_boolean embedded_spu_file (lang_input_statement_type *, const char *); 224static bfd_boolean gld${EMULATION_NAME}_load_symbols (lang_input_statement_type *); 225 226static bfd_boolean 227ppc_recognized_file (lang_input_statement_type *entry) 228{ 229 if (embedded_spu_file (entry, "-m32")) 230 return TRUE; 231 232 return gld${EMULATION_NAME}_load_symbols (entry); 233} 234 235EOF 236LDEMUL_RECOGNIZED_FILE=ppc_recognized_file 237fi 238 239# Define some shell vars to insert bits of code into the standard elf 240# parse_args and list_options functions. 241# 242PARSE_AND_LIST_PROLOGUE=${PARSE_AND_LIST_PROLOGUE}' 243#define OPTION_NO_TLS_OPT 321 244#define OPTION_NO_TLS_GET_ADDR_OPT (OPTION_NO_TLS_OPT + 1) 245#define OPTION_NEW_PLT (OPTION_NO_TLS_GET_ADDR_OPT + 1) 246#define OPTION_OLD_PLT (OPTION_NEW_PLT + 1) 247#define OPTION_OLD_GOT (OPTION_OLD_PLT + 1) 248#define OPTION_STUBSYMS (OPTION_OLD_GOT + 1) 249#define OPTION_NO_STUBSYMS (OPTION_STUBSYMS + 1) 250#define OPTION_PPC476_WORKAROUND (OPTION_NO_STUBSYMS + 1) 251#define OPTION_NO_PPC476_WORKAROUND (OPTION_PPC476_WORKAROUND + 1) 252' 253 254PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}' 255 { "emit-stub-syms", no_argument, NULL, OPTION_STUBSYMS }, 256 { "no-emit-stub-syms", no_argument, NULL, OPTION_NO_STUBSYMS }, 257 { "no-tls-optimize", no_argument, NULL, OPTION_NO_TLS_OPT }, 258 { "no-tls-get-addr-optimize", no_argument, NULL, OPTION_NO_TLS_GET_ADDR_OPT },' 259if test -z "$VXWORKS_BASE_EM_FILE" ; then 260 PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}' 261 { "secure-plt", no_argument, NULL, OPTION_NEW_PLT }, 262 { "bss-plt", no_argument, NULL, OPTION_OLD_PLT }, 263 { "sdata-got", no_argument, NULL, OPTION_OLD_GOT },' 264fi 265PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}' 266 { "ppc476-workaround", optional_argument, NULL, OPTION_PPC476_WORKAROUND }, 267 { "no-ppc476-workaround", no_argument, NULL, OPTION_NO_PPC476_WORKAROUND }, 268' 269 270PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}' 271 fprintf (file, _("\ 272 --emit-stub-syms Label linker stubs with a symbol.\n\ 273 --no-emit-stub-syms Don'\''t label linker stubs with a symbol.\n\ 274 --no-tls-optimize Don'\''t try to optimize TLS accesses.\n\ 275 --no-tls-get-addr-optimize Don'\''t use a special __tls_get_addr call.\n' 276if test -z "$VXWORKS_BASE_EM_FILE" ; then 277 PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'\ 278 --secure-plt Use new-style PLT if possible.\n\ 279 --bss-plt Force old-style BSS PLT.\n\ 280 --sdata-got Force GOT location just before .sdata.\n' 281fi 282PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'\ 283 --ppc476-workaround [=pagesize]\n\ 284 Avoid a cache bug on ppc476.\n\ 285 --no-ppc476-workaround Disable workaround.\n" 286 )); 287' 288 289PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}' 290 case OPTION_STUBSYMS: 291 params.emit_stub_syms = 1; 292 break; 293 294 case OPTION_NO_STUBSYMS: 295 params.emit_stub_syms = 0; 296 break; 297 298 case OPTION_NO_TLS_OPT: 299 notlsopt = 1; 300 break; 301 302 case OPTION_NO_TLS_GET_ADDR_OPT: 303 params.no_tls_get_addr_opt = 1; 304 break; 305 306 case OPTION_NEW_PLT: 307 params.plt_style = PLT_NEW; 308 break; 309 310 case OPTION_OLD_PLT: 311 params.plt_style = PLT_OLD; 312 break; 313 314 case OPTION_OLD_GOT: 315 old_got = 1; 316 break; 317 318 case OPTION_TRADITIONAL_FORMAT: 319 notlsopt = 1; 320 params.no_tls_get_addr_opt = 1; 321 return FALSE; 322 323 case OPTION_PPC476_WORKAROUND: 324 params.ppc476_workaround = 1; 325 if (optarg != NULL) 326 { 327 char *end; 328 pagesize = strtoul (optarg, &end, 0); 329 if (*end 330 || (pagesize < 4096 && pagesize != 0) 331 || pagesize != (pagesize & -pagesize)) 332 einfo (_("%P%F: invalid pagesize `%s'\''\n"), optarg); 333 } 334 break; 335 336 case OPTION_NO_PPC476_WORKAROUND: 337 params.ppc476_workaround = 0; 338 break; 339' 340 341# Put these extra ppc32elf routines in ld_${EMULATION_NAME}_emulation 342# 343LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=ppc_after_open_output 344if test -z "$VXWORKS_BASE_EM_FILE" ; then 345 LDEMUL_AFTER_OPEN=ppc_after_open 346fi 347LDEMUL_BEFORE_ALLOCATION=ppc_before_allocation 348LDEMUL_FINISH=ppc_finish 349