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/] [dl-lookup.c] - Blame information for rev 816

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
#include <alloca.h>
21
#include <libintl.h>
22
#include <stdlib.h>
23
#include <string.h>
24
#include <unistd.h>
25
#include <ldsodefs.h>
26
#include "dl-hash.h"
27
#include <machine/dl-machine.h>
28
#include <bits/libc-lock.h>
29
 
30
#include <assert.h>
31
 
32
#define VERSTAG(tag)    (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (tag))
33
 
34
/* We need this string more than once.  */
35
static const char undefined_msg[] = "undefined symbol: ";
36
 
37
 
38
struct sym_val
39
  {
40
    const ElfW(Sym) *s;
41
    struct link_map *m;
42
  };
43
 
44
 
45
#define make_string(string, rest...) \
46
  ({                                                                          \
47
    const char *all[] = { string, ## rest };                                  \
48
    size_t len, cnt;                                                          \
49
    char *result, *cp;                                                        \
50
                                                                              \
51
    len = 1;                                                                  \
52
    for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt)                  \
53
      len += strlen (all[cnt]);                                               \
54
                                                                              \
55
    cp = result = alloca (len);                                               \
56
    for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt)                  \
57
    {                                                                         \
58
      cp = strcpy (cp, all[cnt]);                                             \
59
      cp += strlen(all[cnt]);                                                 \
60
    }                                                                         \
61
                                                                              \
62
    result;                                                                   \
63
  })
64
 
65
/* Statistics function.  */
66
unsigned long int _dl_num_relocations;
67
 
68
 
69
/* We have two different situations when looking up a simple: with or
70
   without versioning.  gcc is not able to optimize a single function
71
   definition serving for both purposes so we define two functions.  */
72
#define VERSIONED       0
73
#include "do-lookup.h"
74
 
75
#define VERSIONED       1
76
#include "do-lookup.h"
77
 
78
 
79
/* Add extra dependency on MAP to UNDEF_MAP.  */
80
static int
81
internal_function
82
add_dependency (struct link_map *undef_map, struct link_map *map)
83
{
84
  struct link_map **list;
85
  struct link_map *runp;
86
  unsigned int act;
87
  unsigned int i;
88
  int result = 0;
89
 
90
  /* Avoid self-references.  */
91
  if (undef_map == map)
92
    return 0;
93
 
94
  /* Make sure nobody can unload the object while we are at it.  */
95
#ifdef HAVE_DD_LOCK
96
    __lock_acquire(_dl_load_lock);
97
#endif
98
 
99
 
100
  /* Determine whether UNDEF_MAP already has a reference to MAP.  First
101
     look in the normal dependencies.  */
102
  if (undef_map->l_searchlist.r_list != NULL)
103
    {
104
      list = undef_map->l_initfini;
105
 
106
      for (i = 0; list[i] != NULL; ++i)
107
        if (list[i] == map)
108
          goto out;
109
    }
110
 
111
  /* No normal dependency.  See whether we already had to add it
112
     to the special list of dynamic dependencies.  */
113
  list = undef_map->l_reldeps;
114
  act = undef_map->l_reldepsact;
115
 
116
  for (i = 0; i < act; ++i)
117
    if (list[i] == map)
118
      goto out;
119
 
120
  /* The object is not yet in the dependency list.  Before we add
121
     it make sure just one more time the object we are about to
122
     reference is still available.  There is a brief period in
123
     which the object could have been removed since we found the
124
     definition.  */
125
  runp = _dl_loaded;
126
  while (runp != NULL && runp != map)
127
    runp = runp->l_next;
128
 
129
  if (runp != NULL)
130
    {
131
      /* The object is still available.  Add the reference now.  */
132
      if (__builtin_expect (act >= undef_map->l_reldepsmax, 0))
133
        {
134
          /* Allocate more memory for the dependency list.  Since this
135
             can never happen during the startup phase we can use
136
             `realloc'.  */
137
          void *newp;
138
 
139
          undef_map->l_reldepsmax += 5;
140
          newp = realloc (undef_map->l_reldeps,
141
                          undef_map->l_reldepsmax
142
                          * sizeof (struct link_map *));
143
 
144
          if (__builtin_expect (newp != NULL, 1))
145
            undef_map->l_reldeps = (struct link_map **) newp;
146
          else
147
            /* Correct the addition.  */
148
            undef_map->l_reldepsmax -= 5;
149
        }
150
 
151
      /* If we didn't manage to allocate memory for the list this is
152
         no fatal mistake.  We simply increment the use counter of the
153
         referenced object and don't record the dependencies.  This
154
         means this increment can never be reverted and the object
155
         will never be unloaded.  This is semantically the correct
156
         behaviour.  */
157
      if (__builtin_expect (act < undef_map->l_reldepsmax, 1))
158
        undef_map->l_reldeps[undef_map->l_reldepsact++] = map;
159
 
160
      if (map->l_searchlist.r_list != NULL)
161
        /* And increment the counter in the referenced object.  */
162
        ++map->l_opencount;
163
      else
164
        /* We have to bump the counts for all dependencies since so far
165
           this object was only a normal or transitive dependency.
166
           Now it might be closed with _dl_close() directly.  */
167
        for (list = map->l_initfini; *list != NULL; ++list)
168
          ++(*list)->l_opencount;
169
 
170
      /* Display information if we are debugging.  */
171
      if (__builtin_expect (_dl_debug_mask & DL_DEBUG_FILES, 0))
172
        _dl_debug_printf ("\
173
\nfile=%s;  needed by %s (relocation dependency)\n\n",
174
                          map->l_name[0] ? map->l_name : _dl_argv[0],
175
                          undef_map->l_name[0]
176
                          ? undef_map->l_name : _dl_argv[0]);
177
    }
178
  else
179
    /* Whoa, that was bad luck.  We have to search again.  */
180
    result = -1;
181
 
182
 out:
183
  /* Release the lock.  */
184
#ifdef HAVE_DD_LOCK
185
    __lock_release(_dl_load_lock);
186
#endif
187
 
188
 
189
  return result;
190
}
191
 
192
static int
193
internal_function
194
_dl_do_lookup (const char *undef_name, unsigned long int hash,
195
               const ElfW(Sym) *ref, struct sym_val *result,
196
               struct r_scope_elem *scope, size_t i,
197
               struct link_map *skip, int type_class);
198
static int
199
internal_function
200
_dl_do_lookup_versioned (const char *undef_name, unsigned long int hash,
201
                         const ElfW(Sym) *ref, struct sym_val *result,
202
                         struct r_scope_elem *scope, size_t i,
203
                         const struct r_found_version *const version,
204
                         struct link_map *skip, int type_class);
205
 
206
 
207
/* Search loaded objects' symbol tables for a definition of the symbol
208
   UNDEF_NAME.  */
209
 
210
lookup_t
211
internal_function
212
_dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
213
                   const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
214
                   int type_class, int explicit)
215
{
216
  unsigned long int hash = _dl_elf_hash (undef_name);
217
  struct sym_val current_value = { NULL, NULL };
218
  struct r_scope_elem **scope;
219
  int protected;
220
 
221
  ++_dl_num_relocations;
222
 
223
  /* Search the relevant loaded objects for a definition.  */
224
  for (scope = symbol_scope; *scope; ++scope)
225
    if (do_lookup (undef_name, hash, *ref, &current_value, *scope, 0, NULL,
226
                   type_class))
227
      {
228
        /* We have to check whether this would bind UNDEF_MAP to an object
229
           in the global scope which was dynamically loaded.  In this case
230
           we have to prevent the latter from being unloaded unless the
231
           UNDEF_MAP object is also unloaded.  */
232
        if (__builtin_expect (current_value.m->l_type == lt_loaded, 0)
233
            /* Don't do this for explicit lookups as opposed to implicit
234
               runtime lookups.  */
235
            && ! explicit
236
            /* Add UNDEF_MAP to the dependencies.  */
237
            && add_dependency (undef_map, current_value.m) < 0)
238
          /* Something went wrong.  Perhaps the object we tried to reference
239
             was just removed.  Try finding another definition.  */
240
          return _dl_lookup_symbol (undef_name, undef_map, ref, symbol_scope,
241
                                    type_class, 0);
242
 
243
        break;
244
      }
245
 
246
  if (__builtin_expect (current_value.s == NULL, 0))
247
    {
248
      const char *reference_name = undef_map ? undef_map->l_name : NULL;
249
 
250
      if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
251
        /* We could find no value for a strong reference.  */
252
        /* XXX We cannot translate the messages.  */
253
        _dl_signal_cerror (0, (reference_name && reference_name[0]
254
                               ? reference_name
255
                               : (_dl_argv[0] ?: "<main program>")),
256
                           N_("relocation error"),
257
                           make_string (undefined_msg, undef_name));
258
      *ref = NULL;
259
      return 0;
260
    }
261
 
262
  protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
263
 
264
  if (__builtin_expect (_dl_debug_mask & DL_DEBUG_BINDINGS, 0))
265
    {
266
      const char *reference_name = undef_map ? undef_map->l_name : NULL;
267
 
268
      _dl_debug_printf ("binding file %s to %s: %s symbol `%s'\n",
269
                        (reference_name && reference_name[0]
270
                         ? reference_name : (_dl_argv[0] ?: "<main program>")),
271
                        current_value.m->l_name[0]
272
                        ? current_value.m->l_name : _dl_argv[0],
273
                        protected ? "protected" : "normal", undef_name);
274
    }
275
 
276
  if (__builtin_expect (protected == 0, 1))
277
    {
278
      *ref = current_value.s;
279
      return LOOKUP_VALUE (current_value.m);
280
    }
281
  else
282
    {
283
      /* It is very tricky. We need to figure out what value to
284
         return for the protected symbol */
285
      struct sym_val protected_value = { NULL, NULL };
286
 
287
      for (scope = symbol_scope; *scope; ++scope)
288
        if (_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope,
289
                           0, NULL, ELF_RTYPE_CLASS_PLT))
290
          break;
291
 
292
      if (protected_value.s == NULL || protected_value.m == undef_map)
293
        {
294
          *ref = current_value.s;
295
          return LOOKUP_VALUE (current_value.m);
296
        }
297
 
298
      return LOOKUP_VALUE (undef_map);
299
    }
300
}
301
 
302
 
303
/* This function is nearly the same as `_dl_lookup_symbol' but it
304
   skips in the first list all objects until SKIP_MAP is found.  I.e.,
305
   it only considers objects which were loaded after the described
306
   object.  If there are more search lists the object described by
307
   SKIP_MAP is only skipped.  */
308
lookup_t
309
internal_function
310
_dl_lookup_symbol_skip (const char *undef_name,
311
                        struct link_map *undef_map, const ElfW(Sym) **ref,
312
                        struct r_scope_elem *symbol_scope[],
313
                        struct link_map *skip_map)
314
{
315
  const char *reference_name = undef_map ? undef_map->l_name : NULL;
316
  const unsigned long int hash = _dl_elf_hash (undef_name);
317
  struct sym_val current_value = { NULL, NULL };
318
  struct r_scope_elem **scope;
319
  size_t i;
320
  int protected;
321
 
322
  ++_dl_num_relocations;
323
 
324
  /* Search the relevant loaded objects for a definition.  */
325
  scope = symbol_scope;
326
  for (i = 0; (*scope)->r_list[i] != skip_map; ++i)
327
    assert (i < (*scope)->r_nlist);
328
 
329
  if (! _dl_do_lookup (undef_name, hash, *ref, &current_value, *scope, i,
330
                       skip_map, 0))
331
    while (*++scope)
332
      if (_dl_do_lookup (undef_name, hash, *ref, &current_value, *scope, 0,
333
                         skip_map, 0))
334
        break;
335
 
336
  if (__builtin_expect (current_value.s == NULL, 0))
337
    {
338
      *ref = NULL;
339
      return 0;
340
    }
341
 
342
  protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
343
 
344
  if (__builtin_expect (_dl_debug_mask & DL_DEBUG_BINDINGS, 0))
345
    _dl_debug_printf ("binding file %s to %s: %s symbol `%s'\n",
346
                       (reference_name && reference_name[0]
347
                        ? reference_name : (_dl_argv[0] ?: "<main program>")),
348
                       current_value.m->l_name[0]
349
                       ? current_value.m->l_name : _dl_argv[0],
350
                       protected ? "protected" : "normal", undef_name);
351
 
352
  if (__builtin_expect (protected == 0, 1))
353
    {
354
      *ref = current_value.s;
355
      return LOOKUP_VALUE (current_value.m);
356
    }
357
  else
358
    {
359
      /* It is very tricky.  We need to figure out what value to
360
         return for the protected symbol.  */
361
      struct sym_val protected_value = { NULL, NULL };
362
 
363
      if (i >= (*scope)->r_nlist
364
          || !_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope,
365
                             i, skip_map, ELF_RTYPE_CLASS_PLT))
366
        while (*++scope)
367
          if (_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope,
368
                             0, skip_map, ELF_RTYPE_CLASS_PLT))
369
            break;
370
 
371
      if (protected_value.s == NULL || protected_value.m == undef_map)
372
        {
373
          *ref = current_value.s;
374
          return LOOKUP_VALUE (current_value.m);
375
        }
376
 
377
      return LOOKUP_VALUE (undef_map);
378
    }
379
}
380
 
381
 
382
/* This function works like _dl_lookup_symbol but it takes an
383
   additional arguement with the version number of the requested
384
   symbol.
385
 
386
   XXX We'll see whether we need this separate function.  */
387
lookup_t
388
internal_function
389
_dl_lookup_versioned_symbol (const char *undef_name,
390
                             struct link_map *undef_map, const ElfW(Sym) **ref,
391
                             struct r_scope_elem *symbol_scope[],
392
                             const struct r_found_version *version,
393
                             int type_class, int explicit)
394
{
395
  unsigned long int hash = _dl_elf_hash (undef_name);
396
  struct sym_val current_value = { NULL, NULL };
397
  struct r_scope_elem **scope;
398
  int protected;
399
 
400
  ++_dl_num_relocations;
401
 
402
  /* Search the relevant loaded objects for a definition.  */
403
  for (scope = symbol_scope; *scope; ++scope)
404
    {
405
      int res = do_lookup_versioned (undef_name, hash, *ref, &current_value,
406
                                     *scope, 0, version, NULL, type_class);
407
      if (res > 0)
408
        {
409
          /* We have to check whether this would bind UNDEF_MAP to an object
410
             in the global scope which was dynamically loaded.  In this case
411
             we have to prevent the latter from being unloaded unless the
412
             UNDEF_MAP object is also unloaded.  */
413
          if (__builtin_expect (current_value.m->l_type == lt_loaded, 0)
414
              /* Don't do this for explicit lookups as opposed to implicit
415
                 runtime lookups.  */
416
              && ! explicit
417
              /* Add UNDEF_MAP to the dependencies.  */
418
              && add_dependency (undef_map, current_value.m) < 0)
419
            /* Something went wrong.  Perhaps the object we tried to reference
420
               was just removed.  Try finding another definition.  */
421
            return _dl_lookup_versioned_symbol (undef_name, undef_map, ref,
422
                                                symbol_scope, version,
423
                                                type_class, 0);
424
 
425
          break;
426
        }
427
 
428
      if (__builtin_expect (res, 0) < 0)
429
        {
430
          /* Oh, oh.  The file named in the relocation entry does not
431
             contain the needed symbol.  */
432
          const char *reference_name = undef_map ? undef_map->l_name : NULL;
433
 
434
          /* XXX We cannot translate the message.  */
435
          _dl_signal_cerror (0, (reference_name && reference_name[0]
436
                                 ? reference_name
437
                                 : (_dl_argv[0] ?: "<main program>")),
438
                             N_("relocation error"),
439
                             make_string ("symbol ", undef_name, ", version ",
440
                                          version->name,
441
                                          " not defined in file ",
442
                                          version->filename,
443
                                          " with link time reference",
444
                                          res == -2
445
                                          ? " (no version symbols)" : ""));
446
          *ref = NULL;
447
          return 0;
448
        }
449
    }
450
 
451
  if (__builtin_expect (current_value.s == NULL, 0))
452
    {
453
      if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
454
        {
455
          /* We could find no value for a strong reference.  */
456
          const char *reference_name = undef_map ? undef_map->l_name : NULL;
457
 
458
          /* XXX We cannot translate the message.  */
459
          _dl_signal_cerror (0, (reference_name && reference_name[0]
460
                                 ? reference_name
461
                                 : (_dl_argv[0] ?: "<main program>")), NULL,
462
                             make_string (undefined_msg, undef_name,
463
                                          ", version ",
464
                                          version->name ?: NULL));
465
        }
466
      *ref = NULL;
467
      return 0;
468
    }
469
 
470
  protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
471
 
472
  if (__builtin_expect (_dl_debug_mask & DL_DEBUG_BINDINGS, 0))
473
    {
474
      const char *reference_name = undef_map ? undef_map->l_name : NULL;
475
 
476
      _dl_debug_printf ("binding file %s to %s: %s symbol `%s' [%s]\n",
477
                        (reference_name && reference_name[0]
478
                         ? reference_name : (_dl_argv[0] ?: "<main program>")),
479
                        current_value.m->l_name[0]
480
                        ? current_value.m->l_name : _dl_argv[0],
481
                        protected ? "protected" : "normal",
482
                        undef_name, version->name);
483
    }
484
 
485
  if (__builtin_expect (protected == 0, 1))
486
    {
487
      *ref = current_value.s;
488
      return LOOKUP_VALUE (current_value.m);
489
    }
490
  else
491
    {
492
      /* It is very tricky. We need to figure out what value to
493
         return for the protected symbol */
494
      struct sym_val protected_value = { NULL, NULL };
495
 
496
      for (scope = symbol_scope; *scope; ++scope)
497
        if (_dl_do_lookup_versioned (undef_name, hash, *ref, &protected_value,
498
                                     *scope, 0, version, NULL,
499
                                     ELF_RTYPE_CLASS_PLT))
500
          break;
501
 
502
      if (protected_value.s == NULL || protected_value.m == undef_map)
503
        {
504
          *ref = current_value.s;
505
          return LOOKUP_VALUE (current_value.m);
506
        }
507
 
508
      return LOOKUP_VALUE (undef_map);
509
    }
510
}
511
 
512
 
513
/* Similar to _dl_lookup_symbol_skip but takes an additional argument
514
   with the version we are looking for.  */
515
lookup_t
516
internal_function
517
_dl_lookup_versioned_symbol_skip (const char *undef_name,
518
                                  struct link_map *undef_map,
519
                                  const ElfW(Sym) **ref,
520
                                  struct r_scope_elem *symbol_scope[],
521
                                  const struct r_found_version *version,
522
                                  struct link_map *skip_map)
523
{
524
  const char *reference_name = undef_map ? undef_map->l_name : NULL;
525
  const unsigned long int hash = _dl_elf_hash (undef_name);
526
  struct sym_val current_value = { NULL, NULL };
527
  struct r_scope_elem **scope;
528
  size_t i;
529
  int protected;
530
 
531
  ++_dl_num_relocations;
532
 
533
  /* Search the relevant loaded objects for a definition.  */
534
  scope = symbol_scope;
535
  for (i = 0; (*scope)->r_list[i] != skip_map; ++i)
536
    assert (i < (*scope)->r_nlist);
537
 
538
  if (! _dl_do_lookup_versioned (undef_name, hash, *ref, &current_value,
539
                                 *scope, i, version, skip_map, 0))
540
    while (*++scope)
541
      if (_dl_do_lookup_versioned (undef_name, hash, *ref, &current_value,
542
                                   *scope, 0, version, skip_map, 0))
543
        break;
544
 
545
  if (__builtin_expect (current_value.s == NULL, 0))
546
    {
547
      if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
548
        {
549
          /* We could find no value for a strong reference.  */
550
          const size_t len = strlen (undef_name);
551
          char buf[sizeof undefined_msg + len];
552
          char *tmp;
553
          tmp = memcpy (buf, undefined_msg, sizeof undefined_msg - 1);
554
          tmp += (sizeof undefined_msg - 1);
555
 
556
          memcpy (tmp, undef_name, len + 1);
557
 
558
          /* XXX We cannot translate the messages.  */
559
          _dl_signal_cerror (0, (reference_name && reference_name[0]
560
                                 ? reference_name
561
                                 : (_dl_argv[0] ?: "<main program>")),
562
                             NULL, buf);
563
        }
564
      *ref = NULL;
565
      return 0;
566
    }
567
 
568
  protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
569
 
570
  if (__builtin_expect (_dl_debug_mask & DL_DEBUG_BINDINGS, 0))
571
    _dl_debug_printf ("binding file %s to %s: %s symbol `%s' [%s]\n",
572
                      (reference_name && reference_name[0]
573
                       ? reference_name : (_dl_argv[0] ?: "<main program>")),
574
                      current_value.m->l_name[0]
575
                      ? current_value.m->l_name : _dl_argv[0],
576
                      protected ? "protected" : "normal",
577
                      undef_name, version->name);
578
 
579
  if (__builtin_expect (protected == 0, 1))
580
    {
581
      *ref = current_value.s;
582
      return LOOKUP_VALUE (current_value.m);
583
    }
584
  else
585
    {
586
      /* It is very tricky. We need to figure out what value to
587
         return for the protected symbol */
588
      struct sym_val protected_value = { NULL, NULL };
589
 
590
      if (i >= (*scope)->r_nlist
591
          || !_dl_do_lookup_versioned (undef_name, hash, *ref,
592
                                       &protected_value, *scope, i, version,
593
                                       skip_map, ELF_RTYPE_CLASS_PLT))
594
        while (*++scope)
595
          if (_dl_do_lookup_versioned (undef_name, hash, *ref,
596
                                       &protected_value, *scope, 0, version,
597
                                       skip_map, ELF_RTYPE_CLASS_PLT))
598
            break;
599
 
600
      if (protected_value.s == NULL || protected_value.m == undef_map)
601
        {
602
          *ref = current_value.s;
603
          return LOOKUP_VALUE (current_value.m);
604
        }
605
 
606
      return LOOKUP_VALUE (undef_map);
607
    }
608
}
609
 
610
 
611
/* Cache the location of MAP's hash table.  */
612
 
613
void
614
internal_function
615
_dl_setup_hash (struct link_map *map)
616
{
617
  Elf_Symndx *hash;
618
  Elf_Symndx nchain;
619
 
620
  if (!map->l_info[DT_HASH])
621
    return;
622
  hash = (void *)(map->l_addr + map->l_info[DT_HASH]->d_un.d_ptr);
623
 
624
  map->l_nbuckets = *hash++;
625
  nchain = *hash++;
626
  map->l_buckets = hash;
627
  hash += map->l_nbuckets;
628
  map->l_chain = hash;
629
}
630
 
631
/* These are here so that we only inline do_lookup{,_versioned} in the common
632
   case, not everywhere.  */
633
static int
634
internal_function
635
_dl_do_lookup (const char *undef_name, unsigned long int hash,
636
               const ElfW(Sym) *ref, struct sym_val *result,
637
               struct r_scope_elem *scope, size_t i,
638
               struct link_map *skip, int type_class)
639
{
640
  return do_lookup (undef_name, hash, ref, result, scope, i, skip,
641
                    type_class);
642
}
643
 
644
static int
645
internal_function
646
_dl_do_lookup_versioned (const char *undef_name, unsigned long int hash,
647
                         const ElfW(Sym) *ref, struct sym_val *result,
648
                         struct r_scope_elem *scope, size_t i,
649
                         const struct r_found_version *const version,
650
                         struct link_map *skip, int type_class)
651
{
652
  return do_lookup_versioned (undef_name, hash, ref, result, scope, i,
653
                              version, skip, type_class);
654
}

powered by: WebSVN 2.1.0

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