opd_mapping.c

Go to the documentation of this file.
00001 
00012 #include "opd_mapping.h"
00013 #include "opd_proc.h"
00014 #include "opd_image.h"
00015 #include "opd_printf.h"
00016 
00017 #include "op_interface.h"
00018 #include "op_config_24.h"
00019 #include "op_libiberty.h"
00020 
00021 #include <sys/mman.h>
00022 #include <limits.h>
00023 #include <stdlib.h>
00024 #include <stdio.h>
00025 #include <string.h>
00026 
00027 /* hash map device mmap */
00028 static struct op_hash_index * hashmap;
00029 /* already seen mapping name */
00030 static char const * hash_name[OP_HASH_MAP_NR];
00031 
00032 
00033 void opd_cleanup_hash_name(void)
00034 {
00035     int i;
00036     for (i = 0; i < OP_HASH_MAP_NR; ++i)
00037         free((char *)hash_name[i]);
00038     
00039 }
00040 
00041 
00042 void opd_init_hash_map(void)
00043 {
00044     extern fd_t hashmapdevfd;
00045 
00046     hashmap = mmap(0, OP_HASH_MAP_SIZE, PROT_READ, MAP_SHARED, hashmapdevfd, 0);
00047     if ((long)hashmap == -1) {
00048         perror("oprofiled: couldn't mmap hash map");
00049         exit(EXIT_FAILURE);
00050     }
00051 
00052 }
00053 
00054 
00055 void opd_kill_maps(struct opd_proc * proc)
00056 {
00057     struct list_head * pos, * pos2;
00058 
00059     list_for_each_safe(pos, pos2, &proc->maps) {
00060         struct opd_map * map = list_entry(pos, struct opd_map, next);
00061         list_del(pos);
00062         opd_delete_image(map->image);
00063         free(map);
00064     }
00065 }
00066 
00067 
00068 void opd_add_mapping(struct opd_proc * proc, struct opd_image * image,
00069         unsigned long start, unsigned long offset, unsigned long end)
00070 {
00071     struct opd_map * map;
00072 
00073     verbprintf(vmisc, "Adding mapping for process %d: 0x%.8lx-0x%.8lx, off 0x%.8lx, \"%s\"\n",
00074         proc->tid, start, end, offset, image->name);
00075 
00076     map = malloc(sizeof(struct opd_map));
00077 
00078     /* first map is the primary image */
00079     if (list_empty(&proc->maps)) {
00080         if (proc->name)
00081             free((char *)proc->name);
00082         proc->name = xstrdup(image->name);
00083     }
00084 
00085     image->ref_count++;
00086 
00087     map->image = image;
00088     map->start = start;
00089     map->offset = offset;
00090     map->end = end;
00091     list_add_tail(&map->next, &proc->maps);
00092 }
00093 
00094 
00099 inline static char * get_from_pool(uint ind)
00100 {
00101     return ((char *)(hashmap + OP_HASH_MAP_NR) + ind);
00102 }
00103 
00104 
00109 static char const * opd_get_hash_name(int hash)
00110 {
00111     char file[PATH_MAX];
00112     char * c = &file[PATH_MAX-1];
00113     int orighash = hash;
00114 
00115     if (hash_name[hash])
00116         return hash_name[hash];
00117 
00118     *c = '\0';
00119     while (hash) {
00120         char * name = get_from_pool(hashmap[hash].name);
00121 
00122         if (strlen(name) + 1 + strlen(c) >= PATH_MAX) {
00123             fprintf(stderr, "String \"%s\" too large.\n", c);
00124             exit(EXIT_FAILURE);
00125         }
00126 
00127         c -= strlen(name) + 1;
00128         *c = '/';
00129         strncpy(c + 1, name, strlen(name));
00130 
00131         /* move onto parent */
00132         hash = hashmap[hash].parent;
00133     }
00134 
00135     return hash_name[orighash] = xstrdup(c);
00136 }
00137 
00138 
00139 void opd_handle_mapping(struct op_note const * note)
00140 {
00141     struct opd_proc * proc;
00142     struct opd_image * image;
00143     int hash;
00144     char const * name;
00145 
00146     proc = opd_get_proc(note->pid, note->tgid);
00147 
00148     if (!proc) {
00149         verbprintf(vmisc, "Told about mapping for non-existent process %u.\n", note->pid);
00150         proc = opd_new_proc(note->pid, note->tgid);
00151     }
00152 
00153     hash = note->hash;
00154 
00155     if (hash == -1) {
00156         /* possibly deleted file */
00157         return;
00158     }
00159 
00160     if (hash < 0 || hash >= OP_HASH_MAP_NR) {
00161         fprintf(stderr, "hash value %u out of range.\n", hash);
00162         return;
00163     }
00164 
00165     name = opd_get_hash_name(hash);
00166     image = opd_get_image(name, proc->name, 0, note->pid, note->tgid);
00167 
00168     opd_add_mapping(proc, image, note->addr, note->offset,
00169                     note->addr + note->len);
00170 }

Generated on 8 Nov 2012 for Oprofile by  doxygen 1.6.1