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

📄 sym.c

📁 Sun Solaris 10 中的 DTrace 组件的源代码。请参看: http://www.sun.com/software/solaris/observability.jsp
💻 C
字号:
/* * Copyright 2005 Sun Microsystems, Inc.  All rights reserved. * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only. * See the file usr/src/LICENSING.NOTICE in this distribution or * http://www.opensolaris.org/license/ for details. */#pragma ident	"@(#)sym.c	1.3	99/07/27 SMI"#include <stdio.h>#include <fcntl.h>#include <ctype.h>#include <string.h>#include <signal.h>#include <errno.h>#include <stdlib.h>#include <stdarg.h>#include <unistd.h>#include <limits.h>#include <sys/types.h>#include <sys/stat.h>#include <libelf.h>#include <link.h>#include <elf.h>#include <sys/machelf.h>#include <kstat.h>#include <sys/cpuvar.h>typedef struct syment {	uintptr_t	addr;	char		*name;	size_t		size;} syment_t;static syment_t *symbol_table;static int nsyms, maxsyms;static char maxsymname[64];#ifdef _ELF64#define	elf_getshdr elf64_getshdr#else#define	elf_getshdr elf32_getshdr#endifstatic voidadd_symbol(char *name, uintptr_t addr, size_t size){	syment_t *sep;	if (nsyms >= maxsyms) {		maxsyms += 10000;		symbol_table = realloc(symbol_table, maxsyms * sizeof (*sep));		if (symbol_table == NULL) {			(void) fprintf(stderr, "can't allocate symbol table\n");			exit(3);		}	}	sep = &symbol_table[nsyms++];	sep->name = name;	sep->addr = addr;	sep->size = size;}static voidremove_symbol(uintptr_t addr){	int i;	syment_t *sep = symbol_table;	for (i = 0; i < nsyms; i++, sep++)		if (sep->addr == addr)			sep->addr = 0;}static voidfake_up_certain_popular_kernel_symbols(void){	kstat_ctl_t *kc;	kstat_t *ksp;	char *name;	if ((kc = kstat_open()) == NULL)		return;	for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {		if (strcmp(ksp->ks_module, "cpu_info") == 0) {			if ((name = malloc(20)) == NULL)				break;			/*			 * For consistency, keep cpu[0] and toss cpu0			 * or any other such symbols.			 */			if (ksp->ks_instance == 0)				remove_symbol((uintptr_t)ksp->ks_private);			(void) sprintf(name, "cpu[%d]", ksp->ks_instance);			add_symbol(name, (uintptr_t)ksp->ks_private,			    sizeof (struct cpu));		}	}	(void) kstat_close(kc);}static intsymcmp(const void *p1, const void *p2){	uintptr_t a1 = ((syment_t *)p1)->addr;	uintptr_t a2 = ((syment_t *)p2)->addr;	if (a1 < a2)		return (-1);	if (a1 > a2)		return (1);	return (0);}intsymtab_init(void){	Elf		*elf;	Elf_Scn		*scn = NULL;	Sym		*symtab, *symp, *lastsym;	char		*strtab;	uint_t		cnt;	int		fd;	int		i;	int		strindex = -1;	if ((fd = open("/dev/ksyms", O_RDONLY)) == -1)		return (-1);	(void) elf_version(EV_CURRENT);	elf = elf_begin(fd, ELF_C_READ, NULL);	for (cnt = 1; (scn = elf_nextscn(elf, scn)) != NULL; cnt++) {		Shdr *shdr = elf_getshdr(scn);		if (shdr->sh_type == SHT_SYMTAB) {			symtab = (Sym *)elf_getdata(scn, NULL)->d_buf;			nsyms = shdr->sh_size / shdr->sh_entsize;			strindex = shdr->sh_link;		}	}	for (cnt = 1; (scn = elf_nextscn(elf, scn)) != NULL; cnt++) {		if (cnt == strindex)			strtab = (char *)elf_getdata(scn, NULL)->d_buf;	}	lastsym = symtab + nsyms;	nsyms = 0;	for (symp = symtab; symp < lastsym; symp++)		if ((uint_t)ELF32_ST_TYPE(symp->st_info) <= STT_FUNC &&		    symp->st_size != 0)			add_symbol(symp->st_name + strtab,			    (uintptr_t)symp->st_value, (size_t)symp->st_size);	fake_up_certain_popular_kernel_symbols();	(void) sprintf(maxsymname, "0x%lx", ULONG_MAX);	add_symbol(maxsymname, ULONG_MAX, 1);	qsort(symbol_table, nsyms, sizeof (syment_t), symcmp);	/*	 * Destroy all duplicate symbols, then sort it again.	 */	for (i = 0; i < nsyms - 1; i++)		if (symbol_table[i].addr == symbol_table[i + 1].addr)			symbol_table[i].addr = 0;	qsort(symbol_table, nsyms, sizeof (syment_t), symcmp);	while (symbol_table[1].addr == 0) {		symbol_table++;		nsyms--;	}	symbol_table[0].name = "(usermode)";	symbol_table[0].addr = 0;	symbol_table[0].size = 1;	return (0);}char *addr_to_sym(uintptr_t addr, uintptr_t *offset, size_t *sizep){	int lo = 0;	int hi = nsyms - 1;	int mid;	syment_t *sep;	while (hi - lo > 1) {		mid = (lo + hi) / 2;		if (addr >= symbol_table[mid].addr) {			lo = mid;		} else {			hi = mid;		}	}	sep = &symbol_table[lo];	*offset = addr - sep->addr;	*sizep = sep->size;	return (sep->name);}uintptr_tsym_to_addr(char *name){	int i;	syment_t *sep = symbol_table;	for (i = 0; i < nsyms; i++) {		if (strcmp(name, sep->name) == 0)			return (sep->addr);		sep++;	}	return (NULL);}size_tsym_size(char *name){	int i;	syment_t *sep = symbol_table;	for (i = 0; i < nsyms; i++) {		if (strcmp(name, sep->name) == 0)			return (sep->size);		sep++;	}	return (0);}

⌨️ 快捷键说明

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