This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PR3609
On Thu, Aug 09, 2001 at 01:50:31PM -0400, Jakub Jelinek wrote:
> On Thu, Aug 09, 2001 at 10:24:28AM -0700, Mark Mitchell wrote:
> >
> > Franz --
> >
> > Here is a patch that disables the strlen over-optimization. I've
> > tested it in the usual ways, but I'd like to have you verify that it
> > fixes your kernel bug before I check it in. Would you let me know
> > ASAP?
>
> Actually, from what I see the call is optimized into
> memcpy(namep, "linux,phandle" + offset, sizeof("linux,phandle") - offset);
> (and not offset - sizeof("linux,phandle") as Franz wrote).
> And I don't see how this can be overoptimization, if offset is larger than
> the size of string, then it triggers undefined behaviour.
> E.g. with SHF_MERGE support in the linker, the linker can reorder the
> strings (and merge) any way it wants, so if some code relies on this, it
> will break anyway.
>
> Franz, can you point where exactly in the Linux kernel is such code?
It happens in the early boot process - when the kernel is not running
at the address it was linked for and knows it. Using C for some of
this is, of course, a bit hokey but very convenient. See
arch/ppc/kernel/prom.c:
/*
* prom_init() is called very early on, before the kernel text
* and data have been mapped to KERNELBASE. At this point the code
* is running at whatever address it has been loaded at, so
* references to extern and static variables must be relocated
* explicitly. The procedure reloc_offset() returns the address
* we're currently running at minus the address we were linked at.
* (Note that strings count as static variables.)
*
* Because OF may have mapped I/O devices into the area starting at
* KERNELBASE, particularly on CHRP machines, we can't safely call
* OF once the kernel has been mapped to KERNELBASE. Therefore all
* OF calls should be done within prom_init(), and prom_init()
* and all routines called within it must be careful to relocate
* references as necessary.
*/
#define PTRRELOC(x) ((typeof(x))((unsigned long)(x) + offset))
#define PTRUNRELOC(x) ((typeof(x))((unsigned long)(x) - offset))
#define RELOC(x) (*PTRRELOC(&(x)))
The offset is not really into the string, but moving the base of the
string - SHF_MERGE is irrelevant here. I can't think of a proper use
of volatile to express this concept - casting the address of the string
to a volatile unsigned long maybe?
--
Daniel Jacobowitz Carnegie Mellon University
MontaVista Software Debian GNU/Linux Developer