1 /** 2 * @file daemon/opd_mangling.c 3 * Mangling and opening of sample files 4 * 5 * @remark Copyright 2002 OProfile authors 6 * @remark Read the file COPYING 7 * 8 * @author John Levon 9 * @author Philippe Elie 10 */ 11 12 #include <sys/types.h> 13 14 #include "opd_mangling.h" 15 #include "opd_kernel.h" 16 #include "opd_cookie.h" 17 #include "opd_sfile.h" 18 #include "opd_anon.h" 19 #include "opd_printf.h" 20 #include "opd_events.h" 21 #include "oprofiled.h" 22 23 #include "op_file.h" 24 #include "op_sample_file.h" 25 #include "op_config.h" 26 #include "op_mangle.h" 27 #include "op_events.h" 28 #include "op_libiberty.h" 29 30 #include <limits.h> 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <string.h> 34 #include <errno.h> 35 36 37 static char const * get_dep_name(struct sfile const * sf) 38 { 39 if (sf->anon) 40 return find_cookie(sf->app_cookie); 41 42 /* avoid to call find_cookie(), caller can recover using image_name */ 43 if (sf->cookie == sf->app_cookie) 44 return NULL; 45 46 if (!separate_kernel && !(separate_lib && !sf->kernel)) 47 return NULL; 48 49 /* this will fail if e.g. kernel thread */ 50 if (sf->app_cookie == 0) 51 return NULL; 52 53 return find_cookie(sf->app_cookie); 54 } 55 56 57 static char * mangle_anon(struct anon_mapping const * anon) 58 { 59 char * name = xmalloc(PATH_MAX); 60 61 snprintf(name, 1024, "%u.0x%llx.0x%llx", (unsigned int)anon->tgid, 62 anon->start, anon->end); 63 64 return name; 65 } 66 67 68 static char * 69 mangle_filename(struct sfile * last, struct sfile const * sf, int counter, int cg) 70 { 71 char * mangled; 72 struct mangle_values values; 73 struct opd_event * event = find_counter_event(counter); 74 75 values.flags = 0; 76 77 if (sf->kernel) { 78 values.image_name = sf->kernel->name; 79 values.flags |= MANGLE_KERNEL; 80 } else if (sf->anon) { 81 values.flags |= MANGLE_ANON; 82 values.image_name = mangle_anon(sf->anon); 83 values.anon_name = sf->anon->name; 84 } else { 85 values.image_name = find_cookie(sf->cookie); 86 } 87 88 values.dep_name = get_dep_name(sf); 89 if (!values.dep_name) 90 values.dep_name = values.image_name; 91 92 /* FIXME: log */ 93 if (!values.image_name || !values.dep_name) 94 return NULL; 95 96 if (separate_thread) { 97 values.flags |= MANGLE_TGID | MANGLE_TID; 98 values.tid = sf->tid; 99 values.tgid = sf->tgid; 100 } 101 102 if (separate_cpu) { 103 values.flags |= MANGLE_CPU; 104 values.cpu = sf->cpu; 105 } 106 107 if (cg) { 108 values.flags |= MANGLE_CALLGRAPH; 109 if (last->kernel) { 110 values.cg_image_name = last->kernel->name; 111 } else if (last->anon) { 112 values.flags |= MANGLE_CG_ANON; 113 values.cg_image_name = mangle_anon(last->anon); 114 values.anon_name = last->anon->name; 115 } else { 116 values.cg_image_name = find_cookie(last->cookie); 117 } 118 119 /* FIXME: log */ 120 if (!values.cg_image_name) { 121 if (values.flags & MANGLE_ANON) 122 free((char *)values.image_name); 123 return NULL; 124 } 125 } 126 127 values.event_name = event->name; 128 values.count = event->count; 129 values.unit_mask = event->um; 130 131 mangled = op_mangle_filename(&values); 132 133 if (values.flags & MANGLE_ANON) 134 free((char *)values.image_name); 135 if (values.flags & MANGLE_CG_ANON) 136 free((char *)values.cg_image_name); 137 return mangled; 138 } 139 140 141 int opd_open_sample_file(odb_t *file, struct sfile *last, 142 struct sfile * sf, int counter, int cg) 143 { 144 char * mangled; 145 char const * binary; 146 int spu_profile = 0; 147 vma_t last_start = 0; 148 int err; 149 150 mangled = mangle_filename(last, sf, counter, cg); 151 152 if (!mangled) 153 return EINVAL; 154 155 verbprintf(vsfile, "Opening \"%s\"\n", mangled); 156 157 create_path(mangled); 158 159 /* locking sf will lock associated cg files too */ 160 sfile_get(sf); 161 if (sf != last) 162 sfile_get(last); 163 164 retry: 165 err = odb_open(file, mangled, ODB_RDWR, sizeof(struct opd_header)); 166 167 /* This can naturally happen when racing against opcontrol --reset. */ 168 if (err) { 169 if (err == EMFILE) { 170 if (sfile_lru_clear()) { 171 printf("LRU cleared but odb_open() fails for %s.\n", mangled); 172 abort(); 173 } 174 goto retry; 175 } 176 177 fprintf(stderr, "oprofiled: open of %s failed: %s\n", 178 mangled, strerror(err)); 179 goto out; 180 } 181 182 if (!sf->kernel) 183 binary = find_cookie(sf->cookie); 184 else 185 binary = sf->kernel->name; 186 187 if (last && last->anon) 188 last_start = last->anon->start; 189 190 if (sf->embedded_offset != UNUSED_EMBEDDED_OFFSET) 191 spu_profile = 1; 192 193 fill_header(odb_get_data(file), counter, 194 sf->anon ? sf->anon->start : 0, last_start, 195 !!sf->kernel, last ? !!last->kernel : 0, 196 spu_profile, sf->embedded_offset, 197 binary ? op_get_mtime(binary) : 0); 198 199 out: 200 sfile_put(sf); 201 if (sf != last) 202 sfile_put(last); 203 free(mangled); 204 return err; 205 } 206