1# This shell script emits a C file. -*- C -*- 2# Copyright 2003, 2005 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/* Chooses the correct place for .plt and .got. */ 45static int old_plt = 0; 46static int old_got = 0; 47 48static void 49ppc_after_open (void) 50{ 51 if (is_ppc_elf32_vec (link_info.hash->creator)) 52 { 53 int new_plt; 54 int keep_new; 55 unsigned int num_plt; 56 unsigned int num_got; 57 lang_output_section_statement_type *os; 58 lang_output_section_statement_type *plt_os[2]; 59 lang_output_section_statement_type *got_os[2]; 60 61 new_plt = ppc_elf_select_plt_layout (output_bfd, &link_info, old_plt); 62 if (new_plt < 0) 63 einfo ("%X%P: select_plt_layout problem %E\n"); 64 65 num_got = 0; 66 num_plt = 0; 67 for (os = &lang_output_section_statement.head->output_section_statement; 68 os != NULL; 69 os = os->next) 70 { 71 if (os->constraint == SPECIAL && strcmp (os->name, ".plt") == 0) 72 { 73 if (num_plt < 2) 74 plt_os[num_plt] = os; 75 ++num_plt; 76 } 77 if (os->constraint == SPECIAL && strcmp (os->name, ".got") == 0) 78 { 79 if (num_got < 2) 80 got_os[num_got] = os; 81 ++num_got; 82 } 83 } 84 85 keep_new = new_plt == 1 ? 0 : -1; 86 if (num_plt == 2) 87 { 88 plt_os[0]->constraint = keep_new; 89 plt_os[1]->constraint = ~keep_new; 90 } 91 if (num_got == 2) 92 { 93 if (old_got) 94 keep_new = -1; 95 got_os[0]->constraint = keep_new; 96 got_os[1]->constraint = ~keep_new; 97 } 98 } 99 100 gld${EMULATION_NAME}_after_open (); 101} 102 103static void 104ppc_before_allocation (void) 105{ 106 if (is_ppc_elf32_vec (link_info.hash->creator)) 107 { 108 if (ppc_elf_tls_setup (output_bfd, &link_info) && !notlsopt) 109 { 110 if (!ppc_elf_tls_optimize (output_bfd, &link_info)) 111 { 112 einfo ("%X%P: TLS problem %E\n"); 113 return; 114 } 115 } 116 } 117 gld${EMULATION_NAME}_before_allocation (); 118} 119 120static void 121gld${EMULATION_NAME}_after_allocation (void) 122{ 123 if (is_ppc_elf32_vec (link_info.hash->creator)) 124 { 125 if (!ppc_elf_set_sdata_syms (output_bfd, &link_info)) 126 einfo ("%X%P: cannot set sdata syms %E\n"); 127 } 128} 129 130EOF 131 132# Define some shell vars to insert bits of code into the standard elf 133# parse_args and list_options functions. 134# 135PARSE_AND_LIST_PROLOGUE=' 136#define OPTION_NO_TLS_OPT 301 137#define OPTION_OLD_PLT 302 138#define OPTION_OLD_GOT 303 139' 140 141PARSE_AND_LIST_LONGOPTS=' 142 { "no-tls-optimize", no_argument, NULL, OPTION_NO_TLS_OPT }, 143 { "bss-plt", no_argument, NULL, OPTION_OLD_PLT }, 144 { "sdata-got", no_argument, NULL, OPTION_OLD_GOT }, 145' 146 147PARSE_AND_LIST_OPTIONS=' 148 fprintf (file, _("\ 149 --no-tls-optimize Don'\''t try to optimize TLS accesses.\n\ 150 --bss-plt Force old-style BSS PLT.\n\ 151 --sdata-got Force GOT location just before .sdata.\n" 152 )); 153' 154 155PARSE_AND_LIST_ARGS_CASES=' 156 case OPTION_NO_TLS_OPT: 157 notlsopt = 1; 158 break; 159 160 case OPTION_OLD_PLT: 161 old_plt = 1; 162 break; 163 164 case OPTION_OLD_GOT: 165 old_got = 1; 166 break; 167' 168 169# Put these extra ppc32elf routines in ld_${EMULATION_NAME}_emulation 170# 171LDEMUL_AFTER_OPEN=ppc_after_open 172LDEMUL_BEFORE_ALLOCATION=ppc_before_allocation 173LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation 174