~ubuntu-branches/ubuntu/utopic/binutils-arm64-cross/utopic

« back to all changes in this revision

Viewing changes to binutils-2.23.52.20130611/ld/emultempl/ppc32elf.em

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2013-06-20 17:38:09 UTC
  • Revision ID: package-import@ubuntu.com-20130620173809-app8lzgvymy5fg6c
Tags: 0.7
Build-depend on binutils-source (>= 2.23.52.20130620-1~).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# This shell script emits a C file. -*- C -*-
 
2
#   Copyright 2003, 2005, 2007, 2008, 2009, 2010, 2011, 2012
 
3
#   Free Software Foundation, Inc.
 
4
#
 
5
# This file is part of the GNU Binutils.
 
6
#
 
7
# This program is free software; you can redistribute it and/or modify
 
8
# it under the terms of the GNU General Public License as published by
 
9
# the Free Software Foundation; either version 3 of the License, or
 
10
# (at your option) any later version.
 
11
#
 
12
# This program is distributed in the hope that it will be useful,
 
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
# GNU General Public License for more details.
 
16
#
 
17
# You should have received a copy of the GNU General Public License
 
18
# along with this program; if not, write to the Free Software
 
19
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
 
20
# MA 02110-1301, USA.
 
21
#
 
22
 
 
23
# This file is sourced from elf32.em, and defines extra powerpc32-elf
 
24
# specific routines.
 
25
#
 
26
fragment <<EOF
 
27
 
 
28
#include "libbfd.h"
 
29
#include "elf32-ppc.h"
 
30
#include "ldlex.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.  */
 
37
static int notlsopt = 0;
 
38
static int no_tls_get_addr_opt = 0;
 
39
 
 
40
/* Whether to emit symbols for stubs.  */
 
41
static int emit_stub_syms = -1;
 
42
 
 
43
/* Chooses the correct place for .plt and .got.  */
 
44
static enum ppc_elf_plt_type plt_style = PLT_UNSET;
 
45
static int old_got = 0;
 
46
 
 
47
static void
 
48
ppc_after_open (void)
 
49
{
 
50
  if (is_ppc_elf (link_info.output_bfd))
 
51
    {
 
52
      int new_plt;
 
53
      int keep_new;
 
54
      unsigned int num_plt;
 
55
      unsigned int num_got;
 
56
      lang_output_section_statement_type *os;
 
57
      lang_output_section_statement_type *plt_os[2];
 
58
      lang_output_section_statement_type *got_os[2];
 
59
 
 
60
      if (emit_stub_syms < 0)
 
61
        emit_stub_syms = link_info.emitrelocations || link_info.shared;
 
62
      new_plt = ppc_elf_select_plt_layout (link_info.output_bfd, &link_info,
 
63
                                           plt_style, emit_stub_syms);
 
64
      if (new_plt < 0)
 
65
        einfo ("%X%P: select_plt_layout problem %E\n");
 
66
 
 
67
      num_got = 0;
 
68
      num_plt = 0;
 
69
      for (os = &lang_output_section_statement.head->output_section_statement;
 
70
           os != NULL;
 
71
           os = os->next)
 
72
        {
 
73
          if (os->constraint == SPECIAL && strcmp (os->name, ".plt") == 0)
 
74
            {
 
75
              if (num_plt < 2)
 
76
                plt_os[num_plt] = os;
 
77
              ++num_plt;
 
78
            }
 
79
          if (os->constraint == SPECIAL && strcmp (os->name, ".got") == 0)
 
80
            {
 
81
              if (num_got < 2)
 
82
                got_os[num_got] = os;
 
83
              ++num_got;
 
84
            }
 
85
        }
 
86
 
 
87
      keep_new = new_plt == 1 ? 0 : -1;
 
88
      if (num_plt == 2)
 
89
        {
 
90
          plt_os[0]->constraint = keep_new;
 
91
          plt_os[1]->constraint = ~keep_new;
 
92
        }
 
93
      if (num_got == 2)
 
94
        {
 
95
          if (old_got)
 
96
            keep_new = -1;
 
97
          got_os[0]->constraint = keep_new;
 
98
          got_os[1]->constraint = ~keep_new;
 
99
        }
 
100
    }
 
101
 
 
102
  gld${EMULATION_NAME}_after_open ();
 
103
}
 
104
 
 
105
static void
 
106
ppc_before_allocation (void)
 
107
{
 
108
  if (is_ppc_elf (link_info.output_bfd))
 
109
    {
 
110
      if (ppc_elf_tls_setup (link_info.output_bfd, &link_info,
 
111
                             no_tls_get_addr_opt)
 
112
          && !notlsopt)
 
113
        {
 
114
          if (!ppc_elf_tls_optimize (link_info.output_bfd, &link_info))
 
115
            {
 
116
              einfo ("%X%P: TLS problem %E\n");
 
117
              return;
 
118
            }
 
119
        }
 
120
    }
 
121
 
 
122
  gld${EMULATION_NAME}_before_allocation ();
 
123
 
 
124
  /* Turn on relaxation if executable sections have addresses that
 
125
     might make branches overflow.  */
 
126
  if (RELAXATION_DISABLED_BY_DEFAULT)
 
127
    {
 
128
      bfd_vma low = (bfd_vma) -1;
 
129
      bfd_vma high = 0;
 
130
      asection *o;
 
131
 
 
132
      /* Run lang_size_sections (if not already done).  */
 
133
      if (expld.phase != lang_mark_phase_enum)
 
134
        {
 
135
          expld.phase = lang_mark_phase_enum;
 
136
          expld.dataseg.phase = exp_dataseg_none;
 
137
          one_lang_size_sections_pass (NULL, FALSE);
 
138
          lang_reset_memory_regions ();
 
139
        }
 
140
 
 
141
      for (o = link_info.output_bfd->sections; o != NULL; o = o->next)
 
142
        {
 
143
          if ((o->flags & (SEC_ALLOC | SEC_CODE)) != (SEC_ALLOC | SEC_CODE))
 
144
            continue;
 
145
          if (o->rawsize == 0)
 
146
            continue;
 
147
          if (low > o->vma)
 
148
            low = o->vma;
 
149
          if (high < o->vma + o->rawsize - 1)
 
150
            high = o->vma + o->rawsize - 1;
 
151
        }
 
152
      if (high > low && high - low > (1 << 25) - 1)
 
153
        ENABLE_RELAXATION;
 
154
    }
 
155
}
 
156
 
 
157
EOF
 
158
 
 
159
if grep -q 'ld_elf32_spu_emulation' ldemul-list.h; then
 
160
  fragment <<EOF
 
161
/* Special handling for embedded SPU executables.  */
 
162
extern bfd_boolean embedded_spu_file (lang_input_statement_type *, const char *);
 
163
static bfd_boolean gld${EMULATION_NAME}_load_symbols (lang_input_statement_type *);
 
164
 
 
165
static bfd_boolean
 
166
ppc_recognized_file (lang_input_statement_type *entry)
 
167
{
 
168
  if (embedded_spu_file (entry, "-m32"))
 
169
    return TRUE;
 
170
 
 
171
  return gld${EMULATION_NAME}_load_symbols (entry);
 
172
}
 
173
 
 
174
EOF
 
175
LDEMUL_RECOGNIZED_FILE=ppc_recognized_file
 
176
fi
 
177
 
 
178
# Define some shell vars to insert bits of code into the standard elf
 
179
# parse_args and list_options functions.
 
180
#
 
181
PARSE_AND_LIST_PROLOGUE=${PARSE_AND_LIST_PROLOGUE}'
 
182
#define OPTION_NO_TLS_OPT               321
 
183
#define OPTION_NO_TLS_GET_ADDR_OPT      (OPTION_NO_TLS_OPT + 1)
 
184
#define OPTION_NEW_PLT                  (OPTION_NO_TLS_GET_ADDR_OPT + 1)
 
185
#define OPTION_OLD_PLT                  (OPTION_NEW_PLT + 1)
 
186
#define OPTION_OLD_GOT                  (OPTION_OLD_PLT + 1)
 
187
#define OPTION_STUBSYMS                 (OPTION_OLD_GOT + 1)
 
188
#define OPTION_NO_STUBSYMS              (OPTION_STUBSYMS + 1)
 
189
'
 
190
 
 
191
PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
 
192
  { "emit-stub-syms", no_argument, NULL, OPTION_STUBSYMS },
 
193
  { "no-emit-stub-syms", no_argument, NULL, OPTION_NO_STUBSYMS },
 
194
  { "no-tls-optimize", no_argument, NULL, OPTION_NO_TLS_OPT },
 
195
  { "no-tls-get-addr-optimize", no_argument, NULL, OPTION_NO_TLS_GET_ADDR_OPT },
 
196
  { "secure-plt", no_argument, NULL, OPTION_NEW_PLT },
 
197
  { "bss-plt", no_argument, NULL, OPTION_OLD_PLT },
 
198
  { "sdata-got", no_argument, NULL, OPTION_OLD_GOT },
 
199
'
 
200
 
 
201
PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'
 
202
  fprintf (file, _("\
 
203
  --emit-stub-syms            Label linker stubs with a symbol.\n\
 
204
  --no-emit-stub-syms         Don'\''t label linker stubs with a symbol.\n\
 
205
  --no-tls-optimize           Don'\''t try to optimize TLS accesses.\n\
 
206
  --no-tls-get-addr-optimize  Don'\''t use a special __tls_get_addr call.\n\
 
207
  --secure-plt                Use new-style PLT if possible.\n\
 
208
  --bss-plt                   Force old-style BSS PLT.\n\
 
209
  --sdata-got                 Force GOT location just before .sdata.\n"
 
210
                   ));
 
211
'
 
212
 
 
213
PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
 
214
    case OPTION_STUBSYMS:
 
215
      emit_stub_syms = 1;
 
216
      break;
 
217
 
 
218
    case OPTION_NO_STUBSYMS:
 
219
      emit_stub_syms = 0;
 
220
      break;
 
221
 
 
222
    case OPTION_NO_TLS_OPT:
 
223
      notlsopt = 1;
 
224
      break;
 
225
 
 
226
    case OPTION_NO_TLS_GET_ADDR_OPT:
 
227
      no_tls_get_addr_opt = 1;
 
228
      break;
 
229
 
 
230
    case OPTION_NEW_PLT:
 
231
      plt_style = PLT_NEW;
 
232
      break;
 
233
 
 
234
    case OPTION_OLD_PLT:
 
235
      plt_style = PLT_OLD;
 
236
      break;
 
237
 
 
238
    case OPTION_OLD_GOT:
 
239
      old_got = 1;
 
240
      break;
 
241
 
 
242
    case OPTION_TRADITIONAL_FORMAT:
 
243
      notlsopt = 1;
 
244
      no_tls_get_addr_opt = 1;
 
245
      return FALSE;
 
246
'
 
247
 
 
248
# Put these extra ppc32elf routines in ld_${EMULATION_NAME}_emulation
 
249
#
 
250
LDEMUL_AFTER_OPEN=ppc_after_open
 
251
LDEMUL_BEFORE_ALLOCATION=ppc_before_allocation