| 
									
										
										
										
											2022-01-18 12:53:11 +00:00
										 |  |  | /* Cache the location of a link map hash table.
 | 
					
						
							| 
									
										
										
										
											2024-01-01 18:12:26 +00:00
										 |  |  |    Copyright (C) 1995-2024 Free Software Foundation, Inc. | 
					
						
							| 
									
										
										
										
											2022-01-18 12:53:11 +00:00
										 |  |  |    This file is part of the GNU C Library. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    The GNU C Library is free software; you can redistribute it and/or | 
					
						
							|  |  |  |    modify it under the terms of the GNU Lesser General Public | 
					
						
							|  |  |  |    License as published by the Free Software Foundation; either | 
					
						
							|  |  |  |    version 2.1 of the License, or (at your option) any later version. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    The GNU C Library is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
					
						
							|  |  |  |    Lesser General Public License for more details. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    You should have received a copy of the GNU Lesser General Public | 
					
						
							|  |  |  |    License along with the GNU C Library; if not, see | 
					
						
							|  |  |  |    <https://www.gnu.org/licenses/>.  */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <assert.h>
 | 
					
						
							|  |  |  | #include <link.h>
 | 
					
						
							|  |  |  | #include <ldsodefs.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | _dl_setup_hash (struct link_map *map) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Elf_Symndx *hash; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (__glibc_likely (map->l_info[ELF_MACHINE_GNU_HASH_ADDRIDX] != NULL)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       Elf32_Word *hash32 | 
					
						
							|  |  |  |         = (void *) D_PTR (map, l_info[ELF_MACHINE_GNU_HASH_ADDRIDX]); | 
					
						
							|  |  |  |       map->l_nbuckets = *hash32++; | 
					
						
							|  |  |  |       Elf32_Word symbias = *hash32++; | 
					
						
							|  |  |  |       Elf32_Word bitmask_nwords = *hash32++; | 
					
						
							|  |  |  |       /* Must be a power of two.  */ | 
					
						
							|  |  |  |       assert ((bitmask_nwords & (bitmask_nwords - 1)) == 0); | 
					
						
							|  |  |  |       map->l_gnu_bitmask_idxbits = bitmask_nwords - 1; | 
					
						
							|  |  |  |       map->l_gnu_shift = *hash32++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       map->l_gnu_bitmask = (ElfW(Addr) *) hash32; | 
					
						
							|  |  |  |       hash32 += __ELF_NATIVE_CLASS / 32 * bitmask_nwords; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       map->l_gnu_buckets = hash32; | 
					
						
							|  |  |  |       hash32 += map->l_nbuckets; | 
					
						
							|  |  |  |       map->l_gnu_chain_zero = hash32 - symbias; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /* Initialize MIPS xhash translation table.  */ | 
					
						
							|  |  |  |       ELF_MACHINE_XHASH_SETUP (hash32, symbias, map); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!map->l_info[DT_HASH]) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   hash = (void *) D_PTR (map, l_info[DT_HASH]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   map->l_nbuckets = *hash++; | 
					
						
							|  |  |  |   /* Skip nchain.  */ | 
					
						
							|  |  |  |   hash++; | 
					
						
							|  |  |  |   map->l_buckets = hash; | 
					
						
							|  |  |  |   hash += map->l_nbuckets; | 
					
						
							|  |  |  |   map->l_chain = hash; | 
					
						
							|  |  |  | } |