Subject: re: mips gcc4 ld.elf_so problems
To: Jason Thorpe <thorpej@shagadelic.org>
From: matthew green <mrg@eterna.com.au>
List: tech-toolchain
Date: 06/28/2006 05:06:44
   > I think if you do this:
   >
   > static inline void
   > store_ptr(void *where, Elf_Addr val)
   > {
   > 	void *from = &val;
   
   Oops, make that:
   
   	const void *from = &val;
   
   :-)
   
   >
   > 	memcpy(where, from, sizeof(val));
   > }
   >
   > that it will work.  And that is a lot less invasive than your  
   > proposed change.


unfortunately, as i suspectd, this doesn't work.  the problem
isn't the load -- which is what you may be affecting there, but
the store to where.  and you haven't changed what GCC knows
about where at all.  you can reduce this to a simple test case:

	typedef long Elf_Addr;
	typedef unsigned int size_t;

	void *memcpy(void *, const void *, size_t);

	static inline void store_ptr(void *where, Elf_Addr val)
	{
		memcpy(where, &val, sizeof(val));
	}

	void bar(void *p, Elf_Addr val)
	{
		void *vwhere;
		Elf_Addr foo;

		vwhere = p + sizeof(size_t);
		store_ptr(vwhere, val);
	}

	void bar_novoid(Elf_Addr *p, Elf_Addr val)
	{
		Elf_Addr *where, foo;

		where = p + sizeof(size_t);
		store_ptr(where, val);
	}

	void bar_void_novoid(void *p, Elf_Addr val)
	{
		void *vwhere;
		Elf_Addr *where, foo;

		vwhere = p + sizeof(size_t);
		where = (Elf_Addr *)where;
		store_ptr(where, val);
	}


which compiles to use "sw" in both the novoid cases and swl/swr in
the other case.  ie, when GCC starts off with what it believes
should be an aligned pointer ("Elf_Addr *p"), or ends up with one
via an assignment, it will keep that information right into builtins
like this and optimise based on it.


i'm pretty sure simon's patch, while intrusive, is pretty much
the right thing.


.mrg.