1 /* Look up a symbol in the loaded objects.
2 Copyright (C) 1995 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
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 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If
17 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
18 Cambridge, MA 02139, USA. */
25 /* Search loaded objects' symbol tables for a definition of
26 the symbol UNDEF_NAME. If NOSELF is nonzero, then *REF
27 cannot satisfy the reference itself; some different binding
31 _dl_lookup_symbol (const char *undef_name
, const Elf32_Sym
**ref
,
32 struct link_map
*symbol_scope
,
33 const char *reference_name
,
36 unsigned long int hash
= elf_hash (undef_name
);
42 } weak_value
= { 0, NULL
};
44 /* Search the relevant loaded objects for a definition. */
45 for (map
= symbol_scope
; map
; map
= map
->l_next
)
47 const Elf32_Sym
*symtab
;
51 symtab
= ((void *) map
->l_addr
+ map
->l_info
[DT_SYMTAB
]->d_un
.d_ptr
);
52 strtab
= ((void *) map
->l_addr
+ map
->l_info
[DT_STRTAB
]->d_un
.d_ptr
);
54 /* Search the appropriate hash bucket in this object's symbol table
55 for a definition for the same symbol name. */
56 for (symidx
= map
->l_buckets
[hash
% map
->l_nbuckets
];
58 symidx
= map
->l_chain
[symidx
])
60 const Elf32_Sym
*sym
= &symtab
[symidx
];
62 if (sym
->st_value
== 0 || /* No value. */
63 sym
->st_shndx
== SHN_UNDEF
|| /* PLT entry. */
64 (noself
&& sym
== *ref
)) /* The reference can't define it. */
67 switch (ELF32_ST_TYPE (sym
->st_info
))
74 /* Not a code/data definition. */
78 if (sym
!= *ref
&& strcmp (strtab
+ sym
->st_name
, undef_name
))
79 /* Not the symbol we are looking for. */
82 switch (ELF32_ST_BIND (sym
->st_info
))
85 /* Global definition. Just what we need. */
89 /* Weak definition. Use this value if we don't find another. */
90 if (weak_value
.a
== 0)
93 weak_value
.a
= map
->l_addr
;
97 /* Local symbols are ignored. */
103 if (weak_value
.s
== NULL
)
105 const char msg
[] = "undefined symbol: ";
106 char buf
[sizeof msg
+ strlen (undef_name
)];
107 memcpy (buf
, msg
, sizeof msg
- 1);
108 memcpy (&buf
[sizeof msg
- 1], undef_name
, sizeof buf
- sizeof msg
+ 1);
109 _dl_signal_error (0, reference_name
, buf
);
117 /* Cache the location of MAP's hash table. */
120 _dl_setup_hash (struct link_map
*map
)
122 Elf32_Word
*hash
= (void *) map
->l_addr
+ map
->l_info
[DT_HASH
]->d_un
.d_ptr
;
124 map
->l_nbuckets
= *hash
++;
126 map
->l_buckets
= hash
;
127 hash
+= map
->l_nbuckets
;