opd_cookie.c
Go to the documentation of this file.00001
00011 #include "opd_cookie.h"
00012 #include "oprofiled.h"
00013 #include "op_list.h"
00014 #include "op_libiberty.h"
00015
00016 #include <sys/syscall.h>
00017 #include <unistd.h>
00018 #include <limits.h>
00019 #include <stdio.h>
00020 #include <stdlib.h>
00021 #include <errno.h>
00022
00023 #ifndef __NR_lookup_dcookie
00024 #if defined(__i386__)
00025 #define __NR_lookup_dcookie 253
00026 #elif defined(__x86_64__)
00027 #define __NR_lookup_dcookie 212
00028 #elif defined(__powerpc__)
00029 #define __NR_lookup_dcookie 235
00030 #elif defined(__alpha__)
00031 #define __NR_lookup_dcookie 406
00032 #elif defined(__hppa__)
00033 #define __NR_lookup_dcookie 223
00034 #elif defined(__ia64__)
00035 #define __NR_lookup_dcookie 1237
00036 #elif defined(__sparc__)
00037
00038 #define __NR_lookup_dcookie 208
00039 #elif defined(__s390__) || defined (__s390x__)
00040 #define __NR_lookup_dcookie 110
00041 #elif defined(__arm__)
00042 #define __NR_lookup_dcookie (__NR_SYSCALL_BASE+249)
00043 #elif defined(__mips__)
00044 #include <sgidefs.h>
00045
00046 #if _MIPS_SIM == _MIPS_SIM_ABI32
00047 #define __NR_lookup_dcookie 4247
00048
00049 #elif _MIPS_SIM == _MIPS_SIM_ABI64
00050 #define __NR_lookup_dcookie 5206
00051
00052 #elif _MIPS_SIM == _MIPS_SIM_NABI32
00053 #define __NR_lookup_dcookie 6206
00054 #else
00055 #error Unknown MIPS ABI: Dunno __NR_lookup_dcookie
00056 #endif
00057 #else
00058 #error Please define __NR_lookup_dcookie for your architecture
00059 #endif
00060 #endif
00061
00062 #if (defined(__powerpc__) && !defined(__powerpc64__)) || defined(__hppa__)\
00063 || (defined(__s390__) && !defined(__s390x__)) \
00064 || (defined(__mips__) && (_MIPS_SIM == _MIPS_SIM_ABI32) \
00065 && defined(__MIPSEB__)) \
00066 || (defined(__arm__) && defined(__ARM_EABI__) \
00067 && defined(__ARMEB__))
00068 static inline int lookup_dcookie(cookie_t cookie, char * buf, size_t size)
00069 {
00070 return syscall(__NR_lookup_dcookie, (unsigned long)(cookie >> 32),
00071 (unsigned long)(cookie & 0xffffffff), buf, size);
00072 }
00073 #elif (defined(__mips__) && (_MIPS_SIM == _MIPS_SIM_ABI32)) \
00074 || (defined(__arm__) && defined(__ARM_EABI__)) \
00075 || (defined(__tile__) && !defined(__LP64__))
00076 static inline int lookup_dcookie(cookie_t cookie, char * buf, size_t size)
00077 {
00078 return syscall(__NR_lookup_dcookie,
00079 (unsigned long)(cookie & 0xffffffff),
00080 (unsigned long)(cookie >> 32), buf, size);
00081 }
00082 #else
00083 static inline int lookup_dcookie(cookie_t cookie, char * buf, size_t size)
00084 {
00085 return syscall(__NR_lookup_dcookie, cookie, buf, size);
00086 }
00087 #endif
00088
00089
00090 struct cookie_entry {
00091 cookie_t value;
00092 char * name;
00093 int ignored;
00094 struct list_head list;
00095 };
00096
00097
00098 #define HASH_SIZE 512
00099 #define HASH_BITS (HASH_SIZE - 1)
00100
00101 static struct list_head hashes[HASH_SIZE];
00102
00103 static struct cookie_entry * create_cookie(cookie_t cookie)
00104 {
00105 int err;
00106 struct cookie_entry * entry = xmalloc(sizeof(struct cookie_entry));
00107
00108 entry->value = cookie;
00109 entry->name = xmalloc(PATH_MAX + 1);
00110
00111 err = lookup_dcookie(cookie, entry->name, PATH_MAX);
00112
00113 if (err < 0) {
00114 fprintf(stderr, "Lookup of cookie %llx failed, errno=%d\n",
00115 cookie, errno);
00116 free(entry->name);
00117 entry->name = NULL;
00118 entry->ignored = 0;
00119 } else {
00120 entry->ignored = is_image_ignored(entry->name);
00121 }
00122
00123 return entry;
00124 }
00125
00126
00127
00128 static unsigned long hash_cookie(cookie_t cookie)
00129 {
00130 return (cookie >> DCOOKIE_SHIFT) & (HASH_SIZE - 1);
00131 }
00132
00133
00134 char const * find_cookie(cookie_t cookie)
00135 {
00136 unsigned long hash = hash_cookie(cookie);
00137 struct list_head * pos;
00138 struct cookie_entry * entry;
00139
00140 if (cookie == INVALID_COOKIE || cookie == NO_COOKIE)
00141 return NULL;
00142
00143 list_for_each(pos, &hashes[hash]) {
00144 entry = list_entry(pos, struct cookie_entry, list);
00145 if (entry->value == cookie)
00146 goto out;
00147 }
00148
00149
00150 entry = create_cookie(cookie);
00151 list_add(&entry->list, &hashes[hash]);
00152 out:
00153 return entry->name;
00154 }
00155
00156
00157 int is_cookie_ignored(cookie_t cookie)
00158 {
00159 unsigned long hash = hash_cookie(cookie);
00160 struct list_head * pos;
00161 struct cookie_entry * entry;
00162
00163 if (cookie == INVALID_COOKIE || cookie == NO_COOKIE)
00164 return 1;
00165
00166 list_for_each(pos, &hashes[hash]) {
00167 entry = list_entry(pos, struct cookie_entry, list);
00168 if (entry->value == cookie)
00169 goto out;
00170 }
00171
00172 entry = create_cookie(cookie);
00173 list_add(&entry->list, &hashes[hash]);
00174 out:
00175 return entry->ignored;
00176 }
00177
00178
00179 char const * verbose_cookie(cookie_t cookie)
00180 {
00181 unsigned long hash = hash_cookie(cookie);
00182 struct list_head * pos;
00183 struct cookie_entry * entry;
00184
00185 if (cookie == INVALID_COOKIE)
00186 return "invalid";
00187
00188 if (cookie == NO_COOKIE)
00189 return "anonymous";
00190
00191 list_for_each(pos, &hashes[hash]) {
00192 entry = list_entry(pos, struct cookie_entry, list);
00193 if (entry->value == cookie) {
00194 if (!entry->name)
00195 return "failed lookup";
00196 return entry->name;
00197 }
00198 }
00199
00200 return "not hashed";
00201 }
00202
00203
00204 void cookie_init(void)
00205 {
00206 size_t i;
00207
00208 for (i = 0; i < HASH_SIZE; ++i)
00209 list_init(&hashes[i]);
00210 }