]>
git.ipfire.org Git - thirdparty/glibc.git/blob - elf/dl-lookup.c
1 /* Look up a symbol in the loaded objects.
2 Copyright (C) 1995, 1996 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 the symbol
26 UNDEF_NAME. If NOPLT is nonzero, then a PLT entry cannot satisfy the
27 reference; some different binding must be found. */
30 _dl_lookup_symbol (const char *undef_name
, const Elf32_Sym
**ref
,
31 struct link_map
*symbol_scope
,
32 const char *reference_name
,
35 unsigned long int hash
= elf_hash (undef_name
);
41 } weak_value
= { 0, NULL
};
43 /* Search the relevant loaded objects for a definition. */
44 for (map
= symbol_scope
; map
; map
= map
->l_next
)
46 const Elf32_Sym
*symtab
;
50 symtab
= ((void *) map
->l_addr
+ map
->l_info
[DT_SYMTAB
]->d_un
.d_ptr
);
51 strtab
= ((void *) map
->l_addr
+ map
->l_info
[DT_STRTAB
]->d_un
.d_ptr
);
53 /* Search the appropriate hash bucket in this object's symbol table
54 for a definition for the same symbol name. */
55 for (symidx
= map
->l_buckets
[hash
% map
->l_nbuckets
];
57 symidx
= map
->l_chain
[symidx
])
59 const Elf32_Sym
*sym
= &symtab
[symidx
];
61 if (sym
->st_value
== 0 || /* No value. */
62 (noplt
&& sym
->st_shndx
== SHN_UNDEF
)) /* Unwanted PLT entry. */
65 switch (ELF32_ST_TYPE (sym
->st_info
))
72 /* Not a code/data definition. */
76 if (sym
!= *ref
&& strcmp (strtab
+ sym
->st_name
, undef_name
))
77 /* Not the symbol we are looking for. */
80 switch (ELF32_ST_BIND (sym
->st_info
))
83 /* Global definition. Just what we need. */
87 /* Weak definition. Use this value if we don't find another. */
91 weak_value
.a
= map
->l_addr
;
95 /* Local symbols are ignored. */
101 if (weak_value
.s
== NULL
&& ELF32_ST_BIND ((*ref
)->st_info
) != STB_WEAK
)
103 const char msg
[] = "undefined symbol: ";
104 char buf
[sizeof msg
+ strlen (undef_name
)];
105 memcpy (buf
, msg
, sizeof msg
- 1);
106 memcpy (&buf
[sizeof msg
- 1], undef_name
, sizeof buf
- sizeof msg
+ 1);
107 _dl_signal_error (0, reference_name
, buf
);
115 /* Cache the location of MAP's hash table. */
118 _dl_setup_hash (struct link_map
*map
)
120 Elf32_Word
*hash
= (void *) map
->l_addr
+ map
->l_info
[DT_HASH
]->d_un
.d_ptr
;
122 map
->l_nbuckets
= *hash
++;
124 map
->l_buckets
= hash
;
125 hash
+= map
->l_nbuckets
;