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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [newlib-1.17.0/] [newlib/] [libc/] [sys/] [linux/] [dl/] [do-lookup.h] - Blame information for rev 158

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

Line No. Rev Author Line
1 148 jeremybenn
/* Look up a symbol in the loaded objects.
2
   Copyright (C) 1995,96,97,98,99,2000,2001 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
#if VERSIONED
21
# define FCT do_lookup_versioned
22
# define ARG const struct r_found_version *const version,
23
#else
24
# define FCT do_lookup
25
# define ARG
26
#endif
27
 
28
/* Inner part of the lookup functions.  We return a value > 0 if we
29
   found the symbol, the value 0 if nothing is found and < 0 if
30
   something bad happened.  */
31
static inline int
32
FCT (const char *undef_name, unsigned long int hash, const ElfW(Sym) *ref,
33
     struct sym_val *result, struct r_scope_elem *scope, size_t i, ARG
34
     struct link_map *skip, int type_class)
35
{
36
  struct link_map **list = scope->r_list;
37
  size_t n = scope->r_nlist;
38
  struct link_map *map;
39
 
40
  do
41
    {
42
      const ElfW(Sym) *symtab;
43
      const char *strtab;
44
      const ElfW(Half) *verstab;
45
      Elf_Symndx symidx;
46
      const ElfW(Sym) *sym;
47
#if ! VERSIONED
48
      int num_versions = 0;
49
      const ElfW(Sym) *versioned_sym = NULL;
50
#endif
51
 
52
      map = list[i];
53
 
54
      /* Here come the extra test needed for `_dl_lookup_symbol_skip'.  */
55
      if (skip != NULL && map == skip)
56
        continue;
57
 
58
      /* Don't search the executable when resolving a copy reloc.  */
59
      if ((type_class & ELF_RTYPE_CLASS_COPY) && map->l_type == lt_executable)
60
        continue;
61
 
62
      /* Print some debugging info if wanted.  */
63
      if (__builtin_expect (_dl_debug_mask & DL_DEBUG_SYMBOLS, 0))
64
        _dl_debug_printf ("symbol=%s;  lookup in file=%s\n", undef_name,
65
                          map->l_name[0] ? map->l_name : _dl_argv[0]);
66
 
67
      symtab = (const void *) D_PTR (map, l_info[DT_SYMTAB]);
68
      strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
69
      verstab = map->l_versyms;
70
 
71
      /* Search the appropriate hash bucket in this object's symbol table
72
         for a definition for the same symbol name.  */
73
      for (symidx = map->l_buckets[hash % map->l_nbuckets];
74
           symidx != STN_UNDEF;
75
           symidx = map->l_chain[symidx])
76
        {
77
          sym = &symtab[symidx];
78
 
79
          assert (ELF_RTYPE_CLASS_PLT == 1);
80
          if (sym->st_value == 0 || /* No value.  */
81
              /* ((type_class & ELF_RTYPE_CLASS_PLT)
82
                  && (sym->st_shndx == SHN_UNDEF)) */
83
              (type_class & (sym->st_shndx == SHN_UNDEF)))
84
            continue;
85
 
86
          if (ELFW(ST_TYPE) (sym->st_info) > STT_FUNC
87
              && ELFW(ST_TYPE) (sym->st_info) != STT_COMMON)
88
            /* Ignore all but STT_NOTYPE, STT_OBJECT, STT_COMMON and
89
               STT_FUNC entries since these are no code/data definitions.  */
90
            continue;
91
 
92
          if (sym != ref && strcmp (strtab + sym->st_name, undef_name))
93
            /* Not the symbol we are looking for.  */
94
            continue;
95
 
96
#if VERSIONED
97
          if (__builtin_expect (verstab == NULL, 0))
98
            {
99
              /* We need a versioned symbol but haven't found any.  If
100
                 this is the object which is referenced in the verneed
101
                 entry it is a bug in the library since a symbol must
102
                 not simply disappear.
103
 
104
                 It would also be a bug in the object since it means that
105
                 the list of required versions is incomplete and so the
106
                 tests in dl-version.c haven't found a problem.*/
107
              assert (version->filename == NULL
108
                      || ! _dl_name_match_p (version->filename, map));
109
 
110
              /* Otherwise we accept the symbol.  */
111
            }
112
          else
113
            {
114
              /* We can match the version information or use the
115
                 default one if it is not hidden.  */
116
              ElfW(Half) ndx = verstab[symidx] & 0x7fff;
117
              if ((map->l_versions[ndx].hash != version->hash
118
                   || strcmp (map->l_versions[ndx].name, version->name))
119
                  && (version->hidden || map->l_versions[ndx].hash
120
                      || (verstab[symidx] & 0x8000)))
121
                /* It's not the version we want.  */
122
                continue;
123
            }
124
#else
125
          /* No specific version is selected.  When the object file
126
             also does not define a version we have a match.
127
             Otherwise we accept the default version, or in case there
128
             is only one version defined, this one version.  */
129
          if (verstab != NULL)
130
            {
131
              ElfW(Half) ndx = verstab[symidx] & 0x7fff;
132
              if (ndx > 2) /* map->l_versions[ndx].hash != 0) */
133
                {
134
                  /* Don't accept hidden symbols.  */
135
                  if ((verstab[symidx] & 0x8000) == 0 && num_versions++ == 0)
136
                    /* No version so far.  */
137
                    versioned_sym = sym;
138
                  continue;
139
                }
140
            }
141
#endif
142
 
143
          /* There cannot be another entry for this symbol so stop here.  */
144
          goto found_it;
145
        }
146
 
147
      /* If we have seen exactly one versioned symbol while we are
148
         looking for an unversioned symbol and the version is not the
149
         default version we still accept this symbol since there are
150
         no possible ambiguities.  */
151
#if VERSIONED
152
      sym = NULL;
153
#else
154
      sym = num_versions == 1 ? versioned_sym : NULL;
155
#endif
156
 
157
      if (sym != NULL)
158
        {
159
        found_it:
160
          switch (ELFW(ST_BIND) (sym->st_info))
161
            {
162
            case STB_WEAK:
163
              /* Weak definition.  Use this value if we don't find another.  */
164
              if (__builtin_expect (_dl_dynamic_weak, 0))
165
                {
166
                  if (! result->s)
167
                    {
168
                      result->s = sym;
169
                      result->m = map;
170
                    }
171
                  break;
172
                }
173
              /* FALLTHROUGH */
174
            case STB_GLOBAL:
175
              /* Global definition.  Just what we need.  */
176
              result->s = sym;
177
              result->m = map;
178
              return 1;
179
            default:
180
              /* Local symbols are ignored.  */
181
              break;
182
            }
183
        }
184
 
185
#if VERSIONED
186
      /* If this current map is the one mentioned in the verneed entry
187
         and we have not found a weak entry, it is a bug.  */
188
      if (symidx == STN_UNDEF && version->filename != NULL
189
          && __builtin_expect (_dl_name_match_p (version->filename, map), 0))
190
        return -1;
191
#endif
192
    }
193
  while (++i < n);
194
 
195
  /* We have not found anything until now.  */
196
  return 0;
197
}
198
 
199
#undef FCT
200
#undef ARG
201
#undef VERSIONED

powered by: WebSVN 2.1.0

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