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

📄 vdso.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (fix == NULL) {		sym32_gen->st_name = 0;		return 0;	}	sym32_fix = find_symbol32(v32, fix);	if (sym32_fix == NULL) {		printk(KERN_ERR "vDSO32: Can't find symbol %s !\n", fix);		return -1;	}	sym32_gen->st_value = sym32_fix->st_value;	sym32_gen->st_size = sym32_fix->st_size;	sym32_gen->st_info = sym32_fix->st_info;	sym32_gen->st_other = sym32_fix->st_other;	sym32_gen->st_shndx = sym32_fix->st_shndx;	return 0;}#ifdef CONFIG_PPC64static void * __init find_section64(Elf64_Ehdr *ehdr, const char *secname,				  unsigned long *size){	Elf64_Shdr *sechdrs;	unsigned int i;	char *secnames;	/* Grab section headers and strings so we can tell who is who */	sechdrs = (void *)ehdr + ehdr->e_shoff;	secnames = (void *)ehdr + sechdrs[ehdr->e_shstrndx].sh_offset;	/* Find the section they want */	for (i = 1; i < ehdr->e_shnum; i++) {		if (strcmp(secnames+sechdrs[i].sh_name, secname) == 0) {			if (size)				*size = sechdrs[i].sh_size;			return (void *)ehdr + sechdrs[i].sh_offset;		}	}	if (size)		*size = 0;	return NULL;}static Elf64_Sym * __init find_symbol64(struct lib64_elfinfo *lib,					const char *symname){	unsigned int i;	char name[MAX_SYMNAME], *c;	for (i = 0; i < (lib->dynsymsize / sizeof(Elf64_Sym)); i++) {		if (lib->dynsym[i].st_name == 0)			continue;		strlcpy(name, lib->dynstr + lib->dynsym[i].st_name,			MAX_SYMNAME);		c = strchr(name, '@');		if (c)			*c = 0;		if (strcmp(symname, name) == 0)			return &lib->dynsym[i];	}	return NULL;}/* Note that we assume the section is .text and the symbol is relative to * the library base */static unsigned long __init find_function64(struct lib64_elfinfo *lib,					    const char *symname){	Elf64_Sym *sym = find_symbol64(lib, symname);	if (sym == NULL) {		printk(KERN_WARNING "vDSO64: function %s not found !\n",		       symname);		return 0;	}#ifdef VDS64_HAS_DESCRIPTORS	return *((u64 *)(vdso64_kbase + sym->st_value - VDSO64_LBASE)) -		VDSO64_LBASE;#else	return sym->st_value - VDSO64_LBASE;#endif}static int vdso_do_func_patch64(struct lib32_elfinfo *v32,				struct lib64_elfinfo *v64,				const char *orig, const char *fix){	Elf64_Sym *sym64_gen, *sym64_fix;	sym64_gen = find_symbol64(v64, orig);	if (sym64_gen == NULL) {		printk(KERN_ERR "vDSO64: Can't find symbol %s !\n", orig);		return -1;	}	if (fix == NULL) {		sym64_gen->st_name = 0;		return 0;	}	sym64_fix = find_symbol64(v64, fix);	if (sym64_fix == NULL) {		printk(KERN_ERR "vDSO64: Can't find symbol %s !\n", fix);		return -1;	}	sym64_gen->st_value = sym64_fix->st_value;	sym64_gen->st_size = sym64_fix->st_size;	sym64_gen->st_info = sym64_fix->st_info;	sym64_gen->st_other = sym64_fix->st_other;	sym64_gen->st_shndx = sym64_fix->st_shndx;	return 0;}#endif /* CONFIG_PPC64 */static __init int vdso_do_find_sections(struct lib32_elfinfo *v32,					struct lib64_elfinfo *v64){	void *sect;	/*	 * Locate symbol tables & text section	 */	v32->dynsym = find_section32(v32->hdr, ".dynsym", &v32->dynsymsize);	v32->dynstr = find_section32(v32->hdr, ".dynstr", NULL);	if (v32->dynsym == NULL || v32->dynstr == NULL) {		printk(KERN_ERR "vDSO32: required symbol section not found\n");		return -1;	}	sect = find_section32(v32->hdr, ".text", NULL);	if (sect == NULL) {		printk(KERN_ERR "vDSO32: the .text section was not found\n");		return -1;	}	v32->text = sect - vdso32_kbase;#ifdef CONFIG_PPC64	v64->dynsym = find_section64(v64->hdr, ".dynsym", &v64->dynsymsize);	v64->dynstr = find_section64(v64->hdr, ".dynstr", NULL);	if (v64->dynsym == NULL || v64->dynstr == NULL) {		printk(KERN_ERR "vDSO64: required symbol section not found\n");		return -1;	}	sect = find_section64(v64->hdr, ".text", NULL);	if (sect == NULL) {		printk(KERN_ERR "vDSO64: the .text section was not found\n");		return -1;	}	v64->text = sect - vdso64_kbase;#endif /* CONFIG_PPC64 */	return 0;}static __init void vdso_setup_trampolines(struct lib32_elfinfo *v32,					  struct lib64_elfinfo *v64){	/*	 * Find signal trampolines	 */#ifdef CONFIG_PPC64	vdso64_rt_sigtramp = find_function64(v64, "__kernel_sigtramp_rt64");#endif	vdso32_sigtramp	   = find_function32(v32, "__kernel_sigtramp32");	vdso32_rt_sigtramp = find_function32(v32, "__kernel_sigtramp_rt32");}static __init int vdso_fixup_datapage(struct lib32_elfinfo *v32,				       struct lib64_elfinfo *v64){	Elf32_Sym *sym32;#ifdef CONFIG_PPC64	Elf64_Sym *sym64;       	sym64 = find_symbol64(v64, "__kernel_datapage_offset");	if (sym64 == NULL) {		printk(KERN_ERR "vDSO64: Can't find symbol "		       "__kernel_datapage_offset !\n");		return -1;	}	*((int *)(vdso64_kbase + sym64->st_value - VDSO64_LBASE)) =		(vdso64_pages << PAGE_SHIFT) -		(sym64->st_value - VDSO64_LBASE);#endif /* CONFIG_PPC64 */	sym32 = find_symbol32(v32, "__kernel_datapage_offset");	if (sym32 == NULL) {		printk(KERN_ERR "vDSO32: Can't find symbol "		       "__kernel_datapage_offset !\n");		return -1;	}	*((int *)(vdso32_kbase + (sym32->st_value - VDSO32_LBASE))) =		(vdso32_pages << PAGE_SHIFT) -		(sym32->st_value - VDSO32_LBASE);	return 0;}static __init int vdso_fixup_alt_funcs(struct lib32_elfinfo *v32,				       struct lib64_elfinfo *v64){	int i;	for (i = 0; i < ARRAY_SIZE(vdso_patches); i++) {		struct vdso_patch_def *patch = &vdso_patches[i];		int match = (cur_cpu_spec->cpu_features & patch->ftr_mask)			== patch->ftr_value;		if (!match)			continue;		DBG("replacing %s with %s...\n", patch->gen_name,		    patch->fix_name ? "NONE" : patch->fix_name);		/*		 * Patch the 32 bits and 64 bits symbols. Note that we do not		 * patch the "." symbol on 64 bits.		 * It would be easy to do, but doesn't seem to be necessary,		 * patching the OPD symbol is enough.		 */		vdso_do_func_patch32(v32, v64, patch->gen_name,				     patch->fix_name);#ifdef CONFIG_PPC64		vdso_do_func_patch64(v32, v64, patch->gen_name,				     patch->fix_name);#endif /* CONFIG_PPC64 */	}	return 0;}static __init int vdso_setup(void){	struct lib32_elfinfo	v32;	struct lib64_elfinfo	v64;	v32.hdr = vdso32_kbase;#ifdef CONFIG_PPC64	v64.hdr = vdso64_kbase;#endif	if (vdso_do_find_sections(&v32, &v64))		return -1;	if (vdso_fixup_datapage(&v32, &v64))		return -1;	if (vdso_fixup_alt_funcs(&v32, &v64))		return -1;	vdso_setup_trampolines(&v32, &v64);	return 0;}/* * Called from setup_arch to initialize the bitmap of available * syscalls in the systemcfg page */static void __init vdso_setup_syscall_map(void){	unsigned int i;	extern unsigned long *sys_call_table;	extern unsigned long sys_ni_syscall;	for (i = 0; i < __NR_syscalls; i++) {#ifdef CONFIG_PPC64		if (sys_call_table[i*2] != sys_ni_syscall)			vdso_data->syscall_map_64[i >> 5] |=				0x80000000UL >> (i & 0x1f);		if (sys_call_table[i*2+1] != sys_ni_syscall)			vdso_data->syscall_map_32[i >> 5] |=				0x80000000UL >> (i & 0x1f);#else /* CONFIG_PPC64 */		if (sys_call_table[i] != sys_ni_syscall)			vdso_data->syscall_map_32[i >> 5] |=				0x80000000UL >> (i & 0x1f);#endif /* CONFIG_PPC64 */	}}void __init vdso_init(void){	int i;#ifdef CONFIG_PPC64	/*	 * Fill up the "systemcfg" stuff for backward compatiblity	 */	strcpy(vdso_data->eye_catcher, "SYSTEMCFG:PPC64");	vdso_data->version.major = SYSTEMCFG_MAJOR;	vdso_data->version.minor = SYSTEMCFG_MINOR;	vdso_data->processor = mfspr(SPRN_PVR);	vdso_data->platform = _machine;	vdso_data->physicalMemorySize = lmb_phys_mem_size();	vdso_data->dcache_size = ppc64_caches.dsize;	vdso_data->dcache_line_size = ppc64_caches.dline_size;	vdso_data->icache_size = ppc64_caches.isize;	vdso_data->icache_line_size = ppc64_caches.iline_size;	/*	 * Calculate the size of the 64 bits vDSO	 */	vdso64_pages = (&vdso64_end - &vdso64_start) >> PAGE_SHIFT;	DBG("vdso64_kbase: %p, 0x%x pages\n", vdso64_kbase, vdso64_pages);#endif /* CONFIG_PPC64 */	/*	 * Calculate the size of the 32 bits vDSO	 */	vdso32_pages = (&vdso32_end - &vdso32_start) >> PAGE_SHIFT;	DBG("vdso32_kbase: %p, 0x%x pages\n", vdso32_kbase, vdso32_pages);	/*	 * Setup the syscall map in the vDOS	 */	vdso_setup_syscall_map();	/*	 * Initialize the vDSO images in memory, that is do necessary	 * fixups of vDSO symbols, locate trampolines, etc...	 */	if (vdso_setup()) {		printk(KERN_ERR "vDSO setup failure, not enabled !\n");		vdso32_pages = 0;#ifdef CONFIG_PPC64		vdso64_pages = 0;#endif		return;	}	/* Make sure pages are in the correct state */	for (i = 0; i < vdso32_pages; i++) {		struct page *pg = virt_to_page(vdso32_kbase + i*PAGE_SIZE);		ClearPageReserved(pg);		get_page(pg);	}#ifdef CONFIG_PPC64	for (i = 0; i < vdso64_pages; i++) {		struct page *pg = virt_to_page(vdso64_kbase + i*PAGE_SIZE);		ClearPageReserved(pg);		get_page(pg);	}#endif /* CONFIG_PPC64 */	get_page(virt_to_page(vdso_data));}int in_gate_area_no_task(unsigned long addr){	return 0;}int in_gate_area(struct task_struct *task, unsigned long addr){	return 0;}struct vm_area_struct *get_gate_vma(struct task_struct *tsk){	return NULL;}

⌨️ 快捷键说明

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