aboutsummaryrefslogtreecommitdiff
path: root/libpp/symbol.h
blob: ea2724d5e140626200b14ad524387cb197f76beb (plain)
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/**
 * @file symbol.h
 * Symbol containers
 *
 * @remark Copyright 2002, 2004 OProfile authors
 * @remark Read the file COPYING
 *
 * @author Philippe Elie
 * @author John Levon
 */

#ifndef SYMBOL_H
#define SYMBOL_H

#include "name_storage.h"
#include "growable_vector.h"
#include "sparse_array.h"
#include "format_flags.h"
#include "op_types.h"

#include <bfd.h>
#include <stdint.h>

#include <list>

class extra_images;


/// for storing sample counts
typedef sparse_array<u32, count_type> count_array_t;


/// A simple container for a fileno:linenr location.
struct file_location {
	file_location() : linenr(0) {}
	/// empty if not valid.
	debug_name_id filename;
	/// 0 means invalid or code is generated internally by the compiler
	unsigned int linenr;

	bool operator<(file_location const & rhs) const {
		// Note we sort on filename id not on string
		return filename < rhs.filename ||
		  (filename == rhs.filename && linenr < rhs.linenr);
	}
};


/// associate vma address with a file location and a samples count
struct sample_entry {
	sample_entry() : vma(0) {}
	/// From where file location comes the samples
	file_location file_loc;
	/// From where virtual memory address comes the samples
	bfd_vma vma;
	/// the samples count
	count_array_t counts;
};


/// associate a symbol with a file location, samples count and vma address
class symbol_entry {
public:
	symbol_entry() : size(0) {}
	virtual ~symbol_entry() {}

	/// which image this symbol belongs to
	image_name_id image_name;
	/// owning application name: identical to image name if profiling
	/// session did not separate samples for shared libs or if image_name
	/// is not a shared lib
	image_name_id app_name;
	// index into the op_bfd symbol table
	size_t sym_index;
	/// file location, vma and cumulated samples count for this symbol
	sample_entry sample;
	/// name of symbol
	symbol_name_id name;
	/// symbol size as calculated by op_bfd, start of symbol is sample.vma
	size_t size;

	/**
	 * @param fl  input hint
	 *
	 * combine fl with the calculated hint. It's theoretically possible
	 * that we get a symbol where its samples pass the border line, but
	 * the start is below it, but the the hint is only used for formatting
	 */
	column_flags output_hint(column_flags fl) const;
	uint64_t spu_offset;
	image_name_id embedding_filename;
};


/// a collection of sorted symbols
typedef std::vector<symbol_entry const *> symbol_collection;


/**
 * The public data for call-graph symbols. Each caller/callee has
 * the sample counts replaced with the relevant arc counts, whilst
 * the cg_symbol retains its self count.
 */
class cg_symbol : public symbol_entry {
public:
	cg_symbol(symbol_entry const & sym) : symbol_entry(sym) {}

	typedef std::vector<symbol_entry> children;

	/// all callers of this symbol
	children callers;
	/// total count of callers
	count_array_t total_caller_count;

	/// all symbols called by this symbol
	children callees;
	/// total count of callees
	count_array_t total_callee_count;
};

/// a collection of sorted callgraph symbol objects
typedef std::list<cg_symbol> cg_collection_objs;

/// for storing diff %ages
typedef growable_vector<double> diff_array_t;


/**
 * Data for a diffed symbol.
 */
struct diff_symbol : public symbol_entry  {
	diff_symbol(symbol_entry const & sym) : symbol_entry(sym) {}

	/// diff %age values for each profile class
	diff_array_t diffs;
};


/// a collection of diffed symbols
typedef std::vector<diff_symbol> diff_collection;

bool has_sample_counts(count_array_t const & counts, size_t lo, size_t hi);
std::string const & get_image_name(image_name_id id,
				   image_name_storage::image_name_type type,
				   extra_images const & extra);


#endif /* !SYMBOL_H */