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. Don't use a PLT defn in UNDEF_MAP, since
27 that is the object making the reference. */
30 _dl_lookup_symbol (const char *undef_name
, const Elf32_Sym
**ref
,
31 struct link_map
*symbol_scope
,
32 const char *reference_name
)
34 unsigned long int hash
= elf_hash (undef_name
);
40 } weak_value
= { 0, NULL
};
42 /* Search the relevant loaded objects for a definition. */
43 for (map
= symbol_scope
; map
; map
= map
->l_next
)
45 const Elf32_Sym
*symtab
;
49 symtab
= ((void *) map
->l_addr
+ map
->l_info
[DT_SYMTAB
]->d_un
.d_ptr
);
50 strtab
= ((void *) map
->l_addr
+ map
->l_info
[DT_STRTAB
]->d_un
.d_ptr
);
52 /* Search the appropriate hash bucket in this object's symbol table
53 for a definition for the same symbol name. */
54 for (symidx
= map
->l_buckets
[hash
% map
->l_nbuckets
];
56 symidx
= map
->l_chain
[symidx
])
58 const Elf32_Sym
*sym
= &symtab
[symidx
];
60 if (sym
->st_value
== 0)
63 switch (ELF32_ST_TYPE (sym
->st_info
))
70 /* Not a code/data definition. */
74 if (sym
->st_shndx
== SHN_UNDEF
)
75 /* This is the same symbol we are looking for the value for.
76 If it is a PLT entry, it will have a value of its own;
77 but that is not what we are looking for. */
80 if (sym
!= *ref
&& strcmp (strtab
+ sym
->st_name
, undef_name
))
81 /* Not the symbol we are looking for. */
84 switch (ELF32_ST_BIND (sym
->st_info
))
87 /* Global definition. Just what we need. */
91 /* Weak definition. Use this value if we don't find another. */
92 if (weak_value
.a
== 0)
95 weak_value
.a
= map
->l_addr
;
99 /* Local symbols are ignored. */
105 if (weak_value
.s
== NULL
)
107 const char msg
[] = "undefined symbol: ";
108 char buf
[sizeof msg
+ strlen (undef_name
)];
109 memcpy (buf
, msg
, sizeof msg
- 1);
110 memcpy (&buf
[sizeof msg
- 1], undef_name
, sizeof buf
- sizeof msg
+ 1);
111 _dl_signal_error (0, reference_name
, buf
);
119 /* Cache the location of MAP's hash table. */
122 _dl_setup_hash (struct link_map
*map
)
124 Elf32_Word
*hash
= (void *) map
->l_addr
+ map
->l_info
[DT_HASH
]->d_un
.d_ptr
;
126 map
->l_nbuckets
= *hash
++;
128 map
->l_buckets
= hash
;
129 hash
+= map
->l_nbuckets
;