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