blob: 48e1e80b334989f83161a119d7c7d36ce9d03b31 [file] [log] [blame]
Upstreamcc2ee171970-01-12 13:46:40 +00001/**
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__))
64static inline int lookup_dcookie(cookie_t cookie, char * buf, size_t size)
65{
66 return syscall(__NR_lookup_dcookie, (unsigned long)(cookie >> 32),
67 (unsigned long)(cookie & 0xffffffff), buf, size);
68}
69#else
70static inline int lookup_dcookie(cookie_t cookie, char * buf, size_t size)
71{
72 return syscall(__NR_lookup_dcookie, cookie, buf, size);
73}
74#endif
75
76
77struct cookie_entry {
78 cookie_t value;
79 char * name;
80 int ignored;
81 struct list_head list;
82};
83
84
85#define HASH_SIZE 512
86#define HASH_BITS (HASH_SIZE - 1)
87
88static struct list_head hashes[HASH_SIZE];
89
90static struct cookie_entry * create_cookie(cookie_t cookie)
91{
92 int err;
93 struct cookie_entry * entry = xmalloc(sizeof(struct cookie_entry));
94
95 entry->value = cookie;
96 entry->name = xmalloc(PATH_MAX + 1);
97
98 err = lookup_dcookie(cookie, entry->name, PATH_MAX);
99
100 if (err < 0) {
101 fprintf(stderr, "Lookup of cookie %llx failed, errno=%d\n",
102 cookie, errno);
103 free(entry->name);
104 entry->name = NULL;
105 entry->ignored = 0;
106 } else {
107 entry->ignored = is_image_ignored(entry->name);
108 }
109
110 return entry;
111}
112
113
114/* Cookie monster want cookie! */
115static unsigned long hash_cookie(cookie_t cookie)
116{
117 return (cookie >> DCOOKIE_SHIFT) & (HASH_SIZE - 1);
118}
119
120
121char const * find_cookie(cookie_t cookie)
122{
123 unsigned long hash = hash_cookie(cookie);
124 struct list_head * pos;
125 struct cookie_entry * entry;
126
127 if (cookie == INVALID_COOKIE || cookie == NO_COOKIE)
128 return NULL;
129
130 list_for_each(pos, &hashes[hash]) {
131 entry = list_entry(pos, struct cookie_entry, list);
132 if (entry->value == cookie)
133 goto out;
134 }
135
136 /* not sure this can ever happen due to is_cookie_ignored */
137 entry = create_cookie(cookie);
138 list_add(&entry->list, &hashes[hash]);
139out:
140 return entry->name;
141}
142
143
144int is_cookie_ignored(cookie_t cookie)
145{
146 unsigned long hash = hash_cookie(cookie);
147 struct list_head * pos;
148 struct cookie_entry * entry;
149
150 if (cookie == INVALID_COOKIE || cookie == NO_COOKIE)
151 return 1;
152
153 list_for_each(pos, &hashes[hash]) {
154 entry = list_entry(pos, struct cookie_entry, list);
155 if (entry->value == cookie)
156 goto out;
157 }
158
159 entry = create_cookie(cookie);
160 list_add(&entry->list, &hashes[hash]);
161out:
162 return entry->ignored;
163}
164
165
166char const * verbose_cookie(cookie_t cookie)
167{
168 unsigned long hash = hash_cookie(cookie);
169 struct list_head * pos;
170 struct cookie_entry * entry;
171
172 if (cookie == INVALID_COOKIE)
173 return "invalid";
174
175 if (cookie == NO_COOKIE)
176 return "anonymous";
177
178 list_for_each(pos, &hashes[hash]) {
179 entry = list_entry(pos, struct cookie_entry, list);
180 if (entry->value == cookie) {
181 if (!entry->name)
182 return "failed lookup";
183 return entry->name;
184 }
185 }
186
187 return "not hashed";
188}
189
190
191void cookie_init(void)
192{
193 size_t i;
194
195 for (i = 0; i < HASH_SIZE; ++i)
196 list_init(&hashes[i]);
197}