From 4b89341ebf587a8ef2e9349b54e7973f30bd757a Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Thu, 18 Nov 2004 10:01:47 +0000 Subject: [PATCH] Clear the NOCORE flag on any text mappings that the RTLD modifies due to 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 --- libexec/rtld-elf/map_object.c | 18 ++++++++++++------ libexec/rtld-elf/rtld.c | 18 ++++++++++++++++-- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/libexec/rtld-elf/map_object.c b/libexec/rtld-elf/map_object.c index e68abaf385..ba55a9ce44 100644 --- a/libexec/rtld-elf/map_object.c +++ b/libexec/rtld-elf/map_object.c @@ -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 @@ -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. */ diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index 54f15c648c..a59326f358 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -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", -- 2.41.0