Clear the NOCORE flag on any text mappings that the RTLD modifies due to
authorMatthew Dillon <dillon@dragonflybsd.org>
Thu, 18 Nov 2004 10:01:47 +0000 (10:01 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Thu, 18 Nov 2004 10:01:47 +0000 (10:01 +0000)
text relocations or compacted BSS areas.  Otherwise the checkpt code will
not write out the modified areas.

Also note that if you mmap() a file MAP_PRIVATE, then modify portions of it
so the mapping is changed from OBJT_VNODE to OBJT_DEFAULT->OBJT_VNODE,
the current ELF coredump code will *NOT* write out a file handle record for
the backing vnode.  This means that the entire vm_map_entry containing
the modified portions must be marked as COREable if it was previously mapped
NOCORE.

In the case of the RTLD code the text area is mapped read-only.  The text
area is temporarily remapped read-write for the relocation pass and so
the whole area is still represented by a single vm_map_entry and thus the
whole area must be marked COREable.  For the BSS fixup only the last page
is remapped read-write and so it gets its own private vm_map_entry and
thus only the last page must be marked COREable.

The DEFAULT->VNODE backing issue is actually a bug in the elf coredump code,
but even if it were fixed core dump sizes would not get much smaller because
relocations tend to be all over the map.

Checkpt-Nonworking-Bug-Reported-by: Michael Neumann <mneumann@ntecs.de>
libexec/rtld-elf/map_object.c
libexec/rtld-elf/rtld.c

index e68abaf..ba55a9c 100644 (file)
@@ -23,7 +23,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/libexec/rtld-elf/map_object.c,v 1.7.2.2 2002/12/28 19:49:41 dillon Exp $
- * $DragonFly: src/libexec/rtld-elf/map_object.c,v 1.3 2003/09/18 21:22:56 dillon Exp $
+ * $DragonFly: src/libexec/rtld-elf/map_object.c,v 1.4 2004/11/18 10:01:47 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -180,18 +180,24 @@ map_object(int fd, const char *path, const struct stat *sb)
        clear_page = mapbase + (trunc_page(clear_vaddr) - base_vaddr);
        if ((nclear = data_vlimit - clear_vaddr) > 0) {
            /* Make sure the end of the segment is writable */
-           if ((data_prot & PROT_WRITE) == 0 &&
-               -1 ==  mprotect(clear_page, PAGE_SIZE, data_prot|PROT_WRITE)) {
+           if ((data_prot & PROT_WRITE) == 0) {
+               if (mprotect(clear_page, PAGE_SIZE, data_prot|PROT_WRITE) < 0) {
                        _rtld_error("%s: mprotect failed: %s", path,
                            strerror(errno));
                        return NULL;
+               }
            }
 
            memset(clear_addr, 0, nclear);
 
-           /* Reset the data protection back */
-           if ((data_prot & PROT_WRITE) == 0)
-                mprotect(clear_page, PAGE_SIZE, data_prot);
+           /*
+            * reset the data protection back, enable the segment to be
+            * coredumped since we modified it.
+            */
+           if ((data_prot & PROT_WRITE) == 0) {
+               madvise(clear_page, PAGE_SIZE, MADV_CORE);
+               mprotect(clear_page, PAGE_SIZE, data_prot);
+           }
        }
 
        /* Overlay the BSS segment onto the proper region. */
index 54f15c6..a59326f 100644 (file)
@@ -24,7 +24,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/libexec/rtld-elf/rtld.c,v 1.43.2.15 2003/02/20 20:42:46 kan Exp $
- * $DragonFly: src/libexec/rtld-elf/rtld.c,v 1.7 2004/01/20 21:32:46 dillon Exp $
+ * $DragonFly: src/libexec/rtld-elf/rtld.c,v 1.8 2004/11/18 10:01:47 dillon Exp $
  */
 
 /*
@@ -1438,7 +1438,21 @@ relocate_objects(Obj_Entry *first, bool bind_now)
        if (reloc_non_plt(obj, &obj_rtld))
                return -1;
 
-       if (obj->textrel) {     /* Re-protected the text segment. */
+       /*
+        * Reprotect the text segment.  Make sure it is included in the
+        * core dump since we modified it.  This unfortunately causes the
+        * entire text segment to core-out but we don't have much of a
+        * choice.  We could try to only reenable core dumps on pages
+        * in which relocations occured but that is likely most of the text
+        * pages anyway, and even that would not work because the rest of
+        * the text pages would wind up as a read-only OBJT_DEFAULT object
+        * (created due to our modifications) backed by the original OBJT_VNODE
+        * object, and the ELF coredump code is currently only able to dump
+        * vnode records for pure vnode-backed mappings, not vnode backings
+        * to memory objects.
+        */
+       if (obj->textrel) {
+           madvise(obj->mapbase, obj->textsize, MADV_CORE);
            if (mprotect(obj->mapbase, obj->textsize,
              PROT_READ|PROT_EXEC) == -1) {
                _rtld_error("%s: Cannot write-protect text segment: %s",