|
From: <sv...@va...> - 2005-07-09 10:37:17
|
Author: sewardj
Date: 2005-07-09 11:36:25 +0100 (Sat, 09 Jul 2005)
New Revision: 4139
Log:
Another seemingly-small but critical change imported from 2.4.0-ppc:
don't read symbols from sections with w permissions. For some reason
ppc-linux maps executables three times, not twice as on x86, and if
the w flag is ignored, we wind up reading debug info twice, getting
wrong redirections, and then it all goes to hell in a handbasket.
Modified:
trunk/coregrind/m_aspacemgr/aspacemgr.c
Modified: trunk/coregrind/m_aspacemgr/aspacemgr.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/m_aspacemgr/aspacemgr.c 2005-07-08 18:28:40 UTC (rev =
4138)
+++ trunk/coregrind/m_aspacemgr/aspacemgr.c 2005-07-09 10:36:25 UTC (rev =
4139)
@@ -787,37 +787,58 @@
/* If this mapping is of the beginning of a file, isn't part of
Valgrind, is at least readable and seems to contain an object
file, then try reading symbols from it.
+
+ Getting this heuristic right is critical. On x86-linux,
+ objects are typically mapped twice:
+
+ 1b8fb000-1b8ff000 r-xp 00000000 08:02 4471477 vgpreload_memcheck.s=
o
+ 1b8ff000-1b900000 rw-p 00004000 08:02 4471477 vgpreload_memcheck.s=
o
+
+ whereas ppc32-linux mysteriously does this:
+
+ 118a6000-118ad000 r-xp 00000000 08:05 14209428 vgpreload_memcheck.=
so
+ 118ad000-118b6000 ---p 00007000 08:05 14209428 vgpreload_memcheck.=
so
+ 118b6000-118bd000 rwxp 00000000 08:05 14209428 vgpreload_memcheck.=
so
+
+ The third mapping should not be considered to have executable code=
in.
+ Therefore a test which works for both is: r and x and NOT w. Read=
ing
+ symbols from the rwx segment -- which overlaps the r-x segment in =
the
+ file -- causes the redirection mechanism to redirect to addresses =
in
+ that third segment, which is wrong and causes crashes.
*/
if (s->seginfo =3D=3D NULL
&& ( (addr+len < VG_(valgrind_base) || addr > VG_(valgrind_last))
|| is_stage2
)
&& (flags & (SF_MMAP|SF_NOSYMS)) =3D=3D SF_MMAP
- ) {
+ ) {
if (off =3D=3D 0
- && s->fnIdx !=3D -1
- && (prot & (VKI_PROT_READ|VKI_PROT_EXEC)) =3D=3D (VKI_PROT_READ|VKI_P=
ROT_EXEC)
- && len >=3D VKI_PAGE_SIZE
- && VG_(is_object_file)((void *)addr)
- ) {
+ && s->fnIdx !=3D -1
+ /* r, x are set */
+ && (prot & (VKI_PROT_READ|VKI_PROT_EXEC)) =3D=3D (VKI_PROT_READ=
|VKI_PROT_EXEC)
+ /* w is clear */
+ && (prot & VKI_PROT_WRITE) =3D=3D 0
+ /* other checks .. */
+ && len >=3D VKI_PAGE_SIZE
+ && VG_(is_object_file)((void *)addr) ) {
s->seginfo =3D VG_(read_seg_symbols)(s->addr, s->len, s->offset=
,
s->filename);
- } else if (flags & SF_MMAP) {
-#if 0
- const SegInfo *info;
-
- /* Otherwise see if an existing SegInfo applies to this Segment */
- for(info =3D VG_(next_seginfo)(NULL);
- info !=3D NULL;
- info =3D VG_(next_seginfo)(info)) {
- if (VG_(seg_overlaps)(s, VG_(seg_start)(info), VG_(seg_size)(info))=
)
- {
- s->seginfo =3D (SegInfo *)info;
- VG_(seginfo_incref)((SegInfo *)info);
- }
- }
-#endif
}
+ //else=20
+ //if (flags & SF_MMAP) {
+ // const SegInfo *info;
+ //
+ // /* Otherwise see if an existing SegInfo applies to this Segme=
nt */
+ // for(info =3D VG_(next_seginfo)(NULL);
+ // info !=3D NULL;
+ // info =3D VG_(next_seginfo)(info)) {
+ // if (VG_(seg_overlaps)(s, VG_(seg_start)(info), VG_(seg_siz=
e)(info)))
+ // {
+ // s->seginfo =3D (SegInfo *)info;
+ // VG_(seginfo_incref)((SegInfo *)info);
+ // }
+ // }
+ //}
}
=20
/* clean up */
|