opd_mangling.c
Go to the documentation of this file.00001
00012 #include <sys/types.h>
00013
00014 #include "opd_mangling.h"
00015 #include "opd_kernel.h"
00016 #include "opd_cookie.h"
00017 #include "opd_sfile.h"
00018 #include "opd_anon.h"
00019 #include "opd_printf.h"
00020 #include "opd_events.h"
00021 #include "oprofiled.h"
00022
00023 #include "op_file.h"
00024 #include "op_sample_file.h"
00025 #include "op_config.h"
00026 #include "op_mangle.h"
00027 #include "op_events.h"
00028 #include "op_libiberty.h"
00029
00030 #include <limits.h>
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include <errno.h>
00035
00036
00037 static char const * get_dep_name(struct sfile const * sf)
00038 {
00039 if (sf->anon)
00040 return find_cookie(sf->app_cookie);
00041
00042
00043 if (sf->cookie == sf->app_cookie)
00044 return NULL;
00045
00046 if (!separate_kernel && !(separate_lib && !sf->kernel))
00047 return NULL;
00048
00049
00050 if (sf->app_cookie == 0)
00051 return NULL;
00052
00053 return find_cookie(sf->app_cookie);
00054 }
00055
00056
00057 static char * mangle_anon(struct anon_mapping const * anon)
00058 {
00059 char * name = xmalloc(PATH_MAX);
00060
00061 snprintf(name, 1024, "%u.0x%llx.0x%llx", (unsigned int)anon->tgid,
00062 anon->start, anon->end);
00063
00064 return name;
00065 }
00066
00067
00068 static char *
00069 mangle_filename(struct sfile * last, struct sfile const * sf, int counter, int cg)
00070 {
00071 char * mangled;
00072 struct mangle_values values;
00073 struct opd_event * event = find_counter_event(counter);
00074
00075 values.flags = 0;
00076
00077 if (sf->kernel) {
00078 values.image_name = sf->kernel->name;
00079 values.flags |= MANGLE_KERNEL;
00080 } else if (sf->anon) {
00081 values.flags |= MANGLE_ANON;
00082 values.image_name = mangle_anon(sf->anon);
00083 values.anon_name = sf->anon->name;
00084 } else {
00085 values.image_name = find_cookie(sf->cookie);
00086 }
00087
00088 values.dep_name = get_dep_name(sf);
00089 if (!values.dep_name)
00090 values.dep_name = values.image_name;
00091
00092
00093 if (!values.image_name || !values.dep_name)
00094 return NULL;
00095
00096 if (separate_thread) {
00097 values.flags |= MANGLE_TGID | MANGLE_TID;
00098 values.tid = sf->tid;
00099 values.tgid = sf->tgid;
00100 }
00101
00102 if (separate_cpu) {
00103 values.flags |= MANGLE_CPU;
00104 values.cpu = sf->cpu;
00105 }
00106
00107 if (cg) {
00108 values.flags |= MANGLE_CALLGRAPH;
00109 if (last->kernel) {
00110 values.cg_image_name = last->kernel->name;
00111 } else if (last->anon) {
00112 values.flags |= MANGLE_CG_ANON;
00113 values.cg_image_name = mangle_anon(last->anon);
00114 values.anon_name = last->anon->name;
00115 } else {
00116 values.cg_image_name = find_cookie(last->cookie);
00117 }
00118
00119
00120 if (!values.cg_image_name) {
00121 if (values.flags & MANGLE_ANON)
00122 free((char *)values.image_name);
00123 return NULL;
00124 }
00125 }
00126
00127 values.event_name = event->name;
00128 values.count = event->count;
00129 values.unit_mask = event->um;
00130
00131 mangled = op_mangle_filename(&values);
00132
00133 if (values.flags & MANGLE_ANON)
00134 free((char *)values.image_name);
00135 if (values.flags & MANGLE_CG_ANON)
00136 free((char *)values.cg_image_name);
00137 return mangled;
00138 }
00139
00140
00141 int opd_open_sample_file(odb_t *file, struct sfile *last,
00142 struct sfile * sf, int counter, int cg)
00143 {
00144 char * mangled;
00145 char const * binary;
00146 int spu_profile = 0;
00147 vma_t last_start = 0;
00148 int err;
00149
00150 mangled = mangle_filename(last, sf, counter, cg);
00151
00152 if (!mangled)
00153 return EINVAL;
00154
00155 verbprintf(vsfile, "Opening \"%s\"\n", mangled);
00156
00157 create_path(mangled);
00158
00159
00160 sfile_get(sf);
00161 if (sf != last)
00162 sfile_get(last);
00163
00164 retry:
00165 err = odb_open(file, mangled, ODB_RDWR, sizeof(struct opd_header));
00166
00167
00168 if (err) {
00169 if (err == EMFILE) {
00170 if (sfile_lru_clear()) {
00171 printf("LRU cleared but odb_open() fails for %s.\n", mangled);
00172 abort();
00173 }
00174 goto retry;
00175 }
00176
00177 fprintf(stderr, "oprofiled: open of %s failed: %s\n",
00178 mangled, strerror(err));
00179 goto out;
00180 }
00181
00182 if (!sf->kernel)
00183 binary = find_cookie(sf->cookie);
00184 else
00185 binary = sf->kernel->name;
00186
00187 if (last && last->anon)
00188 last_start = last->anon->start;
00189
00190 if (sf->embedded_offset != UNUSED_EMBEDDED_OFFSET)
00191 spu_profile = 1;
00192
00193 fill_header(odb_get_data(file), counter,
00194 sf->anon ? sf->anon->start : 0, last_start,
00195 !!sf->kernel, last ? !!last->kernel : 0,
00196 spu_profile, sf->embedded_offset,
00197 binary ? op_get_mtime(binary) : 0);
00198
00199 out:
00200 sfile_put(sf);
00201 if (sf != last)
00202 sfile_put(last);
00203 free(mangled);
00204 return err;
00205 }