MINI SHELL

Server : Apache/2.2.2 (Fedora)
System : Linux App1.pathumtani.go.th 2.6.20-1.2320.fc5smp #1 SMP Tue Jun 12 19:40:16 EDT 2007 i686
User : apache ( 48)
PHP Version : 5.2.9
Disable Function : NONE
Directory :  /usr/share/systemtap/runtime/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : //usr/share/systemtap/runtime/sym.c
/* -*- linux-c -*- 
 * Symbolic Lookup Functions
 * Copyright (C) 2005 Red Hat Inc.
 * Copyright (C) 2006 Intel Corporation.
 *
 * This file is part of systemtap, and is free software.  You can
 * redistribute it and/or modify it under the terms of the GNU General
 * Public License (GPL); either version 2, or (at your option) any
 * later version.
 */

#ifndef _SYM_C_
#define _SYM_C_

#include "string.c"

/** @file sym.c
 * @addtogroup sym Symbolic Functions
 * Symbolic Lookup Functions
 * @{
 */

/* Lookup the kernel address for this symbol. Returns 0 if not found. */
static unsigned long _stp_kallsyms_lookup_name(const char *name)
{
	struct stap_symbol *s = &stap_symbols[0];
	unsigned num = stap_num_symbols;

	/* Warning: Linear search. If this function ends up being used in */
	/* time-critical places, maybe we need to create a new symbol table */
	/* sorted by name. */

	while (num--) {
		if ((strcmp(name, s->symbol) == 0) && (strcmp(s->modname,"") == 0))
			return s->addr;
		s++;
	}

	return 0;
}

static const char * _stp_kallsyms_lookup (
	unsigned long addr,
	unsigned long *symbolsize,
	unsigned long *offset,
	char **modname,
	char *namebuf)
{
	unsigned begin = 0;
	unsigned end = stap_num_symbols;
	/*const*/ struct stap_symbol* s;

	/* binary search on index [begin,end) */
	do {
		unsigned mid = (begin + end) / 2;
		if (addr < stap_symbols[mid].addr)
			end = mid;
		else
			begin = mid;
	} while (begin + 1 < end);
	/* result index in $begin, guaranteed between [0,stap_num_symbols) */

	s = & stap_symbols [begin];
	if (addr < s->addr)
		return NULL;
	else {
		if (offset) *offset = addr - s->addr;
		if (modname) *modname = (char *) s->modname;
		if (symbolsize) {
			if ((begin + 1) < stap_num_symbols)
				*symbolsize = stap_symbols[begin+1].addr - s->addr;
			else
				*symbolsize = 0;
			// NB: This is only a heuristic.  Sometimes there are large
			// gaps between text areas of modules.
		}
		if (namebuf) {
			strlcpy (namebuf, s->symbol, KSYM_NAME_LEN+1);
			return namebuf;
		}
		else
			return s->symbol;
	}
}

/** Write addresses symbolically into a String
 * @param str String
 * @param address The address to lookup.
 * @note Symbolic lookups should not normally be done within
 * a probe because it is too time-consuming. Use at module exit time.
 */

String _stp_symbol_sprint (String str, unsigned long address)
{ 
	char *modname;
        const char *name;
        unsigned long offset, size;
        char namebuf[KSYM_NAME_LEN+1];

        name = _stp_kallsyms_lookup(address, &size, &offset, &modname, namebuf);

	_stp_sprintf (str, "%p", (void *)address);

	if (name) {		
		if (modname)
			_stp_sprintf (str, " : %s+%#lx/%#lx [%s]", name, offset, size, modname);
		else
			_stp_sprintf (str, " : %s+%#lx/%#lx", name, offset, size);
	}
	return str;
}


/** Print addresses symbolically to the print buffer.
 * @param address The address to lookup.
 * @note Symbolic lookups should not normally be done within
 * a probe because it is too time-consuming. Use at module exit time.
 */

#define _stp_symbol_print(address) _stp_symbol_sprint(_stp_stdout,address)


/** Write addresses symbolically into a char buffer
 * @param str Destination buffer
 * @param len Length of destination buffer
 * @param address The address to lookup.
 * @note Symbolic lookups should not normally be done within
 * a probe because it is too time-consuming. Use at module exit time.
 */

const char *_stp_symbol_sprint_basic (char *str, size_t len, unsigned long address)
{ 
    char *modname;
    const char *name;
    unsigned long offset, size;
    char namebuf[KSYM_NAME_LEN+1];

    if (len > KSYM_NAME_LEN) {
        name = _stp_kallsyms_lookup(address, &size, &offset, &modname, str);
        if (!name)
		snprintf(str, len, "%p", (void *)address);
    } else {
        name = _stp_kallsyms_lookup(address, &size, &offset, &modname, namebuf);
        if (name)
            strlcpy(str, namebuf, len);
        else
		snprintf(str, len, "%p", (void *)address);
    }

    return str;
}

/** @} */
#endif /* _SYM_C_ */

Anon7 - 2021