OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [binutils-2.20.1/] [bfd/] [elf-vxworks.c] - Blame information for rev 842

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 205 julius
/* VxWorks support for ELF
2
   Copyright 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
3
 
4
   This file is part of BFD, the Binary File Descriptor library.
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., 59 Temple Place - Suite 330, Boston,
19
   MA 02111-1307, USA.  */
20
 
21
/* This file provides routines used by all VxWorks targets.  */
22
 
23
#include "sysdep.h"
24
#include "bfd.h"
25
#include "libbfd.h"
26
#include "elf-bfd.h"
27
#include "elf-vxworks.h"
28
#include "elf/vxworks.h"
29
 
30
/* Return true if symbol NAME, as defined by ABFD, is one of the special
31
   __GOTT_BASE__ or __GOTT_INDEX__ symbols.  */
32
 
33
static bfd_boolean
34
elf_vxworks_gott_symbol_p (bfd *abfd, const char *name)
35
{
36
  char leading;
37
 
38
  leading = bfd_get_symbol_leading_char (abfd);
39
  if (leading)
40
    {
41
      if (*name != leading)
42
        return FALSE;
43
      name++;
44
    }
45
  return (strcmp (name, "__GOTT_BASE__") == 0
46
          || strcmp (name, "__GOTT_INDEX__") == 0);
47
}
48
 
49
/* Tweak magic VxWorks symbols as they are loaded.  */
50
bfd_boolean
51
elf_vxworks_add_symbol_hook (bfd *abfd,
52
                             struct bfd_link_info *info,
53
                             Elf_Internal_Sym *sym,
54
                             const char **namep,
55
                             flagword *flagsp,
56
                             asection **secp ATTRIBUTE_UNUSED,
57
                             bfd_vma *valp ATTRIBUTE_UNUSED)
58
{
59
  /* Ideally these "magic" symbols would be exported by libc.so.1
60
     which would be found via a DT_NEEDED tag, and then handled
61
     specially by the linker at runtime.  Except shared libraries
62
     don't even link to libc.so.1 by default...
63
     If the symbol is imported from, or will be put in a shared library,
64
     give the symbol weak binding to get the desired samantics.
65
     This transformation will be undone in
66
     elf_i386_vxworks_link_output_symbol_hook. */
67
  if ((info->shared || abfd->flags & DYNAMIC)
68
      && elf_vxworks_gott_symbol_p (abfd, *namep))
69
    {
70
      sym->st_info = ELF_ST_INFO (STB_WEAK, ELF_ST_TYPE (sym->st_info));
71
      *flagsp |= BSF_WEAK;
72
    }
73
 
74
  return TRUE;
75
}
76
 
77
/* Perform VxWorks-specific handling of the create_dynamic_sections hook.
78
   When creating an executable, set *SRELPLT2_OUT to the .rel(a).plt.unloaded
79
   section.  */
80
 
81
bfd_boolean
82
elf_vxworks_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info,
83
                                     asection **srelplt2_out)
84
{
85
  struct elf_link_hash_table *htab;
86
  const struct elf_backend_data *bed;
87
  asection *s;
88
 
89
  htab = elf_hash_table (info);
90
  bed = get_elf_backend_data (dynobj);
91
 
92
  if (!info->shared)
93
    {
94
      s = bfd_make_section_with_flags (dynobj,
95
                                       bed->default_use_rela_p
96
                                       ? ".rela.plt.unloaded"
97
                                       : ".rel.plt.unloaded",
98
                                       SEC_HAS_CONTENTS | SEC_IN_MEMORY
99
                                       | SEC_READONLY | SEC_LINKER_CREATED);
100
      if (s == NULL
101
          || !bfd_set_section_alignment (dynobj, s, bed->s->log_file_align))
102
        return FALSE;
103
 
104
      *srelplt2_out = s;
105
    }
106
 
107
  /* Mark the GOT and PLT symbols as having relocations; they might
108
     not, but we won't know for sure until we build the GOT in
109
     finish_dynamic_symbol.  Also make sure that the GOT symbol
110
     is entered into the dynamic symbol table; the loader uses it
111
     to initialize __GOTT_BASE__[__GOTT_INDEX__].  */
112
  if (htab->hgot)
113
    {
114
      htab->hgot->indx = -2;
115
      htab->hgot->other &= ~ELF_ST_VISIBILITY (-1);
116
      htab->hgot->forced_local = 0;
117
      if (!bfd_elf_link_record_dynamic_symbol (info, htab->hgot))
118
        return FALSE;
119
    }
120
  if (htab->hplt)
121
    {
122
      htab->hplt->indx = -2;
123
      htab->hplt->type = STT_FUNC;
124
    }
125
 
126
  return TRUE;
127
}
128
 
129
/* Tweak magic VxWorks symbols as they are written to the output file.  */
130
int
131
elf_vxworks_link_output_symbol_hook (struct bfd_link_info *info
132
                                       ATTRIBUTE_UNUSED,
133
                                     const char *name,
134
                                     Elf_Internal_Sym *sym,
135
                                     asection *input_sec ATTRIBUTE_UNUSED,
136
                                     struct elf_link_hash_entry *h)
137
{
138
  /* Reverse the effects of the hack in elf_vxworks_add_symbol_hook.  */
139
  if (h
140
      && h->root.type == bfd_link_hash_undefweak
141
      && elf_vxworks_gott_symbol_p (h->root.u.undef.abfd, name))
142
    sym->st_info = ELF_ST_INFO (STB_GLOBAL, ELF_ST_TYPE (sym->st_info));
143
 
144
  return 1;
145
}
146
 
147
/* Copy relocations into the output file.  Fixes up relocations against PLT
148
   entries, then calls the generic routine.  */
149
 
150
bfd_boolean
151
elf_vxworks_emit_relocs (bfd *output_bfd,
152
                         asection *input_section,
153
                         Elf_Internal_Shdr *input_rel_hdr,
154
                         Elf_Internal_Rela *internal_relocs,
155
                         struct elf_link_hash_entry **rel_hash)
156
{
157
  const struct elf_backend_data *bed;
158
  int j;
159
 
160
  bed = get_elf_backend_data (output_bfd);
161
 
162
  if (output_bfd->flags & (DYNAMIC|EXEC_P))
163
    {
164
      Elf_Internal_Rela *irela;
165
      Elf_Internal_Rela *irelaend;
166
      struct elf_link_hash_entry **hash_ptr;
167
 
168
      for (irela = internal_relocs,
169
             irelaend = irela + (NUM_SHDR_ENTRIES (input_rel_hdr)
170
                                 * bed->s->int_rels_per_ext_rel),
171
             hash_ptr = rel_hash;
172
           irela < irelaend;
173
           irela += bed->s->int_rels_per_ext_rel,
174
             hash_ptr++)
175
        {
176
          if (*hash_ptr
177
              && (*hash_ptr)->def_dynamic
178
              && !(*hash_ptr)->def_regular
179
              && ((*hash_ptr)->root.type == bfd_link_hash_defined
180
                  || (*hash_ptr)->root.type == bfd_link_hash_defweak)
181
              && (*hash_ptr)->root.u.def.section->output_section != NULL)
182
            {
183
              /* This is a relocation from an executable or shared
184
                 library against a symbol in a different shared
185
                 library.  We are creating a definition in the output
186
                 file but it does not come from any of our normal (.o)
187
                 files. ie. a PLT stub.  Normally this would be a
188
                 relocation against against SHN_UNDEF with the VMA of
189
                 the PLT stub.  This upsets the VxWorks loader.
190
                 Convert it to a section-relative relocation.  This
191
                 gets some other symbols (for instance .dynbss), but
192
                 is conservatively correct.  */
193
              for (j = 0; j < bed->s->int_rels_per_ext_rel; j++)
194
                {
195
                  asection *sec = (*hash_ptr)->root.u.def.section;
196
                  int this_idx = sec->output_section->target_index;
197
 
198
                  irela[j].r_info
199
                    = ELF32_R_INFO (this_idx, ELF32_R_TYPE (irela[j].r_info));
200
                  irela[j].r_addend += (*hash_ptr)->root.u.def.value;
201
                  irela[j].r_addend += sec->output_offset;
202
                }
203
              /* Stop the generic routine adjusting this entry.  */
204
              *hash_ptr = NULL;
205
            }
206
        }
207
    }
208
  return _bfd_elf_link_output_relocs (output_bfd, input_section,
209
                                      input_rel_hdr, internal_relocs,
210
                                      rel_hash);
211
}
212
 
213
 
214
/* Set the sh_link and sh_info fields on the static plt relocation secton.  */
215
 
216
void
217
elf_vxworks_final_write_processing (bfd *abfd,
218
                                    bfd_boolean linker ATTRIBUTE_UNUSED)
219
{
220
  asection * sec;
221
  struct bfd_elf_section_data *d;
222
 
223
  sec = bfd_get_section_by_name (abfd, ".rel.plt.unloaded");
224
  if (!sec)
225
    sec = bfd_get_section_by_name (abfd, ".rela.plt.unloaded");
226
  if (!sec)
227
    return;
228
  d = elf_section_data (sec);
229
  d->this_hdr.sh_link = elf_tdata (abfd)->symtab_section;
230
  sec = bfd_get_section_by_name (abfd, ".plt");
231
  if (sec)
232
    d->this_hdr.sh_info = elf_section_data (sec)->this_idx;
233
}
234
 
235
/* Add the dynamic entries required by VxWorks.  These point to the
236
   tls sections.  */
237
 
238
bfd_boolean
239
elf_vxworks_add_dynamic_entries (bfd *output_bfd, struct bfd_link_info *info)
240
{
241
  if (bfd_get_section_by_name (output_bfd, ".tls_data"))
242
    {
243
      if (!_bfd_elf_add_dynamic_entry (info, DT_VX_WRS_TLS_DATA_START, 0)
244
          || !_bfd_elf_add_dynamic_entry (info, DT_VX_WRS_TLS_DATA_SIZE, 0)
245
          || !_bfd_elf_add_dynamic_entry (info, DT_VX_WRS_TLS_DATA_ALIGN, 0))
246
        return FALSE;
247
    }
248
  if (bfd_get_section_by_name (output_bfd, ".tls_vars"))
249
    {
250
      if (!_bfd_elf_add_dynamic_entry (info, DT_VX_WRS_TLS_VARS_START, 0)
251
          || !_bfd_elf_add_dynamic_entry (info, DT_VX_WRS_TLS_VARS_SIZE, 0))
252
        return FALSE;
253
    }
254
  return TRUE;
255
}
256
 
257
/* If *DYN is one of the VxWorks-specific dynamic entries, then fill
258
   in the value now  and return TRUE.  Otherwise return FALSE.  */
259
 
260
bfd_boolean
261
elf_vxworks_finish_dynamic_entry (bfd *output_bfd, Elf_Internal_Dyn *dyn)
262
{
263
  asection *sec;
264
 
265
  switch (dyn->d_tag)
266
    {
267
    default:
268
      return FALSE;
269
 
270
    case DT_VX_WRS_TLS_DATA_START:
271
      sec = bfd_get_section_by_name (output_bfd, ".tls_data");
272
      dyn->d_un.d_ptr = sec->vma;
273
      break;
274
 
275
    case DT_VX_WRS_TLS_DATA_SIZE:
276
      sec = bfd_get_section_by_name (output_bfd, ".tls_data");
277
      dyn->d_un.d_val = sec->size;
278
      break;
279
 
280
    case DT_VX_WRS_TLS_DATA_ALIGN:
281
      sec = bfd_get_section_by_name (output_bfd, ".tls_data");
282
      dyn->d_un.d_val
283
        = (bfd_size_type)1 << bfd_get_section_alignment (abfd, sec);
284
      break;
285
 
286
    case DT_VX_WRS_TLS_VARS_START:
287
      sec = bfd_get_section_by_name (output_bfd, ".tls_vars");
288
      dyn->d_un.d_ptr = sec->vma;
289
      break;
290
 
291
    case DT_VX_WRS_TLS_VARS_SIZE:
292
      sec = bfd_get_section_by_name (output_bfd, ".tls_vars");
293
      dyn->d_un.d_val = sec->size;
294
      break;
295
    }
296
  return TRUE;
297
}
298
 
299
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.