[2dcd13]: libperf_events / operf_kernel.cpp  Maximize  Restore  History

Download this file

128 lines (104 with data), 2.9 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
* @file pe_profiling/operf_kernel.cpp
* This file is based on daemon/opd_kernel and is used for
* dealing with the kernel and kernel module samples.
*
* @remark Copyright 2011 OProfile authors
* @remark Read the file COPYING
*
* Created on: Dec 12, 2011
* @author Maynard Johnson
* (C) Copyright IBM Corp. 2011
*/
#include <stdio.h>
#include <iostream>
#include <sstream>
#include <unistd.h>
#include <stdlib.h>
#include "operf_kernel.h"
#include "operf_sfile.h"
#include "op_list.h"
#include "op_libiberty.h"
#include "cverb.h"
#include "op_fileio.h"
extern verbose vmisc;
extern bool no_vmlinux;
static LIST_HEAD(modules);
static struct operf_kernel_image vmlinux_image;
using namespace std;
void operf_create_vmlinux(char const * name, char const * arg)
{
/* vmlinux is *not* on the list of modules */
list_init(&vmlinux_image.list);
/* for no vmlinux */
if (no_vmlinux) {
vmlinux_image.name = xstrdup("no-vmlinux");
return;
}
vmlinux_image.name = xstrdup(name);
sscanf(arg, "%llx,%llx", &vmlinux_image.start, &vmlinux_image.end);
ostringstream message;
message << "kernel_start = " << hex << vmlinux_image.start
<< "; kernel_end = " << vmlinux_image.end << endl;
cverb << vmisc << message.str();
if (!vmlinux_image.start && !vmlinux_image.end) {
ostringstream message;
message << "error: mis-parsed kernel range: " << hex << vmlinux_image.start
<< "; kernel_end = " << vmlinux_image.end << endl;
cerr << message.str();
exit(EXIT_FAILURE);
}
}
/**
* Allocate and initialise a kernel module image description.
* @param name image name
* @param start start address
* @param end end address
*/
void operf_create_module(char const * name, vma_t start, vma_t end)
{
struct operf_kernel_image * image =(struct operf_kernel_image *) xmalloc(sizeof(struct operf_kernel_image));
image->name = xstrdup(name);
image->start = start;
image->end = end;
list_add(&image->list, &modules);
}
void operf_free_modules_list(void)
{
struct list_head * pos;
struct list_head * pos2;
struct operf_kernel_image * image;
list_for_each_safe(pos, pos2, &modules) {
image = list_entry(pos, struct operf_kernel_image, list);
free(image->name);
list_del(&image->list);
free(image);
}
}
/**
* find a kernel image by PC value
* @param trans holds PC value to look up
*
* find the kernel image which contains this PC.
*
* Return %NULL if not found.
*/
struct operf_kernel_image * operf_find_kernel_image(vma_t pc)
{
struct list_head * pos;
struct operf_kernel_image * image = &vmlinux_image;
if (no_vmlinux)
return image;
if (image->start <= pc && image->end > pc)
return image;
list_for_each(pos, &modules) {
image = list_entry(pos, struct operf_kernel_image, list);
if (image->start <= pc && image->end > pc)
return image;
}
return NULL;
}
const char * operf_get_vmlinux_name(void)
{
return vmlinux_image.name;
}