From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29893 invoked by alias); 9 Oct 2003 02:44:53 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 29881 invoked from network); 9 Oct 2003 02:44:52 -0000 Received: from unknown (HELO gateway.sf.frob.com) (64.81.54.130) by sources.redhat.com with SMTP; 9 Oct 2003 02:44:52 -0000 Received: from magilla.sf.frob.com (magilla.sf.frob.com [198.49.250.228]) by gateway.sf.frob.com (Postfix) with ESMTP id 51F40357B; Wed, 8 Oct 2003 19:44:51 -0700 (PDT) Received: from magilla.sf.frob.com (localhost.localdomain [127.0.0.1]) by magilla.sf.frob.com (8.12.9/8.12.9) with ESMTP id h992ioN2028921; Wed, 8 Oct 2003 19:44:50 -0700 Received: (from roland@localhost) by magilla.sf.frob.com (8.12.9/8.12.9/Submit) id h992io72028917; Wed, 8 Oct 2003 19:44:50 -0700 Date: Thu, 09 Oct 2003 02:44:00 -0000 Message-Id: <200310090244.h992io72028917@magilla.sf.frob.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit From: Roland McGrath To: Michael Snyder Cc: gdb-patches@sources.redhat.com Subject: Re: [PATCH] make gcore dump read-only sections not from files In-Reply-To: Michael Snyder's message of Wednesday, 8 October 2003 17:30:08 -0700 <3F84AC10.7080907@redhat.com> X-Zippy-Says: Did YOU find a DIGITAL WATCH in YOUR box of VELVEETA? X-SW-Source: 2003-10/txt/msg00289.txt.bz2 > I'll step up, since I wrote gcore. I like what you're doing, > but I'm uncertain about the SOLIB_ADD part. Like you, I don't > understand why it was the way it was, nor the implications of > the change. But I think this can be done fairly easily without > that change. Ok. I would sure like to know why core files work differently this way. It would be nice if there were any comments in the code, for example! The comment above update_solib_list says it's used for core files and attaching, which is true. But it says nothing about why. I don't understand why anything about this part of the solib handling would be different for core files than for running. > Does this (rewriting your main loop using ALL_OBJSECTIONS) > seem reasonable? Sure does. I didn't read enough code to understand exactly what objfile_find_memory_regions was doing and misread it as doing less. Along the way I noticed another difference between gcore-produced and kernel-produced core dumps. The omitted segments in real core dumps have nonzero p_memsz but zero p_filesz, which in phdrs indicates that the memory is occupied but the contents are not available. gcore's dumps zero the size, which gives a wrong indication of the address space. I changed that as well, so gcore's dumps now look more like real dumps. This works well enough. However, I think that making the determination based on the kernel-supplied indication of anonymous vs file-backed may make more sense. (Linux 2.6's behavior may be changing in this regard, and using that as a determining factor rather than just permission bits.) That would require changing the to_find_memory_regions interface as I described earlier. Can you comment on that? Thanks, Roland 2003-10-08 Roland McGrath * gcore.c (make_mem_sec): Function removed, folded into ... (gcore_create_callback): ... here. To omit a section, clear its SEC_LOAD bit rather than zeroing its size. Omit read-only sections only if they correspond to a known disk file. (gcore_copy_callback): Ignore sections without SEC_LOAD flag set. --- gcore.c.~1.12.~ 2003-09-23 03:01:26.000000000 -0700 +++ gcore.c 2003-10-08 19:39:11.000000000 -0700 @@ -306,55 +306,73 @@ make_output_phdrs (bfd *obfd, asection * bfd_record_phdr (obfd, p_type, 1, p_flags, 0, 0, 0, 0, 1, &osec); } -static asection * -make_mem_sec (bfd *obfd, bfd_vma addr, bfd_size_type size, - unsigned int flags, unsigned int alignment) +static int +gcore_create_callback (CORE_ADDR vaddr, unsigned long size, + int read, int write, int exec, void *data) { + bfd *obfd = data; asection *osec; + flagword flags = SEC_ALLOC | SEC_HAS_CONTENTS | SEC_LOAD; + + if (write == 0) + { + /* See if this region of memory lies inside a known file on disk. + If so, we can avoid copying its contents by clearing SEC_LOAD. */ + struct objfile *objfile; + struct obj_section *objsec; + + ALL_OBJSECTIONS (objfile, objsec) + { + bfd *abfd = objfile->obfd; + asection *asec = objsec->the_bfd_section; + bfd_vma align = (bfd_vma) 1 << bfd_get_section_alignment (abfd, + asec); + bfd_vma start = objsec->addr & -align; + bfd_vma end = (objsec->endaddr + align - 1) & -align; + /* Match if either the entire memory region lies inside the + section (i.e. a mapping covering some pages of a large + segment) or the entire section lies inside the memory region + (i.e. a mapping covering multiple small sections). + + This BFD was synthesized from reading target memory, + we don't want to omit that. */ + if (((vaddr >= start && vaddr + size <= end) + || (start >= vaddr && end <= vaddr + size)) + && !(bfd_get_file_flags (abfd) & BFD_IN_MEMORY)) + { + flags &= ~SEC_LOAD; + goto keep; /* break out of two nested for loops */ + } + } + + keep: + flags |= SEC_READONLY; + } + + if (exec) + flags |= SEC_CODE; + else + flags |= SEC_DATA; osec = bfd_make_section_anyway (obfd, "load"); if (osec == NULL) { warning ("Couldn't make gcore segment: %s", bfd_errmsg (bfd_get_error ())); - return NULL; + return 1; } if (info_verbose) { fprintf_filtered (gdb_stdout, "Save segment, %lld bytes at 0x%s\n", - (long long) size, paddr_nz (addr)); + (long long) size, paddr_nz (vaddr)); } bfd_set_section_size (obfd, osec, size); - bfd_set_section_vma (obfd, osec, addr); + bfd_set_section_vma (obfd, osec, vaddr); bfd_section_lma (obfd, osec) = 0; /* ??? bfd_set_section_lma? */ - bfd_set_section_alignment (obfd, osec, alignment); - bfd_set_section_flags (obfd, osec, - flags | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS); - return osec; -} - -static int -gcore_create_callback (CORE_ADDR vaddr, unsigned long size, - int read, int write, int exec, void *data) -{ - flagword flags = 0; - - if (write == 0) - { - flags |= SEC_READONLY; - /* Mark readonly sections as zero-sized, such that we can avoid - copying their contents. */ - size = 0; - } - - if (exec) - flags |= SEC_CODE; - else - flags |= SEC_DATA; - - return ((make_mem_sec (data, vaddr, size, flags, 0)) == NULL); + bfd_set_section_flags (obfd, osec, flags); + return 0; } static int @@ -416,9 +434,8 @@ gcore_copy_callback (bfd *obfd, asection struct cleanup *old_chain = NULL; void *memhunk; - /* Read-only sections are marked as zero-size. We don't have to - copy their contents. */ - if (size == 0) + /* Read-only sections are marked; we don't have to copy their contents. */ + if ((bfd_get_section_flags (obfd, osec) & SEC_LOAD) == 0) return; /* Only interested in "load" sections. */