Tuesday, July 22, 2008

Cross-compiling Valgrind

Valgrind is available for other architectures other than the i386/PC. Unfortunately it is not ported to the ARM processor family, but it still can be useful for the PPC targets I use.

First, I download the latest version of valgrind (today is 3.3.1).

Before configuring, a word of advice: the prefix option does not work as usual. The absolute prefix path gets hardwired in the valgrind code so that valgrind is able to find other tools such as memcheck, etc. So, the prefix path must be used with the target distribution in mind. As I plan to install valgrind on a network directory and mount it via NFS from the target unit, I will set 'prefix' to
the name of the mountpoint.

The reason for not installing valgrind on the target is because the size of the file is quite big (more than 50MB) as valgrind requires that his own binary files are not stripped. This is explained in the README_PACKAGERS file.

Apart from setting the usual CC variable:
/configure --host=ppc-linux --prefix=/ppc/tools/valgrind --disable-tls
make
make install

TLS is not provided by my kernel version, so it is disabled here.

At this point, valgrind runs but it reports an error that it is unable to do some binary code substitutions (i.e. the strlen function). It suggests that the linker may be stripped /lib/ld-·so, which is true.

Having the unstripped version of 'ld' requires compiling the entire glibc RPM. For my platform, the glibc is installed as an RPM. Then, I download and install the source RPM.

The binary files get automatically stripped by rpmbuild at the end of the %install stage. The "__os_install_post" macro contains the script that must be run at that point. This scriptlet calls the brp-strip-shared script, which lives under /opt/eldk/usr/lib/rpm, and strips all the shared libraries found in the installation directory. Unfortunately, my installation of ppc-rpm does not allow this scriptlet to be edited, so the only option is to add a condition at the top of the brp-strip-shared scripts so that if the DONT_STRIP_SHARED variable is set, then exit the script immediately. The spec file must be edited so that this variable is defined.

Then, I modify the glibc.spec file where, at the end of the %install section, there is a piece of code that strips all shared libraries but the 'libpthread' library. I just add the 'ld' library as an exception to the strip process, and then I rebuild the RPM.

export PATH=/opt/eldk/usr/ppc-linux/bin/:$PATH
ppc-rpmbuild -ba glibc.spec

Do not forget to increase or change the version of the RPM so that it is installed in the target successfully.

A simpler workaround is to copy the ld-x.y.z.so file manually, in this case, use 'cp -f' as the file is always in use.

2 comments:

robert.berger said...

Hi,

I'm trying to get valgrind to run on a PPC with ELDK 4.2 and I'm wondering which rpm you used to build ld.so unstripped.

It would be nice to rebuild just the ld without rebuilding the whole ELDK form scratch.

Regards,

Robert

--
Robert Berger
Embedded Software Specialist

Reliable Embedded Systems
Consulting Training Engineering
Tel.: (+30) 697 593 3428
Fax.:(+30) 210 684 7881
email: robert.berger@reliableembeddedsystems.com
URL: http://www.reliableembeddedsystems.com

Tom said...

Robert,

It looks like this might be the SRPM? I have had trouble too finding it, usually I only end up with SRPMs for glib/glib2 and can't find glibc.

http://source.denx.net/git/eldk/tarballs/glibc-2.6-4.src.rpm

I just found this, and am about to try it. YMMV.