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 /* untested */
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 /* O32 */
00046 #if _MIPS_SIM == _MIPS_SIM_ABI32
00047 #define __NR_lookup_dcookie 4247
00048 /* N64 */
00049 #elif _MIPS_SIM == _MIPS_SIM_ABI64
00050 #define __NR_lookup_dcookie 5206
00051 /* N32 */
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 /* __NR_lookup_dcookie */
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 /* Cookie monster want cookie! */
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     /* not sure this can ever happen due to is_cookie_ignored */
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 }

Generated on 8 Nov 2012 for Oprofile by  doxygen 1.6.1