From f8091e2c8f1e8c64bf58bec286caf99d7626d896 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Wed, 8 Jan 2020 16:57:08 +0000 Subject: [PATCH] linprocfs: Fix some bugs in the maps file implementation. - Export the offset into the backing object, not the object size. - Fix a bug where we would print the previous entry's "offset" when a map_entry has no object. - Try to identify shared mappings. Linux prints "s" when the mapping "may be shared". This attempt is not perfect, for example, we print "p" for anonymous memory that may be shared via minherit(INHERIT_SHARE). PR: 240992 Reviewed by: kib MFC after: 1 week MFC note: no OBJ_ANON in stable/12 Differential Revision: https://reviews.freebsd.org/D23062 --- sys/compat/linprocfs/linprocfs.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c index ab41a5a4d934..caa57f160a2a 100644 --- a/sys/compat/linprocfs/linprocfs.c +++ b/sys/compat/linprocfs/linprocfs.c @@ -1146,7 +1146,7 @@ linprocfs_doprocmaps(PFS_FILL_ARGS) vm_map_entry_t entry, tmp_entry; vm_object_t obj, tobj, lobj; vm_offset_t e_start, e_end; - vm_ooffset_t off = 0; + vm_ooffset_t off; vm_prot_t e_prot; unsigned int last_timestamp; char *name = "", *freename = NULL; @@ -1156,6 +1156,7 @@ linprocfs_doprocmaps(PFS_FILL_ARGS) int error; struct vnode *vp; struct vattr vat; + bool private; PROC_LOCK(p); error = p_candebug(td, p); @@ -1186,17 +1187,20 @@ linprocfs_doprocmaps(PFS_FILL_ARGS) e_start = entry->start; e_end = entry->end; obj = entry->object.vm_object; - for (lobj = tobj = obj; tobj; tobj = tobj->backing_object) { + off = entry->offset; + for (lobj = tobj = obj; tobj != NULL; + lobj = tobj, tobj = tobj->backing_object) { VM_OBJECT_RLOCK(tobj); + off += lobj->backing_object_offset; if (lobj != obj) VM_OBJECT_RUNLOCK(lobj); - lobj = tobj; } + private = (entry->eflags & MAP_ENTRY_COW) != 0 || obj == NULL || + (obj->flags & OBJ_ANON) != 0; last_timestamp = map->timestamp; vm_map_unlock_read(map); ino = 0; if (lobj) { - off = IDX_TO_OFF(lobj->size); vp = vm_object_vnode(lobj); if (vp != NULL) vref(vp); @@ -1233,7 +1237,7 @@ linprocfs_doprocmaps(PFS_FILL_ARGS) (e_prot & VM_PROT_READ)?"r":"-", (e_prot & VM_PROT_WRITE)?"w":"-", (e_prot & VM_PROT_EXECUTE)?"x":"-", - "p", + private ? "p" : "s", (u_long)off, 0, 0,