• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * @file opd_cookie.c
3  * cookie -> name cache
4  *
5  * @remark Copyright 2002, 2005 OProfile authors
6  * @remark Read the file COPYING
7  *
8  * @author John Levon
9  */
10 
11 #include "opd_cookie.h"
12 #include "oprofiled.h"
13 #include "op_list.h"
14 #include "op_libiberty.h"
15 
16 #include <sys/syscall.h>
17 #include <unistd.h>
18 #include <limits.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <errno.h>
22 
23 #ifndef __NR_lookup_dcookie
24 #if defined(__i386__)
25 #define __NR_lookup_dcookie 253
26 #elif defined(__x86_64__)
27 #define __NR_lookup_dcookie 212
28 #elif defined(__powerpc__)
29 #define __NR_lookup_dcookie 235
30 #elif defined(__alpha__)
31 #define __NR_lookup_dcookie 406
32 #elif defined(__hppa__)
33 #define __NR_lookup_dcookie 223
34 #elif defined(__ia64__)
35 #define __NR_lookup_dcookie 1237
36 #elif defined(__sparc__)
37 /* untested */
38 #define __NR_lookup_dcookie 208
39 #elif defined(__s390__) || defined (__s390x__)
40 #define __NR_lookup_dcookie 110
41 #elif defined(__arm__)
42 #define __NR_lookup_dcookie (__NR_SYSCALL_BASE+249)
43 #elif defined(__mips__)
44 #include <sgidefs.h>
45 /* O32 */
46 #if _MIPS_SIM == _MIPS_SIM_ABI32
47 #define __NR_lookup_dcookie 4247
48 /* N64 */
49 #elif _MIPS_SIM == _MIPS_SIM_ABI64
50 #define __NR_lookup_dcookie 5206
51 /* N32 */
52 #elif _MIPS_SIM == _MIPS_SIM_NABI32
53 #define __NR_lookup_dcookie 6206
54 #else
55 #error Unknown MIPS ABI: Dunno __NR_lookup_dcookie
56 #endif
57 #else
58 #error Please define __NR_lookup_dcookie for your architecture
59 #endif
60 #endif /* __NR_lookup_dcookie */
61 
62 #if (defined(__powerpc__) && !defined(__powerpc64__)) || defined(__hppa__)\
63 	|| (defined(__s390__) && !defined(__s390x__)) \
64 	|| (defined(__mips__) && (_MIPS_SIM == _MIPS_SIM_ABI32) \
65 	    && defined(__MIPSEB__)) \
66         || (defined(__arm__) && defined(__ARM_EABI__) \
67             && defined(__ARMEB__))
lookup_dcookie(cookie_t cookie,char * buf,size_t size)68 static inline int lookup_dcookie(cookie_t cookie, char * buf, size_t size)
69 {
70 	return syscall(__NR_lookup_dcookie, (unsigned long)(cookie >> 32),
71 		       (unsigned long)(cookie & 0xffffffff), buf, size);
72 }
73 #elif (defined(__mips__) && (_MIPS_SIM == _MIPS_SIM_ABI32)) \
74 	|| (defined(__arm__) && defined(__ARM_EABI__))
lookup_dcookie(cookie_t cookie,char * buf,size_t size)75 static inline int lookup_dcookie(cookie_t cookie, char * buf, size_t size)
76 {
77 	return syscall(__NR_lookup_dcookie,
78 		       (unsigned long)(cookie & 0xffffffff),
79 		       (unsigned long)(cookie >> 32), buf, size);
80 }
81 #else
lookup_dcookie(cookie_t cookie,char * buf,size_t size)82 static inline int lookup_dcookie(cookie_t cookie, char * buf, size_t size)
83 {
84 	return syscall(__NR_lookup_dcookie, cookie, buf, size);
85 }
86 #endif
87 
88 
89 struct cookie_entry {
90 	cookie_t value;
91 	char * name;
92 	int ignored;
93 	struct list_head list;
94 };
95 
96 
97 #define HASH_SIZE 512
98 #define HASH_BITS (HASH_SIZE - 1)
99 
100 static struct list_head hashes[HASH_SIZE];
101 
create_cookie(cookie_t cookie)102 static struct cookie_entry * create_cookie(cookie_t cookie)
103 {
104 	int err;
105 	struct cookie_entry * entry = xmalloc(sizeof(struct cookie_entry));
106 
107 	entry->value = cookie;
108 	entry->name = xmalloc(PATH_MAX + 1);
109 
110 	err = lookup_dcookie(cookie, entry->name, PATH_MAX);
111 
112 	if (err < 0) {
113 		fprintf(stderr, "Lookup of cookie %llx failed, errno=%d\n",
114 		       cookie, errno);
115 		free(entry->name);
116 		entry->name = NULL;
117 		entry->ignored = 0;
118 	} else {
119 		entry->ignored = is_image_ignored(entry->name);
120 	}
121 
122 	return entry;
123 }
124 
125 
126 /* Cookie monster want cookie! */
hash_cookie(cookie_t cookie)127 static unsigned long hash_cookie(cookie_t cookie)
128 {
129 	return (cookie >> DCOOKIE_SHIFT) & (HASH_SIZE - 1);
130 }
131 
132 
find_cookie(cookie_t cookie)133 char const * find_cookie(cookie_t cookie)
134 {
135 	unsigned long hash = hash_cookie(cookie);
136 	struct list_head * pos;
137 	struct cookie_entry * entry;
138 
139 	if (cookie == INVALID_COOKIE || cookie == NO_COOKIE)
140 		return NULL;
141 
142 	list_for_each(pos, &hashes[hash]) {
143 		entry = list_entry(pos, struct cookie_entry, list);
144 		if (entry->value == cookie)
145 			goto out;
146 	}
147 
148 	/* not sure this can ever happen due to is_cookie_ignored */
149 	entry = create_cookie(cookie);
150 	list_add(&entry->list, &hashes[hash]);
151 out:
152 	return entry->name;
153 }
154 
155 
is_cookie_ignored(cookie_t cookie)156 int is_cookie_ignored(cookie_t cookie)
157 {
158 	unsigned long hash = hash_cookie(cookie);
159 	struct list_head * pos;
160 	struct cookie_entry * entry;
161 
162 	if (cookie == INVALID_COOKIE || cookie == NO_COOKIE)
163 		return 1;
164 
165 	list_for_each(pos, &hashes[hash]) {
166 		entry = list_entry(pos, struct cookie_entry, list);
167 		if (entry->value == cookie)
168 			goto out;
169 	}
170 
171 	entry = create_cookie(cookie);
172 	list_add(&entry->list, &hashes[hash]);
173 out:
174 	return entry->ignored;
175 }
176 
177 
verbose_cookie(cookie_t cookie)178 char const * verbose_cookie(cookie_t cookie)
179 {
180 	unsigned long hash = hash_cookie(cookie);
181 	struct list_head * pos;
182 	struct cookie_entry * entry;
183 
184 	if (cookie == INVALID_COOKIE)
185 		return "invalid";
186 
187 	if (cookie == NO_COOKIE)
188 		return "anonymous";
189 
190 	list_for_each(pos, &hashes[hash]) {
191 		entry = list_entry(pos, struct cookie_entry, list);
192 		if (entry->value == cookie) {
193 			if (!entry->name)
194 				return "failed lookup";
195 			return entry->name;
196 		}
197 	}
198 
199 	return "not hashed";
200 }
201 
202 
cookie_init(void)203 void cookie_init(void)
204 {
205 	size_t i;
206 
207 	for (i = 0; i < HASH_SIZE; ++i)
208 		list_init(&hashes[i]);
209 }
210