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

📄 trace.c

📁 Linux2.4.20针对三星公司的s3c2410开发板的内核改造。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * linux/kernel/trace.c * * (C) Copyright 1999, 2000, 2001, 2002 - Karim Yaghmour (karym@opersys.com) * * This code is distributed under the GPL license * * Tracing management * */#include <linux/config.h>#include <linux/init.h>     /* For __init */#include <linux/trace.h>    /* Tracing definitions */#include <linux/errno.h>    /* Miscellaneous error codes */#include <linux/stddef.h>   /* NULL */#include <linux/slab.h>     /* kmalloc() */#include <linux/module.h>   /* EXPORT_SYMBOL */#include <linux/sched.h>    /* pid_t */#ifdef CONFIG_ARM#include <asm/irq.h>#include <asm/mach/irq.h>#include <asm/arch/irq.h>#else#include <linux/irq.h>      /* irq_desc */#endif/* Local variables */static int        tracer_registered = 0;   /* Is there a tracer registered */struct tracer *   tracer = NULL;           /* The registered tracer *//* Registration lock */rwlock_t tracer_register_lock = RW_LOCK_UNLOCKED;/* Trace callback table entry */struct trace_callback_table_entry{  tracer_call                         callback;    /* The callback function */  struct trace_callback_table_entry*  next;        /* Next entry */};/* Trace callback table */struct trace_callback_table_entry trace_callback_table[TRACE_EV_MAX];/* Custom event description */struct custom_event_desc{  /* The event itself */  trace_new_event              event;  /* PID of event owner, if any */  pid_t                        owner_pid;  /* List links */  struct custom_event_desc*    next;  struct custom_event_desc*    prev;};/* Next event ID to be used */int next_event_id;/* Circular list of custom events */struct custom_event_desc  custom_events_head;struct custom_event_desc* custom_events;/* Circular list lock */rwlock_t custom_list_lock = RW_LOCK_UNLOCKED;/**************************************************** * Register the tracer to the kernel * Return values : *   0, all is OK *   -EBUSY, there already is a registered tracer *   -ENOMEM, couldn't allocate memory ****************************************************/int register_tracer(tracer_call pm_trace_function){  unsigned long    l_flags;   /* Flags for irqsave */  /* Is there a tracer already registered */  if(tracer_registered == 1)    return -EBUSY;  /* Allocate memory for the tracer */  if((tracer = (struct tracer *) kmalloc(sizeof(struct tracer), GFP_ATOMIC)) == NULL)    /* We couldn't allocate any memory */    return -ENOMEM;  /* Lock registration variables */  write_lock_irqsave(&tracer_register_lock, l_flags);  /* There is a tracer registered */  tracer_registered = 1;  /* Set the tracer to the one being passed by the caller */  tracer->trace = pm_trace_function;  /* Unlock registration variables */  write_unlock_irqrestore(&tracer_register_lock, l_flags);  /* Initialize the tracer settings */  tracer->fetch_syscall_eip_use_bounds = 0;  tracer->fetch_syscall_eip_use_depth  = 0;  /* Tell the caller that everything went fine */  return 0;}/*************************************************** * Unregister the currently registered tracer * Return values : *   0, all is OK *   -ENOMEDIUM, there isn't a registered tracer *   -ENXIO, unregestering wrong tracer ***************************************************/int unregister_tracer(tracer_call pm_trace_function){  unsigned long    l_flags;   /* Flags for irqsave */  /* Is there a tracer already registered */  if(tracer_registered == 0)    /* Nothing to unregister */    return -ENOMEDIUM;  /* Lock registration variables */  write_lock_irqsave(&tracer_register_lock, l_flags);  /* Is it the tracer that was registered */  if(tracer->trace == pm_trace_function)    /* There isn't any tracer in here */    tracer_registered = 0;  else    {    /* Unlock registration variables */    write_unlock_irqrestore(&tracer_register_lock, l_flags);    /* We're done here */    return -ENXIO;    }  /* Free the memory used by the tracing structure */  kfree(tracer);  tracer = NULL;  /* Unlock registration variables */  write_unlock_irqrestore(&tracer_register_lock, l_flags);  /* Tell the caller that everything went OK */  return 0;}/******************************************************* * Set the tracing configuration * Parameters : *   pm_trace_function, the trace function. *   pm_fetch_syscall_use_depth, Use depth to fetch eip *   pm_fetch_syscall_use_bounds, Use bounds to fetch eip *   pm_syscall_eip_depth, Detph to fetch eip *   pm_syscall_lower_bound, Lower bound eip address *   pm_syscall_upper_bound, Upper bound eip address * Return values :  *   0, all is OK  *   -ENOMEDIUM, there isn't a registered tracer *   -ENXIO, wrong tracer *   -EINVAL, invalid configuration *******************************************************/int trace_set_config(tracer_call pm_trace_function,		     int         pm_fetch_syscall_use_depth,		     int         pm_fetch_syscall_use_bounds,		     int         pm_syscall_eip_depth,		     void*       pm_syscall_lower_bound,		     void*       pm_syscall_upper_bound){  /* Is there a tracer already registered */  if(tracer_registered == 0)    return -ENOMEDIUM;  /* Is it the tracer that was registered */  if(tracer->trace != pm_trace_function)    return -ENXIO;  /* Is this a valid configuration */  if((pm_fetch_syscall_use_depth && pm_fetch_syscall_use_bounds)   ||(pm_syscall_lower_bound > pm_syscall_upper_bound)   ||(pm_syscall_eip_depth < 0))    return -EINVAL;  /* Set the configuration */  tracer->fetch_syscall_eip_use_depth  = pm_fetch_syscall_use_depth;  tracer->fetch_syscall_eip_use_bounds = pm_fetch_syscall_use_bounds;  tracer->syscall_eip_depth = pm_syscall_eip_depth;  tracer->syscall_lower_eip_bound = pm_syscall_lower_bound;  tracer->syscall_upper_eip_bound = pm_syscall_upper_bound;  /* Tell the caller that everything was OK */  return 0;}/******************************************************* * Get the tracing configuration * Parameters : *   pm_fetch_syscall_use_depth, Use depth to fetch eip *   pm_fetch_syscall_use_bounds, Use bounds to fetch eip *   pm_syscall_eip_depth, Detph to fetch eip *   pm_syscall_lower_bound, Lower bound eip address *   pm_syscall_upper_bound, Upper bound eip address * Return values : *   0, all is OK  *   -ENOMEDIUM, there isn't a registered tracer *******************************************************/int trace_get_config(int*        pm_fetch_syscall_use_depth,		     int*        pm_fetch_syscall_use_bounds,		     int*        pm_syscall_eip_depth,		     void**      pm_syscall_lower_bound,		     void**      pm_syscall_upper_bound){  /* Is there a tracer already registered */  if(tracer_registered == 0)    return -ENOMEDIUM;  /* Get the configuration */  *pm_fetch_syscall_use_depth  = tracer->fetch_syscall_eip_use_depth;  *pm_fetch_syscall_use_bounds = tracer->fetch_syscall_eip_use_bounds;  *pm_syscall_eip_depth = tracer->syscall_eip_depth;  *pm_syscall_lower_bound = tracer->syscall_lower_eip_bound;  *pm_syscall_upper_bound = tracer->syscall_upper_eip_bound;  /* Tell the caller that everything was OK */  return 0;}/******************************************************* * Register a callback function to be called on occurence * of given event * Parameters : *   pm_trace_function, the callback function. *   pm_event_id, the event ID to be monitored. * Return values : *   0, all is OK *   -ENOMEM, unable to allocate memory for callback *******************************************************/int trace_register_callback(tracer_call pm_trace_function,			    uint8_t     pm_event_id){  struct trace_callback_table_entry*  p_tct_entry;  /* Search for an empty entry in the callback table */  for(p_tct_entry = &(trace_callback_table[pm_event_id - 1]);      p_tct_entry->next != NULL;      p_tct_entry = p_tct_entry->next);  /* Allocate a new callback */  if((p_tct_entry->next = kmalloc(sizeof(struct trace_callback_table_entry), GFP_ATOMIC)) == NULL)    return -ENOMEM;  /* Setup the new callback */  p_tct_entry->next->callback = pm_trace_function;  p_tct_entry->next->next     = NULL;  /* Tell the caller everything is ok */  return 0;}/******************************************************* * UnRegister a callback function. * Parameters : *   pm_trace_function, the callback function. *   pm_event_id, the event ID that had to be monitored. * Return values : *   0, all is OK *   -ENOMEDIUM, no such callback resigtered *******************************************************/int trace_unregister_callback(tracer_call pm_trace_function,			      uint8_t     pm_event_id){  struct trace_callback_table_entry*  p_tct_entry;  /* Pointer to trace callback table entry */  struct trace_callback_table_entry*  p_temp_entry; /* Pointer to trace callback table entry */  /* Search for the callback in the callback table */  for(p_tct_entry = &(trace_callback_table[pm_event_id - 1]);      ((p_tct_entry->next != NULL) && (p_tct_entry->next->callback != pm_trace_function));      p_tct_entry = p_tct_entry->next);  /* Did we find anything */  if(p_tct_entry == NULL)    return -ENOMEDIUM;  /* Free the callback entry */  p_temp_entry = p_tct_entry->next->next;  kfree(p_tct_entry->next);  p_tct_entry->next = p_temp_entry;  /* Tell the caller everything is ok */  return 0;}/******************************************************* * Create a new traceable event type * Parameters : *   pm_event_type, string describing event type *   pm_event_desc, string used for standard formatting *   pm_format_type, type of formatting used to log event *                 data *   pm_format_data, data specific to format *   pm_owner_pid, PID of event's owner (0 if none) * Return values : *   New Event ID if all is OK *   -ENOMEM, Unable to allocate new event *******************************************************/int _trace_create_event(char*            pm_event_type,			char*            pm_event_desc,			int              pm_format_type,			char*            pm_format_data,			pid_t            pm_owner_pid){  struct custom_event_desc* p_new_event;          /* Newly created event */  /* Create event */  if((p_new_event = (struct custom_event_desc*) kmalloc(sizeof(struct custom_event_desc), GFP_ATOMIC)) == NULL)    return -ENOMEM;  /* Initialize event properties */  p_new_event->event.type[0] = '\0';  p_new_event->event.desc[0] = '\0';  p_new_event->event.form[0] = '\0';  /* Set basic event properties */  if(pm_event_type != NULL)    strncpy(p_new_event->event.type, pm_event_type, CUSTOM_EVENT_TYPE_STR_LEN);  if(pm_event_desc != NULL)    strncpy(p_new_event->event.desc, pm_event_desc, CUSTOM_EVENT_DESC_STR_LEN);  if(pm_format_data != NULL)    strncpy(p_new_event->event.form, pm_format_data, CUSTOM_EVENT_FORM_STR_LEN);  /* Ensure that strings are bound */  p_new_event->event.type[CUSTOM_EVENT_TYPE_STR_LEN - 1] = '\0';  p_new_event->event.desc[CUSTOM_EVENT_DESC_STR_LEN - 1] = '\0';  p_new_event->event.form[CUSTOM_EVENT_FORM_STR_LEN - 1] = '\0';  /* Set format type */  p_new_event->event.format_type = pm_format_type;  /* Give the new event a unique event ID */  p_new_event->event.id = next_event_id;  next_event_id++;  /* Set event's owner */  p_new_event->owner_pid = pm_owner_pid;  /* Insert new event in event list */  write_lock(&custom_list_lock);

⌨️ 快捷键说明

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