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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [newlib-1.17.0/] [newlib/] [libc/] [sys/] [linux/] [dl/] [dynamic-link.h] - Blame information for rev 158

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 148 jeremybenn
/* Inline functions for dynamic linking.
2
   Copyright (C) 1995,96,97,98,99,2000 Free Software Foundation, Inc.
3
   This file is part of the GNU C Library.
4
 
5
   The GNU C Library is free software; you can redistribute it and/or
6
   modify it under the terms of the GNU Lesser General Public
7
   License as published by the Free Software Foundation; either
8
   version 2.1 of the License, or (at your option) any later version.
9
 
10
   The GNU C Library is distributed in the hope that it will be useful,
11
   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
   Lesser General Public License for more details.
14
 
15
   You should have received a copy of the GNU Lesser General Public
16
   License along with the GNU C Library; if not, write to the Free
17
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18
   02111-1307 USA.  */
19
 
20
#ifndef __DYNAMIC_LINK_H__
21
#define __DYNAMIC_LINK_H__
22
 
23
#include <elf.h>
24
#include <machine/dl-machine.h>
25
#include <assert.h>
26
 
27
#ifndef VERSYMIDX
28
# define VERSYMIDX(sym) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym))
29
#endif
30
 
31
 
32
/* Global read-only variable defined in rtld.c which is nonzero if we
33
   shall give more warning messages.  */
34
extern int _dl_verbose __attribute__ ((unused));
35
 
36
 
37
/* Read the dynamic section at DYN and fill in INFO with indices DT_*.  */
38
 
39
static void __attribute__ ((unused))
40
elf_get_dynamic_info (struct link_map *l)
41
{
42
  ElfW(Dyn) *dyn = l->l_ld;
43
  ElfW(Addr) l_addr;
44
  ElfW(Dyn) **info;
45
 
46
  if (! dyn)
47
    return;
48
 
49
  l_addr = l->l_addr;
50
  info = l->l_info;
51
 
52
  while (dyn->d_tag != DT_NULL)
53
    {
54
      if (dyn->d_tag < DT_NUM)
55
        info[dyn->d_tag] = dyn;
56
      else if (dyn->d_tag >= DT_LOPROC &&
57
               dyn->d_tag < DT_LOPROC + DT_THISPROCNUM)
58
        info[dyn->d_tag - DT_LOPROC + DT_NUM] = dyn;
59
      else if ((Elf32_Word) DT_VERSIONTAGIDX (dyn->d_tag) < DT_VERSIONTAGNUM)
60
        info[VERSYMIDX (dyn->d_tag)] = dyn;
61
      else if ((Elf32_Word) DT_EXTRATAGIDX (dyn->d_tag) < DT_EXTRANUM)
62
        info[DT_EXTRATAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM
63
             + DT_VERSIONTAGNUM] = dyn;
64
      else
65
        assert (! "bad dynamic tag");
66
      ++dyn;
67
    }
68
#ifndef DL_RO_DYN_SECTION
69
  if (info[DT_PLTGOT] != NULL)
70
    info[DT_PLTGOT]->d_un.d_ptr += l_addr;
71
  if (info[DT_STRTAB] != NULL)
72
    info[DT_STRTAB]->d_un.d_ptr += l_addr;
73
  if (info[DT_SYMTAB] != NULL)
74
    info[DT_SYMTAB]->d_un.d_ptr += l_addr;
75
# if ! ELF_MACHINE_NO_RELA
76
  if (info[DT_RELA] != NULL)
77
    {
78
      assert (info[DT_RELAENT]->d_un.d_val == sizeof (ElfW(Rela)));
79
      info[DT_RELA]->d_un.d_ptr += l_addr;
80
    }
81
# endif
82
# if ! ELF_MACHINE_NO_REL
83
  if (info[DT_REL] != NULL)
84
    {
85
      assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel)));
86
      info[DT_REL]->d_un.d_ptr += l_addr;
87
    }
88
# endif
89
#endif
90
  if (info[DT_PLTREL] != NULL)
91
    {
92
# if ELF_MACHINE_NO_RELA
93
      assert (info[DT_PLTREL]->d_un.d_val == DT_REL);
94
# elif ELF_MACHINE_NO_REL
95
      assert (info[DT_PLTREL]->d_un.d_val == DT_RELA);
96
# else
97
      assert (info[DT_PLTREL]->d_un.d_val == DT_REL
98
              || info[DT_PLTREL]->d_un.d_val == DT_RELA);
99
# endif
100
    }
101
#ifndef DL_RO_DYN_SECTION
102
  if (info[DT_JMPREL] != NULL)
103
    info[DT_JMPREL]->d_un.d_ptr += l_addr;
104
  if (info[VERSYMIDX (DT_VERSYM)] != NULL)
105
    info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr += l_addr;
106
#endif
107
  if (info[DT_FLAGS] != NULL)
108
    {
109
      /* Flags are used.  Translate to the old form where available.
110
         Since these l_info entries are only tested for NULL pointers it
111
         is ok if they point to the DT_FLAGS entry.  */
112
      ElfW(Word) flags = info[DT_FLAGS]->d_un.d_val;
113
      if (flags & DF_SYMBOLIC)
114
        info[DT_SYMBOLIC] = info[DT_FLAGS];
115
      if (flags & DF_TEXTREL)
116
        info[DT_TEXTREL] = info[DT_FLAGS];
117
      if (flags & DF_BIND_NOW)
118
        info[DT_BIND_NOW] = info[DT_FLAGS];
119
    }
120
  if (info[VERSYMIDX (DT_FLAGS_1)] != NULL)
121
    l->l_flags_1 = info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val;
122
  if (info[DT_RUNPATH] != NULL)
123
    /* If both RUNPATH and RPATH are given, the latter is ignored.  */
124
    info[DT_RPATH] = NULL;
125
}
126
 
127
# if ! ELF_MACHINE_NO_REL
128
#  include "do-rel.h"
129
# endif
130
 
131
# if ! ELF_MACHINE_NO_RELA
132
#  define DO_RELA
133
#  include "do-rel.h"
134
# endif
135
 
136
#endif  /* __DYNAMIC_LINK_H__ */
137
 
138
#ifdef RESOLVE
139
 
140
/* Get the definitions of `elf_dynamic_do_rel' and `elf_dynamic_do_rela'.
141
   These functions are almost identical, so we use cpp magic to avoid
142
   duplicating their code.  It cannot be done in a more general function
143
   because we must be able to completely inline.  */
144
 
145
/* On some machines, notably SPARC, DT_REL* includes DT_JMPREL in its
146
   range.  Note that according to the ELF spec, this is completely legal!
147
   But conditionally define things so that on machines we know this will
148
   not happen we do something more optimal.  */
149
 
150
# ifdef ELF_MACHINE_PLTREL_OVERLAP
151
#  define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, test_rel) \
152
  do {                                                                        \
153
    struct { ElfW(Addr) start, size; int lazy; } ranges[3];                   \
154
    int ranges_index;                                                         \
155
                                                                              \
156
    ranges[0].lazy = ranges[2].lazy = 0;                                \
157
    ranges[1].lazy = 1;                                                       \
158
    ranges[0].size = ranges[1].size = ranges[2].size = 0;               \
159
                                                                              \
160
    if ((map)->l_info[DT_##RELOC])                                            \
161
      {                                                                       \
162
        ranges[0].start = D_PTR ((map), l_info[DT_##RELOC]);                   \
163
        ranges[0].size = (map)->l_info[DT_##RELOC##SZ]->d_un.d_val;            \
164
      }                                                                       \
165
                                                                              \
166
     if ((do_lazy)                                                            \
167
        && (map)->l_info[DT_PLTREL]                                           \
168
        && (!test_rel || (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC)) \
169
      {                                                                       \
170
        ranges[1].start = D_PTR ((map), l_info[DT_JMPREL]);                   \
171
        ranges[1].size = (map)->l_info[DT_PLTRELSZ]->d_un.d_val;              \
172
        ranges[2].start = ranges[1].start + ranges[1].size;                   \
173
        ranges[2].size = ranges[0].start + ranges[0].size - ranges[2].start;  \
174
        ranges[0].size = ranges[1].start - ranges[0].start;                     \
175
      }                                                                       \
176
                                                                              \
177
    for (ranges_index = 0; ranges_index < 3; ++ranges_index)                   \
178
      elf_dynamic_do_##reloc ((map),                                          \
179
                              ranges[ranges_index].start,                     \
180
                              ranges[ranges_index].size,                      \
181
                              ranges[ranges_index].lazy,                      \
182
                              scope);                                         \
183
  } while (0)
184
# else
185
#  define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, test_rel) \
186
  do {                                                                        \
187
    struct { ElfW(Addr) start, size; int lazy; } ranges[2];                   \
188
    int ranges_index;                                                         \
189
    ranges[0].lazy = 0;                                                         \
190
    ranges[0].size = ranges[1].size = 0;                                \
191
    ranges[0].start = 0;                                                \
192
                                                                              \
193
    if ((map)->l_info[DT_##RELOC])                                            \
194
      {                                                                       \
195
        ranges[0].start = D_PTR ((map), l_info[DT_##RELOC]);                   \
196
        ranges[0].size = (map)->l_info[DT_##RELOC##SZ]->d_un.d_val;            \
197
      }                                                                       \
198
    if ((map)->l_info[DT_PLTREL]                                              \
199
        && (!test_rel || (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC)) \
200
      {                                                                       \
201
        ElfW(Addr) start = D_PTR ((map), l_info[DT_JMPREL]);                  \
202
                                                                              \
203
        if ((do_lazy)                                                         \
204
            /* This test does not only detect whether the relocation          \
205
               sections are in the right order, it also checks whether        \
206
               there is a DT_REL/DT_RELA section.  */                         \
207
            || ranges[0].start + ranges[0].size != start)               \
208
          {                                                                   \
209
            ranges[1].start = start;                                          \
210
            ranges[1].size = (map)->l_info[DT_PLTRELSZ]->d_un.d_val;          \
211
            ranges[1].lazy = (do_lazy);                                       \
212
          }                                                                   \
213
        else                                                                  \
214
          /* Combine processing the sections.  */                             \
215
          ranges[0].size += (map)->l_info[DT_PLTRELSZ]->d_un.d_val;            \
216
      }                                                                       \
217
                                                                              \
218
    for (ranges_index = 0; ranges_index < 2; ++ranges_index)                   \
219
      elf_dynamic_do_##reloc ((map),                                          \
220
                              ranges[ranges_index].start,                     \
221
                              ranges[ranges_index].size,                      \
222
                              ranges[ranges_index].lazy,                      \
223
                              scope);                                         \
224
  } while (0)
225
# endif
226
 
227
# if ELF_MACHINE_NO_REL || ELF_MACHINE_NO_RELA
228
#  define _ELF_CHECK_REL 0
229
# else
230
#  define _ELF_CHECK_REL 1
231
# endif
232
 
233
# if ! ELF_MACHINE_NO_REL
234
#  define ELF_DYNAMIC_DO_REL(map, lazy) \
235
  _ELF_DYNAMIC_DO_RELOC (REL, rel, map, lazy, _ELF_CHECK_REL)
236
# else
237
#  define ELF_DYNAMIC_DO_REL(map, lazy) /* Nothing to do.  */
238
# endif
239
 
240
# if ! ELF_MACHINE_NO_RELA
241
#  define ELF_DYNAMIC_DO_RELA(map, lazy) \
242
  _ELF_DYNAMIC_DO_RELOC (RELA, rela, map, lazy, _ELF_CHECK_REL)
243
# else
244
#  define ELF_DYNAMIC_DO_RELA(map, lazy) /* Nothing to do.  */
245
# endif
246
 
247
/* This can't just be an inline function because GCC is too dumb
248
   to inline functions containing inlines themselves.  */
249
# define ELF_DYNAMIC_RELOCATE(map, lazy, consider_profile) \
250
  do {                                                                        \
251
    int edr_lazy = elf_machine_runtime_setup ((map), (lazy),                  \
252
                                              (consider_profile));            \
253
    ELF_DYNAMIC_DO_REL ((map), edr_lazy);                                     \
254
    ELF_DYNAMIC_DO_RELA ((map), edr_lazy);                                    \
255
  } while (0)
256
 
257
#endif

powered by: WebSVN 2.1.0

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