⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dl-hash.c

📁 Axis 221 camera embedded programing interface
💻 C
字号:
/* vi: set sw=4 ts=4: *//* * Program to load an ELF binary on a linux system, and run it * after resolving ELF shared library symbols * * Copyright (C) 2004 by Joakim Tjernlund <joakim.tjernlund@lumentis.se> * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org> * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald, *				David Engel, Hongjiu Lu and Mitch D'Souza * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. The name of the above contributors may not be *    used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. *//* Various symbol table handling functions, including symbol lookup *//* * This is the start of the linked list that describes all of the files present * in the system with pointers to all of the symbol, string, and hash tables, * as well as all of the other good stuff in the binary. */struct elf_resolve *_dl_loaded_modules = NULL;/* * This is the list of modules that are loaded when the image is first * started.  As we add more via dlopen, they get added into other * chains. */struct dyn_elf *_dl_symbol_tables = NULL;/* * This is the list of modules that are loaded via dlopen.  We may need * to search these for RTLD_GLOBAL files. */struct dyn_elf *_dl_handles = NULL;/* This is the hash function that is used by the ELF linker to generate the * hash table that each executable and library is required to have.  We need * it to decode the hash table.  */unsigned long _dl_elf_hash(const unsigned char *name){	unsigned long hash = 0;	unsigned long tmp;	while (*name) {		hash = (hash << 4) + *name++;		if ((tmp = hash & 0xf0000000))			hash ^= tmp >> 24;		hash &= ~tmp;	}	return hash;}/* Check to see if a library has already been added to the hash chain.  */struct elf_resolve *_dl_check_hashed_files(const char *libname){	struct elf_resolve *tpnt;	int len = _dl_strlen(libname);	for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {		if (_dl_strncmp(tpnt->libname, libname, len) == 0 &&				(tpnt->libname[len] == '\0' || tpnt->libname[len] == '.'))			return tpnt;	}	return NULL;}/* * We call this function when we have just read an ELF library or executable. * We add the relevant info to the symbol chain, so that we can resolve all * externals properly. */struct elf_resolve *_dl_add_elf_hash_table(const char *libname,	char *loadaddr, unsigned long *dynamic_info, unsigned long dynamic_addr,	unsigned long dynamic_size){	unsigned long *hash_addr;	struct elf_resolve *tpnt;	int i;	if (!_dl_loaded_modules) {		tpnt = _dl_loaded_modules = (struct elf_resolve *) _dl_malloc(sizeof(struct elf_resolve));		_dl_memset(tpnt, 0, sizeof(struct elf_resolve));	} else {		tpnt = _dl_loaded_modules;		while (tpnt->next)			tpnt = tpnt->next;		tpnt->next = (struct elf_resolve *) _dl_malloc(sizeof(struct elf_resolve));		_dl_memset(tpnt->next, 0, sizeof(struct elf_resolve));		tpnt->next->prev = tpnt;		tpnt = tpnt->next;	};	tpnt->next = NULL;	tpnt->init_flag = 0;	tpnt->libname = _dl_strdup(libname);	tpnt->dynamic_addr = (ElfW(Dyn) *)dynamic_addr;	tpnt->libtype = loaded_file;	if (dynamic_info[DT_HASH] != 0) {		hash_addr = (unsigned long *) (intptr_t)(dynamic_info[DT_HASH] + loadaddr);		tpnt->nbucket = *hash_addr++;		tpnt->nchain = *hash_addr++;		tpnt->elf_buckets = hash_addr;		hash_addr += tpnt->nbucket;		tpnt->chains = hash_addr;	}	tpnt->loadaddr = (ElfW(Addr))loadaddr;	for (i = 0; i < DYNAMIC_SIZE; i++)		tpnt->dynamic_info[i] = dynamic_info[i];	return tpnt;}/* * This function resolves externals, and this is either called when we process * relocations or when we call an entry in the PLT table for the first time. */char *_dl_find_hash(const char *name, struct dyn_elf *rpnt, struct elf_resolve *mytpnt, int type_class){	struct elf_resolve *tpnt;	int si;	char *strtab;	Elf32_Sym *symtab;	unsigned long elf_hash_number, hn;	const ElfW(Sym) *sym;	char *weak_result = NULL;	elf_hash_number = _dl_elf_hash(name);	   	for (; rpnt; rpnt = rpnt->next) {		tpnt = rpnt->dyn;		if (!(tpnt->rtld_flags & RTLD_GLOBAL) && mytpnt) {			if (mytpnt == tpnt)				;			else {				struct init_fini_list *tmp;				for (tmp = mytpnt->rtld_local; tmp; tmp = tmp->next) {					if (tmp->tpnt == tpnt)						break;				}				if (!tmp)					continue;			}		}		/* Don't search the executable when resolving a copy reloc. */		if ((type_class &  ELF_RTYPE_CLASS_COPY) && tpnt->libtype == elf_executable)			continue;		/* Avoid calling .urem here. */		do_rem(hn, elf_hash_number, tpnt->nbucket);		symtab = (Elf32_Sym *) (intptr_t) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);		strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);		for (si = tpnt->elf_buckets[hn]; si != STN_UNDEF; si = tpnt->chains[si]) {			sym = &symtab[si];			if (type_class & (sym->st_shndx == SHN_UNDEF))				continue;			if (_dl_strcmp(strtab + sym->st_name, name) != 0)				continue;			if (sym->st_value == 0)				continue;			if (ELF32_ST_TYPE(sym->st_info) > STT_FUNC)				continue;			switch (ELF32_ST_BIND(sym->st_info)) {			case STB_WEAK:#if 0/* Perhaps we should support old style weak symbol handling * per what glibc does when you export LD_DYNAMIC_WEAK */				if (!weak_result)					weak_result = (char *)tpnt->loadaddr + sym->st_value;				break;#endif			case STB_GLOBAL:				return (char*)tpnt->loadaddr + sym->st_value;			default:	/* Local symbols not handled here */				break;			}		}	}	return weak_result;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -