static int oprof_output_maps(struct task_struct * task) { int size=0; struct mm_struct * mm; struct vm_area_struct * map; /* we don't need to worry about mm_users here, since there is at least one user (current), and if there's other code using this mm, then mm_users must be at least 2; we should never have to mmput() here. */ if (!(mm = task->mm)) goto out; lock_mmap(mm); spin_lock(¬e_lock); /* We need two pass, daemon assume than the first mmap notification * is for the executable but some process doesn't follow this model. */ for (map = mm->mmap; map; map = map->vm_next) { if (!(map->vm_flags & VM_EXEC) || !map->vm_file) continue; if (!(map->vm_flags & VM_EXECUTABLE)) continue; oprof_output_map(map->vm_start, map->vm_end-map->vm_start, GET_VM_OFFSET(map), map->vm_file, 1); } for (map = mm->mmap; map; map = map->vm_next) { if (!(map->vm_flags & VM_EXEC) || !map->vm_file) continue; if (map->vm_flags & VM_EXECUTABLE) continue; oprof_output_map(map->vm_start, map->vm_end-map->vm_start, GET_VM_OFFSET(map), map->vm_file, 0); } spin_unlock(¬e_lock); unlock_mmap(mm); out: return size; }
int oprof_hash_map_mmap(struct file * file, struct vm_area_struct * vma) { ulong start = (ulong)vma->vm_start; ulong page, pos; ulong size = (ulong)(vma->vm_end-vma->vm_start); if (size > PAGE_ALIGN(OP_HASH_MAP_SIZE) || (vma->vm_flags & VM_WRITE) || GET_VM_OFFSET(vma)) return -EINVAL; pos = (ulong)hash_map; while (size > 0) { page = kvirt_to_pa(pos); if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) return -EAGAIN; start += PAGE_SIZE; pos += PAGE_SIZE; size -= PAGE_SIZE; } return 0; }