|
From: Bart V. A. <bar...@gm...> - 2008-05-12 19:16:59
|
Hello, I would like to modify the Valgrind configure.in and Makefile.am files such that Valgrind can be cross-compiled. One issue I encountered was that VEX/auxprogs/genoffsets has to be executed while Valgrind is built. I have modified configure.in locally such that it not only detects the name of the cross-compiler, but also the path of the native compiler. I modified various makefiles such that VEX/auxprogs/genoffsets is built natively. I hope this is safe and that the output of the genoffsets program does not depend on the CPU it is run on, but only on the -m32/-m64 flags ? There is one other issue with regard to cross compiling, namely ar versus ranlib. autoconf only has support for detecting ranlib and not for detecting ar. Is it safe to replace all references to ar in Valgrind and VEX makefiles by references to ranlib ? Bart. |
|
From: Tom H. <to...@co...> - 2008-05-12 19:31:39
|
Bart Van Assche wrote: > I would like to modify the Valgrind configure.in and Makefile.am files > such that Valgrind can be cross-compiled. One issue I encountered was > that VEX/auxprogs/genoffsets has to be executed while Valgrind is > built. I have modified configure.in locally such that it not only > detects the name of the cross-compiler, but also the path of the > native compiler. I modified various makefiles such that > VEX/auxprogs/genoffsets is built natively. I hope this is safe and > that the output of the genoffsets program does not depend on the CPU > it is run on, but only on the -m32/-m64 flags ? I'm sure Julian will comment, but I think it needs to run on the target processor. > There is one other issue with regard to cross compiling, namely ar > versus ranlib. autoconf only has support for detecting ranlib and not > for detecting ar. Is it safe to replace all references to ar in > Valgrind and VEX makefiles by references to ranlib ? Certainly not - they do completely different things. On any vaguely modern system ranlib is not needed as ar does the necessary magic when updating the library. On really ancient systems you needed to run ranlib after building the archive with ar. Tom -- Tom Hughes (to...@co...) http://www.compton.nu/ |
|
From: Bart V. A. <bar...@gm...> - 2008-05-12 19:34:23
|
On Mon, May 12, 2008 at 9:31 PM, Tom Hughes <to...@co...> wrote: > On any vaguely modern system ranlib is not needed as ar does the necessary > magic when updating the library. On really ancient systems you needed to run > ranlib after building the archive with ar. What I see now is that when cross-compiling Valgrind, that the ar tool of the build system (e.g. x86_64) is ran on object files generated by the cross-compiler (e.g. ppc64). Is this safe ? Bart. |
|
From: Tom H. <to...@co...> - 2008-05-12 19:45:09
|
In message <e2e...@ma...>
"Bart Van Assche" <bar...@gm...> wrote:
> On Mon, May 12, 2008 at 9:31 PM, Tom Hughes <to...@co...> wrote:
> > On any vaguely modern system ranlib is not needed as ar does the necessary
> > magic when updating the library. On really ancient systems you needed to run
> > ranlib after building the archive with ar.
>
> What I see now is that when cross-compiling Valgrind, that the ar tool
> of the build system (e.g. x86_64) is ran on object files generated by
> the cross-compiler (e.g. ppc64). Is this safe ?
I doubt it in general terms.
BTW the point about ranlib is that ranlib generates the symbol table
for the archive, but modern ar does that anyway with the -s switch.
Tom
--
Tom Hughes (to...@co...)
http://www.compton.nu/
|
|
From: Florian K. <br...@ac...> - 2008-05-12 21:25:52
|
On Monday 12 May 2008 3:17:02 pm Bart Van Assche wrote: > Hello, > > I would like to modify the Valgrind configure.in and Makefile.am files > such that Valgrind can be cross-compiled. One issue I encountered was > that VEX/auxprogs/genoffsets has to be executed while Valgrind is > built. Yes, it would be nice if this step could be eliminated. > I have modified configure.in locally such that it not only > detects the name of the cross-compiler, but also the path of the > native compiler. I modified various makefiles such that > VEX/auxprogs/genoffsets is built natively. I hope this is safe and > that the output of the genoffsets program does not depend on the CPU > it is run on, but only on the -m32/-m64 flags ? > I can't answer that with a certainty but would guess it ought to be the compiler for the target. Assuming that the target compiler is needed, wouldn't it be possible to eliminate genoffsets altogether and distribute the definitions that it generates to the various libvex_guest_XYZZY.h files? E.g. libvex_guest_ppc64.h would include #define OFFSET_ppc64_GPR0 offsetof(VexGuestPPC64State,guest_GPR0) and so on and similarly for the other targets. There is only one guest state active for a given valgrind instance so we only need one set of these OFFSETs at a time. Or am I missing something ? Cheers, Florian |
|
From: Bart V. A. <bar...@gm...> - 2008-05-14 06:41:14
|
On Mon, May 12, 2008 at 11:25 PM, Florian Krohm <br...@ac...> wrote: > Assuming that the target compiler is needed, wouldn't it be possible > to eliminate genoffsets altogether and distribute the definitions that > it generates to the various libvex_guest_XYZZY.h files? > E.g. libvex_guest_ppc64.h would include > > #define OFFSET_ppc64_GPR0 offsetof(VexGuestPPC64State,guest_GPR0) > > and so on and similarly for the other targets. > There is only one guest state active for a given valgrind instance so > we only need one set of these OFFSETs at a time. > Or am I missing something ? Sounds like a good idea to me. And an offsetof() macro is already defined in VEX/pub/libvex_basictypes.h, so we don't have to #include any glibc header file for the definition of offsetof(). I'll implement these changes on a branch as soon as I have the time for it, such that the changes can be reviewed before they are merged to the trunk. Bart. |
|
From: Bart V. A. <bar...@gm...> - 2008-05-14 14:39:42
|
On Mon, May 12, 2008 at 11:25 PM, Florian Krohm <br...@ac...> wrote: > Assuming that the target compiler is needed, wouldn't it be possible > to eliminate genoffsets altogether and distribute the definitions that > it generates to the various libvex_guest_XYZZY.h files? > E.g. libvex_guest_ppc64.h would include > > #define OFFSET_ppc64_GPR0 offsetof(VexGuestPPC64State,guest_GPR0) > > and so on and similarly for the other targets. > There is only one guest state active for a given valgrind instance so > we only need one set of these OFFSETs at a time. > Or am I missing something ? Hello Florian, Are you aware that the file libvex_guest_offsets.h is also included from assembler files (.S) ? Bart. |
|
From: Florian K. <br...@ac...> - 2008-05-14 15:52:57
|
On Wednesday 14 May 2008 10:39:48 am Bart Van Assche wrote:
>
> Are you aware that the file libvex_guest_offsets.h is also included
> from assembler files (.S) ?
>
Hello Bart,
no, I missed that. Bummer. Thanks for pointing it out.
I think it's safe to assume that converting the assembler files into
.c files with inline assembly is not an option.
In that case we need these OFFSET.. macros to expand to integer
constants.
Here is one way I can think of. It's not ideal but perhaps acceptable.
Taking libvex_guest_ppc64.h as an example, we could add this at the
end of that header file:
#define OFFSET_ppc64_GPR0 0
#define OFFSET_ppc64_GPR2 16
#define OFFSET_ppc64_GPR3 24
... and so on ...
#if defined(VPA_ppc64)
#define check_guest_offsets() \
do { \
vassert(OFFSET_ppc64_GPR0 == offsetof(VexGuestPPC64State,guest_GPR0)); \
vassert(OFFSET_ppc64_GPR2 == offsetof(VexGuestPPC64State,guest_GPR2)); \
vassert(OFFSET_ppc64_GPR3 == offsetof(VexGuestPPC64State,guest_GPR3)); \
... and so on ...
} while (0)
#endif
When VEX is initialised in LibVEX_Init we could simply call this
"function" to make sure the offsets are properly defined.
I used a macro here, because using a proper function has two issues:
(1) GCC warnings about function being defined but not used
(2) vassert is private, but libvex_guest... is public, so it's not
accessible from that context
Another alternative would be to give LibVEX_Init an additional
parameter which is a function pointer to the checking function. But
I've not explored this further.
It is true, that check_guest_offsets has to be updated whenever the
guest state changes. But that doesn't really happen all that often
once the port to a given platform has been finished.
Cheers,
Florian
|
|
From: Bart V. A. <bar...@gm...> - 2008-05-14 17:52:09
|
On Wed, May 14, 2008 at 5:52 PM, Florian Krohm <br...@ac...> wrote: > On Wednesday 14 May 2008 10:39:48 am Bart Van Assche wrote: >> >> Are you aware that the file libvex_guest_offsets.h is also included >> from assembler files (.S) ? > > no, I missed that. Bummer. Thanks for pointing it out. Hello Florian, Can you have a look at the output of the following command: svn diff svn://svn.valgrind.org/valgrind/trunk \ svn://svn.valgrind.org/valgrind/branches/CROSS_COMPILATION I have to test the changes on the CROSS_COMPILATION branch further, but I believe that's all what's needed to make it possible to cross-compile Valgrind. Since I do not have the rights to create a VEX branch I have added the VEX changes as a file (vex-cross-compilation.patch). Bart. |
|
From: Florian K. <br...@ac...> - 2008-05-14 20:41:27
|
On Wednesday 14 May 2008 1:51:57 pm Bart Van Assche wrote: > > Can you have a look at the output of the following command: > svn diff svn://svn.valgrind.org/valgrind/trunk \ > svn://svn.valgrind.org/valgrind/branches/CROSS_COMPILATION It worked for me after adding #include <assert.h> to genoffset.c Without that it would not link for me. But, the more I think of it the more I get convinced that these OFFSETs need to be computed by the target compiler. Florian |
|
From: Bart V. A. <bar...@gm...> - 2008-05-15 18:21:17
|
On Wed, May 14, 2008 at 10:41 PM, Florian Krohm <br...@ac...> wrote: > On Wednesday 14 May 2008 1:51:57 pm Bart Van Assche wrote: >> >> Can you have a look at the output of the following command: >> svn diff svn://svn.valgrind.org/valgrind/trunk \ >> svn://svn.valgrind.org/valgrind/branches/CROSS_COMPILATION > > It worked for me after adding #include <assert.h> to genoffset.c > Without that it would not link for me. > > But, the more I think of it the more I get convinced that these > OFFSETs need to be computed by the target compiler. I agree. But I can't imagine any way to get offsetof() values out of a cross-compiler in a portable way (i.e. without relying on nm or libbfd). There is an alternative however: add the header file libvex_guest_offsets.h to VEX and let the cross-compiler verify consistency of the header file and the computed offsetof() values. I have implemented this as follows on the CROSS_COMPILATION branch: * Added the file VEX/pub/libvex_guest_offsets_in.h * Added the file VEX/auxprogs/verifyoffsets.c, which verify the offsets via the static_assert() macro. * Changed VEX/Makefile as follows: pub/libvex_guest_offsets.h: - $(CC) -Wall -g -o auxprogs/genoffsets auxprogs/genoffsets.c - ./auxprogs/genoffsets > pub/libvex_guest_offsets.h + $(CC) -Wall -g -c auxprogs/verifyoffsets.c \ + && cp pub/libvex_guest_offsets_in.h pub/libvex_guest_offsets.h What is your opinion about this ? Bart. |
|
From: Florian K. <br...@ac...> - 2008-05-16 13:39:27
|
On Thursday 15 May 2008 2:20:50 pm Bart Van Assche wrote: > On Wed, May 14, 2008 at 10:41 PM, Florian Krohm <br...@ac...> wrote: > > But, the more I think of it the more I get convinced that these > > OFFSETs need to be computed by the target compiler. > > I agree. But I can't imagine any way to get offsetof() values out of a > cross-compiler in a portable way (i.e. without relying on nm or > libbfd). Correct. > There is an alternative however: add the header file > libvex_guest_offsets.h to VEX and let the cross-compiler verify > consistency of the header file and the computed offsetof() values. > I have implemented this as follows on the CROSS_COMPILATION branch: > * Added the file VEX/pub/libvex_guest_offsets_in.h > * Added the file VEX/auxprogs/verifyoffsets.c, which verify the > offsets via the static_assert() macro. > * Changed VEX/Makefile as follows: > pub/libvex_guest_offsets.h: > - $(CC) -Wall -g -o auxprogs/genoffsets auxprogs/genoffsets.c > - ./auxprogs/genoffsets > pub/libvex_guest_offsets.h > + $(CC) -Wall -g -c auxprogs/verifyoffsets.c \ > + && cp pub/libvex_guest_offsets_in.h pub/libvex_guest_offsets.h > > What is your opinion about this ? > I'm not too crazy about libvex_guest_offsets.h, now that it is no longer generated. The reason is that I think that, conceptually, the definition of the guest state offsets for a particular architecture should be placed next to the definition on the guest state itself. As for verifying the offsets, it would be helpful if the checking code could be defined in proximity to the offset definitions. If it's in a different file, there is a chance that things get out of sync when a new offset definition is being added. You'd have to remember to add the code snippet that verifies the offset. I know, I wouldn't. It is true that static_assert would save some cycles during development as the failed assertion would cause the build to fail. On the other hand, the error message for a failed static_assert is a bit cryptic as compared to vassert. I'll work on a patch but probably won't get to it until sometime this weekend. Florian |
|
From: Paul M. <pa...@sa...> - 2008-05-17 05:57:08
|
Florian Krohm writes:
> On Thursday 15 May 2008 2:20:50 pm Bart Van Assche wrote:
> > On Wed, May 14, 2008 at 10:41 PM, Florian Krohm <br...@ac...> wrote:
> > > But, the more I think of it the more I get convinced that these
> > > OFFSETs need to be computed by the target compiler.
> >
> > I agree. But I can't imagine any way to get offsetof() values out of a
> > cross-compiler in a portable way (i.e. without relying on nm or
> > libbfd).
>
> Correct.
I missed Bart's message so I'll respond to this one.
It can be done if you're willing to require the use of gcc (or
compilers that implement gcc-style asm statements) when
cross-compiling.
Basically you use a macro like this:
#define DEFINE(sym, val) \
asm volatile("\n#define " #sym " %0\n" #val : : "i" (val))
then have a file that contains a string of DEFINE calls:
int x(void)
{
DEFINE(FOO, offsetof(struct bar, foo));
}
then compile to assembly, then grep the lines starting with "#define"
from the generated .s file.
Paul.
|
|
From: Bart V. A. <bar...@gm...> - 2008-05-18 09:36:06
|
On Sat, May 17, 2008 at 7:56 AM, Paul Mackerras <pa...@sa...> wrote:
> #define DEFINE(sym, val) \
> asm volatile("\n#define " #sym " %0\n" #val : : "i" (val))
Thanks -- this works great. This worked directly on ppc, but on x86 I
had to filter out a dollar sign in front of the offset.
Bart.
|
|
From: Florian K. <br...@ac...> - 2008-05-19 15:29:37
|
On Sunday 18 May 2008 5:36:12 am Bart Van Assche wrote:
> On Sat, May 17, 2008 at 7:56 AM, Paul Mackerras <pa...@sa...> wrote:
> > #define DEFINE(sym, val) \
> > asm volatile("\n#define " #sym " %0\n" #val : : "i" (val))
>
Clever !
> Thanks -- this works great. This worked directly on ppc, but on x86 I
> had to filter out a dollar sign in front of the offset.
>
Thanks for working that in. I just tried it and it works for me as well.
Florian
|