exe_handlers->load_fn ( == VG_(load_ELF) )
[or load_MACHO].
- This does the mmap'ing and creates the associated NSegments.
+ This does the mmap'ing with VG_(am_do_mmap_NO_NOTIFY)
+ and creates the associated NSegments.
The NSegments may get merged, (see maybe_merge_nsegments)
so there could be more PT_LOADs than there are NSegments.
ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV, Int use_fd )
{
NSegment const * seg;
- Int rw_load_count;
+ Int expected_rw_load_count;
const HChar* filename;
Bool is_rx_map, is_rw_map, is_ro_map;
/* We're only interested in mappings of object files. */
# if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
- rw_load_count = 0;
+ expected_rw_load_count = 0;
- elf_ok = ML_(check_elf_and_get_rw_loads) ( actual_fd, filename, &rw_load_count );
+ elf_ok = ML_(check_elf_and_get_rw_loads) ( actual_fd, filename, &expected_rw_load_count, use_fd == -1 );
if (use_fd == -1) {
VG_(close)( actual_fd );
/* So, finally, are we in an accept state? */
vg_assert(!di->have_dinfo);
if (di->fsm.have_rx_map &&
- di->fsm.rw_map_count == rw_load_count) {
+ di->fsm.rw_map_count == expected_rw_load_count) {
/* Ok, so, finally, we found what we need, and we haven't
already read debuginfo for this object. So let's do so now.
Yee-ha! */
/* If we don't have an rx and rw mapping, go no further. */
if (debug)
VG_(dmsg)("di_notify_mmap-6: "
- "no dinfo loaded %s (no rx or no rw mapping)\n", filename);
+ "no dinfo loaded %s (no rx or rw mappings (%d) not reached expected count (%d))\n",
+ filename, di->fsm.rw_map_count, expected_rw_load_count);
return 0;
}
}
function. */
extern Bool ML_(read_elf_debug) ( DebugInfo* di );
-extern Bool ML_(check_elf_and_get_rw_loads) ( Int fd, const HChar* filename, Int * rw_load_count );
+extern Bool ML_(check_elf_and_get_rw_loads) ( Int fd, const HChar* filename,
+ Int * rw_load_count, Bool from_nsegments );
#endif /* ndef __PRIV_READELF_H */
/* NOTREACHED */
}
-Bool ML_(check_elf_and_get_rw_loads) ( Int fd, const HChar* filename, Int * rw_load_count )
+Bool ML_(check_elf_and_get_rw_loads) ( Int fd, const HChar* filename,
+ Int * rw_load_count, Bool from_nsegments )
{
Bool res, ok;
UWord i;
* Hold your horses
* Just because The ELF file contains 2 RW PT_LOAD segments
* doesn't mean that Valgrind will also make 2 calls to
- * VG_(di_notify_mmap): in some cases, the 2 NSegments will get
- * merged and VG_(di_notify_mmap) only gets called once.
- * How to detect that the segments will be merged ?
+ * VG_(di_notify_mmap): in some cases, the 2 NSegments will
+ * have been merged and VG_(di_notify_mmap) only gets called
+ * once.
+ * How to detect that the segments were be merged ?
* Logically, they will be merged if the first segment ends
* at the beginning of the second segment:
* Seg1 virtual address + Seg1 segment_size
* the 2 different segments loaded separately are both counted
* here, we use the non rounded up p_filesz.
* This is all a nightmare/hack. Something cleaner should be
- * done than trying to guess here if segments will or will not
- * be merged later depending on how the loader will load
- * with or without rounding up.
- * */
+ * done than other than reverse engineering whether this call
+ * results from merged nsegments or not. Particularly as
+ * the mmap'ing and nsegment merging is all under our control.
+ */
if (previous_rw_a_phdr.p_memsz > 0 &&
- ehdr_m.e_type == ET_EXEC &&
+ from_nsegments &&
previous_rw_a_phdr.p_vaddr + previous_rw_a_phdr.p_filesz
== a_phdr.p_vaddr)
{