|
From: Stephen M.
|
SMcC> Another set of fixed-length structures that currently hold a SMcC> copy of the shadow information is the sigframes. Since these are SMcC> allocated specially, it wasn't immediately clear to me whether SMcC> it would be safe to add a level of indirection to them. >>>>> "NJN" == Nicholas Nethercote <nj...@cs...> writes: NJN> I don't know about them... Probably the easiest thing to do is just to try it and see if anything breaks. There are two things that seem like they could be potential problems: first, if sigframe_destroy() doesn't get called, the allocated space would leak, but it doesn't look like the sort of thing that could get bypassed. Second, in user programs you might worry about calling a non-reentrant malloc() from a signal that was delivered while malloc() was running, but I'd presume Valgrind serializes things so that that wouldn't be a problem. SMcC> I'm not sure now whether the better default for the multiplier SMcC> would be 0 or 1. Most tools don't seem to use shadow registers, SMcC> so 0 would save space for them, but 1 would be more SMcC> backwards-compatible. NJN> Don't worry about backwards compatibility, since you'll probably NJN> be breaking that anyway :) No point wasting space if you don't NJN> have to. Reasonable enough. I am actually expecting this will be pretty backwards-compatible, at least with the more compatible layout, but in any case it's just a one-line change. NJN> But one issue that worries me: even if the shadow size is only NJN> double the normal size, will all the register stuff work in the NJN> IR? For example, if the code is dealing with registers of type NJN> F64 or V128, there's no way to talk about shadow registers of NJN> twice that size, is there? It's probably ok for the integer NJN> registers, but that's only part of the story. Yes, this gets to the point that what my tools are doing is in fact a little more different. The notion of a multiplier isn't really the most natural one for them, since it isn't that they want an n bits-1 bit shadow area in the way Memcheck wants a 1 bit-1 bit one. Instead, they want to have a fixed-size tag for each separate register (e.g., 32 bits per register for the abstract type inference tool, at least on 32 bit machines). So the most space efficient thing would actually be to have a quite different guest-space layout, though depending on how many registers of different sizes there are it might still have to be bigger overall. But since the IR representation of guest state locations is just integer offsets, this would require a somewhat ugly lookup table. The easier scheme that we've hit on is just to multiply all the offsets by a constant when computing the shadow offset. If you pick the constant to be the largest factor by which anything expands (e.g., 4 if there are byte registers that have 32-bit shadows), then nothing overlaps, though there's unused space around the shadows for larger registers. (This scheme would also get in trouble if there were registers that were sometimes accessed with GET/PUT and other times with GETI/PUTI, but that doesn't seem to happen with the current VEX on x86 or amd64.) -- Stephen |