diff --git a/coregrind/m_aspacemgr/Makefile.am b/coregrind/m_aspacemgr/Makefile.am index c9ea0cc80..c2685f591 100644 --- a/coregrind/m_aspacemgr/Makefile.am +++ b/coregrind/m_aspacemgr/Makefile.am @@ -1,6 +1,8 @@ include $(top_srcdir)/Makefile.all.am include $(top_srcdir)/Makefile.core-AM_CPPFLAGS.am +EXTRA_DIST = README_SEGMENTS + noinst_LIBRARIES = libaspacemgr.a libaspacemgr_a_SOURCES = \ diff --git a/coregrind/m_aspacemgr/README_SEGMENTS b/coregrind/m_aspacemgr/README_SEGMENTS new file mode 100644 index 000000000..23513af1d --- /dev/null +++ b/coregrind/m_aspacemgr/README_SEGMENTS @@ -0,0 +1,59 @@ + +----------------------------------------------------------------------------- +Info about the relationship between Segments and SegInfos +----------------------------------------------------------------------------- + +SegInfo is from the very original Valgrind code, and so it predates +Segments. It's poorly named now; its really just a container for all +the object file metadata (symbols, debug info, etc). + +Segments describe memory mapped into the address space, and so any +address-space chaging operation needs to update the Segment structure. +After the process is initalized, this means one of: + + * mmap + * munmap + * mprotect + * brk + * stack growth + +A piece of address space may or may not be mmaped from a file. + +A SegInfo specifically describes memory mmaped from an ELF object file. +Because a single ELF file may be mmaped with multiple Segments, multiple +Segments can point to one Seginfo. A SegInfo can relate to a memory +range which is not yet mmaped. For example, if the process mmaps the +first page of an ELF file (the one containing the header), a SegInfo +will be created for that ELF file's mappings, which will include memory +which will be later mmaped by the client's ELF loader. If a new mmap +appears in the address range of an existing SegInfo, it will have that +SegInfo attached to it, presumably because its part of a .so file. +Similarly, if a Segment gets split (by mprotect, for example), the two +pieces will still be associated with the same SegInfo. For this reason, +the address/length info in a SegInfo is not a duplicate of the Segment +address/length. + +This is complex for several reasons: + + 1. We assume that if a process is mmaping a file which contains an + ELF header, it intends to use it as an ELF object. If a program + which just mmaps ELF files but just uses it as raw data (copy, for + example), we still treat it as a shared-library opening. + 2. Even if it is being loaded as a shared library/other ELF object, + Valgrind doesn't control the mmaps. It just observes the mmaps + being generated by the client and has to cope. One of the reasons + that Valgrind has to make its own mmap of each .so for reading + symtab information is because the client won't necessary mmap the + right pieces, or do so in the wrong order for us. + +SegInfos are reference counted, and freed when no Segments point to them any +more. + +> Aha. So the range of a SegInfo will always be equal to or greater +> than the range of its parent Segment? Or can you eg. mmap a whole +> file plus some extra pages, and then the SegInfo won't cover the extra +> part of the range? + +That would be unusual, but possible. You could imagine ld generating an +ELF file via a mapping this way (which would probably upset Valgrind no +end).