Jean-Michel,
Am 28.06.2024 um 19:24 schrieb Jean-Michel Hautbois:
I forgot to take into account that libraries are loaded only the
binary starts executing. Can you print the same map dump in the exit
syscall code path? That ought to show all loaded libraries at that point.
Thanks for your suggestion !
I changed it a bit, and I added a call in do_exit() as suggested. When
executing ls I get:
bash-5.2# ls -l
load_elf_binary: Dump memory for ls (31):
mmap: 60000000-6001e000 r-xp 00000000 00:00 178 /lib/ld.so.1
mmap: 6001e000-60022000 rw-p 0001c000 00:00 178 /lib/ld.so.1
mmap: 70000000-700c2000 r-xp 00000000 00:00 28 /bin/busybox
mmap: 700c2000-700ca000 rw-p 000c0000 00:00 28 /bin/busybox
mmap: bfc1e000-bfc40000 rw-p bffde000 00:00 0 [stack]
do_exit: Dump memory for ls (31):
mmap: 60000000-6001e000 r-xp 00000000 00:00 178 /lib/ld.so.1
mmap: 6001e000-60020000 r--p 0001c000 00:00 178 /lib/ld.so.1
mmap: 60020000-60022000 rw-p 0001e000 00:00 178 /lib/ld.so.1
mmap: 60022000-6002c000 r-xp 00000000 00:00 193 /lib/libresolv.so.2
mmap: 6002c000-6002e000 r--p 00008000 00:00 193 /lib/libresolv.so.2
mmap: 6002e000-60030000 rw-p 0000a000 00:00 193 /lib/libresolv.so.2
mmap: 60030000-60032000 rw-p 60030000 00:00 0
mmap: 60032000-6015a000 r-xp 00000000 00:00 185 /lib/libc.so.6
mmap: 6015a000-6015c000 r--p 00126000 00:00 185 /lib/libc.so.6
mmap: 6015c000-60160000 rw-p 00128000 00:00 185 /lib/libc.so.6
mmap: 60160000-6016e000 rw-p 60160000 00:00 0
mmap: 70000000-700c2000 r-xp 00000000 00:00 28 /bin/busybox
mmap: 700c2000-700c4000 r--p 000c0000 00:00 28 /bin/busybox
mmap: 700c4000-700ca000 rw-p 000c2000 00:00 28 /bin/busybox
mmap: 700ca000-700ec000 rwxp 700ca000 00:00 0 [heap]
mmap: bfc1e000-bfc40000 rw-p bffde000 00:00 0 [stack]
When I call it a second time, I get:
bash-5.2# ls -l
load_elf_binary: Dump memory for ls (33):
mmap: 60000000-6001e000 r-xp 00000000 00:00 178 /lib/ld.so.1
mmap: 6001e000-60022000 rw-p 0001c000 00:00 178 /lib/ld.so.1
mmap: 70000000-700c2000 r-xp 00000000 00:00 28 /bin/busybox
mmap: 700c2000-700ca000 rw-p 000c0000 00:00 28 /bin/busybox
mmap: bfb5a000-bfb7c000 rw-p bffde000 00:00 0 [stack]
do_exit: Dump memory for ls (33):
mmap: 60000000-6001e000 r-xp 00000000 00:00 178 /lib/ld.so.1
mmap: 6001e000-60020000 r--p 0001c000 00:00 178 /lib/ld.so.1
mmap: 60020000-60022000 rw-p 0001e000 00:00 178 /lib/ld.so.1
mmap: 60022000-6002c000 r-xp 00000000 00:00 193 /lib/libresolv.so.2
mmap: 6002c000-6002e000 r--p 00008000 00:00 193 /lib/libresolv.so.2
mmap: 6002e000-60030000 rw-p 0000a000 00:00 193 /lib/libresolv.so.2
mmap: 60030000-60032000 rw-p 60030000 00:00 0
mmap: 60032000-6015a000 r-xp 00000000 00:00 185 /lib/libc.so.6
mmap: 6015a000-6015c000 r--p 00126000 00:00 185 /lib/libc.so.6
mmap: 6015c000-60160000 rw-p 00128000 00:00 185 /lib/libc.so.6
mmap: 60160000-6016e000 rw-p 60160000 00:00 0
mmap: 70000000-700c2000 r-xp 00000000 00:00 28 /bin/busybox
mmap: 700c2000-700c4000 r--p 000c0000 00:00 28 /bin/busybox
mmap: 700c4000-700ca000 rw-p 000c2000 00:00 28 /bin/busybox
No heap in this second call. Can you print mm->start_brk and mm->brk please?
The process memory layout is a little unusual (I would have expected the
binary to be mapped before the dynamic libraries, not after). Is that
expected on Coldfire, Greg?
Cheers,
Michael
mmap: bfb5a000-bfb7c000 rw-p bffde000 00:00 0 [stack]
The first call generates the "ls" output, not the second one.
The helper looks like:
diff --git a/mm/mmap.c b/mm/mmap.c
index 83b4682ec85c..14d861e9cba2 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -76,6 +76,87 @@ int mmap_rnd_compat_bits __read_mostly =
CONFIG_ARCH_MMAP_RND_COMPAT_BITS;
static bool ignore_rlimit_data;
core_param(ignore_rlimit_data, ignore_rlimit_data, bool, 0644);
+int dump_memory_map(struct task_struct *task)
+{
+ struct mm_struct *mm = task->mm;
+ struct vm_area_struct *vma;
+ struct file *file;
+ struct path *path;
+ char *buf;
+ char *pathname;
+
+ if (!mm) {
+ return -ENOMEM;
+ }
+
+ MA_STATE(mas, &mm->mm_mt, 0, -1);
+ // Acquire the read lock for mmap_lock
+ down_read(&mm->mmap_lock);
+ mas_lock(&mas);
+ for (vma = mas_find(&mas, ULONG_MAX); vma; vma = mas_find(&mas,
ULONG_MAX)) {
+ char perms[5] = "---p"; // Default permissions
+ // Set permissions based on vm_flags
+ if (vma->vm_flags & VM_READ) perms[0] = 'r';
+ if (vma->vm_flags & VM_WRITE) perms[1] = 'w';
+ if (vma->vm_flags & VM_EXEC) perms[2] = 'x';
+ if (vma->vm_flags & VM_MAYSHARE) perms[3] = 's';
+
+ if (vma->vm_file) { // If there's an associated file
+ buf = (char *)__get_free_page(GFP_KERNEL);
+ if (!buf) {
+ continue; // Handle memory allocation
failure
+ }
+
+ file = vma->vm_file;
+ path = &file->f_path;
+ pathname = d_path(path, buf, PAGE_SIZE);
+ if (IS_ERR(pathname)) {
+ pathname = NULL;
+ }
+
+ // Print memory area information with file path
+ pr_info("%08lx-%08lx %s %08lx %02x:%02x %lu %s\n",
+ vma->vm_start, vma->vm_end,
+ perms,
+ vma->vm_pgoff << PAGE_SHIFT,
+ MAJOR(file_inode(file)->i_rdev),
+ MINOR(file_inode(file)->i_rdev),
+ file_inode(file)->i_ino,
+ pathname ? pathname : "");
+
+ free_page((unsigned long)buf);
+ } else {
+ char *special_area_name = NULL;
+
+ // Check for heap
+ if (vma->vm_end > mm->start_brk && vma->vm_start
< mm->brk) {
+ special_area_name = "[heap]";
+ }
+ // Check for stack
+ else if (vma->vm_start <= mm->start_stack &&
vma->vm_end >= mm->start_stack) {
+ special_area_name = "[stack]";
+ }
+ // Check for vdso
+ else if (vma->vm_flags & VM_EXEC &&
vma->vm_flags & VM_READ && !vma->vm_file) {
+ special_area_name = "[vdso]";
+ }
+
+ // Print memory area information without file path
+ pr_info("%08lx-%08lx %s %08lx 00:00 0 %s\n",
+ vma->vm_start, vma->vm_end,
+ perms,
+ vma->vm_pgoff << PAGE_SHIFT,
+ special_area_name ? special_area_name :
" ");
+ }
+ }
+ mas_unlock(&mas);
+ // Release the read lock for mmap_lock
+ up_read(&mm->mmap_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(dump_memory_map);
Thanks,
JM