extern void perf_swcounter_event(u32, u64, int, struct pt_regs *, u64);
 
-extern void perf_counter_mmap(unsigned long addr, unsigned long len,
-                             unsigned long pgoff, struct file *file);
+extern void __perf_counter_mmap(struct vm_area_struct *vma);
+
+static inline void perf_counter_mmap(struct vm_area_struct *vma)
+{
+       if (vma->vm_flags & VM_EXEC)
+               __perf_counter_mmap(vma);
+}
 
 extern void perf_counter_comm(struct task_struct *tsk);
 extern void perf_counter_fork(struct task_struct *tsk);
 perf_swcounter_event(u32 event, u64 nr, int nmi,
                     struct pt_regs *regs, u64 addr)                    { }
 
-static inline void
-perf_counter_mmap(unsigned long addr, unsigned long len,
-                 unsigned long pgoff, struct file *file)               { }
-
+static inline void perf_counter_mmap(struct vm_area_struct *vma)       { }
 static inline void perf_counter_comm(struct task_struct *tsk)          { }
 static inline void perf_counter_fork(struct task_struct *tsk)          { }
 static inline void perf_counter_init(void)                             { }
 
 }
 
 static void perf_output_copy(struct perf_output_handle *handle,
-                            void *buf, unsigned int len)
+                            const void *buf, unsigned int len)
 {
        unsigned int pages_mask;
        unsigned int offset;
  */
 
 struct perf_mmap_event {
-       struct file     *file;
-       char            *file_name;
-       int             file_size;
+       struct vm_area_struct   *vma;
+
+       const char              *file_name;
+       int                     file_size;
 
        struct {
                struct perf_event_header        header;
 {
        struct perf_cpu_context *cpuctx;
        struct perf_counter_context *ctx;
-       struct file *file = mmap_event->file;
+       struct vm_area_struct *vma = mmap_event->vma;
+       struct file *file = vma->vm_file;
        unsigned int size;
        char tmp[16];
        char *buf = NULL;
-       char *name;
+       const char *name;
 
        if (file) {
                buf = kzalloc(PATH_MAX, GFP_KERNEL);
                        goto got_name;
                }
        } else {
+               name = arch_vma_name(mmap_event->vma);
+               if (name)
+                       goto got_name;
+
+               if (!vma->vm_mm) {
+                       name = strncpy(tmp, "[vdso]", sizeof(tmp));
+                       goto got_name;
+               }
+
                name = strncpy(tmp, "//anon", sizeof(tmp));
                goto got_name;
        }
        kfree(buf);
 }
 
-void perf_counter_mmap(unsigned long addr, unsigned long len,
-                      unsigned long pgoff, struct file *file)
+void __perf_counter_mmap(struct vm_area_struct *vma)
 {
        struct perf_mmap_event mmap_event;
 
                return;
 
        mmap_event = (struct perf_mmap_event){
-               .file   = file,
+               .vma    = vma,
                .event  = {
                        .header = { .type = PERF_EVENT_MMAP, },
-                       .start  = addr,
-                       .len    = len,
-                       .pgoff  = pgoff,
+                       .start  = vma->vm_start,
+                       .len    = vma->vm_end - vma->vm_start,
+                       .pgoff  = vma->vm_pgoff,
                },
        };
 
 
        if (correct_wcount)
                atomic_inc(&inode->i_writecount);
 out:
-       if (vm_flags & VM_EXEC)
-               perf_counter_mmap(addr, len, pgoff, file);
+       perf_counter_mmap(vma);
 
        mm->total_vm += len >> PAGE_SHIFT;
        vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
 
        mm->total_vm += len >> PAGE_SHIFT;
 
+       perf_counter_mmap(vma);
+
        return 0;
 }