Vin Shelton <acs(a)xemacs.org> writes:
Steve Youngs <steve(a)sxemacs.org> writes:
> Sorry, haven't checked 21.5, but I'd imagine this is needed there
> too.
>
> 21.4 patch:
> ChangeLog files diff command: cvs -q diff -U 0
> Files affected: src/ChangeLog
> Source files diff command: cvs -q diff -uN
> Files affected: src/emacs.c
>
> Index: src/ChangeLog
> ===================================================================
> RCS file: /pack/xemacscvs/XEmacs/xemacs/src/ChangeLog,v
> retrieving revision 1.290.2.83
> diff -u -U0 -r1.290.2.83 ChangeLog
> --- src/ChangeLog 11 Jan 2005 02:02:11 -0000 1.290.2.83
> +++ src/ChangeLog 12 Jan 2005 01:11:36 -0000
> @@ -0,0 +1,7 @@
> +2005-01-12 Steve Youngs <steve(a)sxemacs.org>
> +
> + From Evgeny Zajcev <lg(a)sxemacs.org>:
> +
> + * emacs.c (debug_can_access_memory): Fix problem of "clever"
> + compilers being over-zealous in their optimising.
> +
> Index: src/emacs.c
> ===================================================================
> RCS file: /pack/xemacscvs/XEmacs/xemacs/src/emacs.c,v
> retrieving revision 1.97.2.8
> diff -u -u -r1.97.2.8 emacs.c
> --- src/emacs.c 13 Jun 2004 20:19:39 -0000 1.97.2.8
> +++ src/emacs.c 12 Jan 2005 01:10:26 -0000
> @@ -535,15 +535,13 @@
> old_sigsegv =
> (SIGTYPE (*) (int)) signal (SIGSEGV, debug_memory_error);
>
> - if (len > 1)
> - /* If we can, try to avoid problems with super-optimizing compilers
> - that might decide that memcmp (ptr, ptr, len) can be optimized
> - away since its result is always 1. */
> - memcmp (ptr, (char *) ptr + 1, len - 1);
> - else
> - memcmp (ptr, ptr, len);
> - }
> - else
> + /* Examine memory pool at PTR */
> + while (len-- > 0) {
> + char a = ((char*)ptr)[len];
> + if (a == '1')
> + /* pass */;
> + }
> + } else
> retval = 0;
> signal (SIGBUS, old_sigbus);
> signal (SIGSEGV, old_sigsegv);
>
Do you have a test case?
Consider two functions:
---- file m.c ----
void
cptr1(void *ptr, unsigned int len)
{
if (len > 1)
/* If we can, try to avoid problems with super-optimizing compilers
that might decide that memcmp (ptr, ptr, len) can be optimized
away since its result is always 1. */
memcmp (ptr, (char *) ptr + 1, len - 1);
else
memcmp (ptr, ptr, len);
}
void
cptr2(void *ptr, unsigned int len)
{
while (len-- > 0) {
char a = ((char*)ptr)[len];
if (a == '1')
/* pass */;
}
}
---- end of m.c ----
compile it with gcc 3.4.2 for example
$ gcc -c m.c
$ objdump -D m.o
...
00000000 <cptr1>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: c9 leave
4: c3 ret
5: 8d 76 00 lea 0x0(%esi),%esi
00000008 <cptr2>:
8: 55 push %ebp
9: 89 e5 mov %esp,%ebp
b: 83 ec 04 sub $0x4,%esp
e: 8d 45 0c lea 0xc(%ebp),%eax
11: ff 08 decl (%eax)
13: 83 7d 0c ff cmpl $0xffffffff,0xc(%ebp)
17: 74 0d je 26 <cptr2+0x1e>
19: 8b 45 0c mov 0xc(%ebp),%eax
1c: 03 45 08 add 0x8(%ebp),%eax
1f: 8a 00 mov (%eax),%al
21: 88 45 ff mov %al,0xffffffff(%ebp)
24: eb e8 jmp e <cptr2+0x6>
26: c9 leave
27: c3 ret
...
As you can see function CPTR1 just does nothing, even without
optimisation flags, gcc optimized this function to just return. So no
actual reading accessity checking performed. CPTR2 does not have such
problem.
Thanks!
--
lg