Bug 197978 - No support for non-flat CS for x86 guests
Summary: No support for non-flat CS for x86 guests
Status: REPORTED
Alias: None
Product: valgrind
Classification: Developer tools
Component: vex (show other bugs)
Version: 3.5 SVN
Platform: Compiled Sources Linux
: NOR crash
Target Milestone: ---
Assignee: Julian Seward
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-06-26 17:35 UTC by Samuel Bronson
Modified: 2009-06-29 06:39 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Samuel Bronson 2009-06-26 17:35:12 UTC
Valgrind cannot handle programs that use non-flat code segments. If it encounters a far jump, it will essentially crash.
Comment 1 Nicholas Nethercote 2009-06-27 03:18:15 UTC
I assume this relates to bug 197448, in that you are trying to run DOSEMU under Valgrind?

DOSEMU is a program that "allows you to run DOS and many DOS programs, including many DPMI applications such as DOOM and Windows 3.1, under Linux."  (http://dosemu.sourceforge.net/)

We need to decide what to do here.  Basically, segment registers are a bit fat pain to handle in Valgrind.  We have limited support for some of the more common cases, but you're reporting new problems that nobody else has, probably because nobody else has been emulating DOS programs :(  I suspect if we fix these bugs, you'll hit more obscure corners of the x86 architecture that modern programs never use.

So I wonder if this is not worth the effort given that it's only needed for what is not exactly a mainstream use.

Julian, what do you think?
Comment 2 Julian Seward 2009-06-27 16:15:06 UTC
> So I wonder if this is not worth the effort given that it's only needed for
> what is not exactly a mainstream use.

For sure this is an obscure case for us, but anyway.  I think we do support
more or less arbitrary use of segment overrides for data access instructions,
though.

What be useful is to guesstimate how difficult/intrusive this will be to fix.
Samuel, can you send a short summary of how code segment overrides on Linux
x86 may be used, or at least what support you need for DOSEMU ?  Plus it would
be interesting to know why it is that we've never had a need to support them
before now.
Comment 3 Samuel Bronson 2009-06-27 22:59:33 UTC
Well, for 32-bit DPMI code to work, DOSEMU just needs to be able to run code from segments it sets up with modify_ldt. This will mostly just mean that the base address of the segment indicated by CS  will need to be added to EIP in order to figure out what linear address to fetch instructions from. The real CPUs also check segment limits, but that might not be needed to just get DOSEMU working at the basic level -- it should only be an issue if code either attempts to jump outside of a segment, or falls off the end of one, and that doesn't seem likely to be very common.

Theoretically, DPMI allows the use of 16-bit protected mode code as well, but I'm not positive DOSEMU implements this, and I'm fairly certain that this is not needed to run DJGPP-compiled programs, which is what I'm hoping to do.
At least 90% of 16-bit DOS programs are designed to run in real mode, which DOSEMU handles using vm86(), and valgrind seems to pass that over to the kernel well enough as it is, so it shouldn't be necessary to add this.

Blocks of translated code would need to be marked with the CS from which they originated, so that
  (a) we don't pick a block that is a translation of the offset in a different segment from the one we want when picking a JMP/CALL target
  (b) we can invalidate all of the translations when a code segment's descriptor is overwritten (though this doesn't have to actually happen until a corresponding selector is next loaded into CS, since the CPU does not actually read segment descriptors except when loading segment registers, in general)
Comment 4 Julian Seward 2009-06-29 02:10:44 UTC
> from segments it sets up with modify_ldt. This will mostly just mean that the
> base address of the segment indicated by CS  will need to be added to EIP in
> order to figure out what linear address to fetch instructions from.

Sure.  So the vex-end stuff is pretty trivial, since we already support
segment overrides for data accesses.

> Blocks of translated code would need to be marked with the CS from which they
> originated, so that

This the real difficulty.  It's not just the code cache that needs
attention.  The assumption that a guest code address can be represented
exactly by a single UWord (host word) is deeply wired into the design,
and we'd need to visit a lot of places to fix that properly.  At least
for code cache management, symbol table stuff, and redirections, and
probably more.
Comment 5 Samuel Bronson 2009-06-29 05:16:39 UTC
(In reply to comment #4)
> > Blocks of translated code would need to be marked with the CS from which
> > they originated, so that
> 
> This the real difficulty.  It's not just the code cache that needs
> attention.  The assumption that a guest code address can be represented
> exactly by a single UWord (host word) is deeply wired into the design,
> and we'd need to visit a lot of places to fix that properly.  At least
> for code cache management, symbol table stuff, and redirections, and
> probably more.

Well, it's possible that I'm overstating things ...

Would it perhaps be possible to avoid doing the symbol table stuff/redirections for non-default CS values? It seems unlikely that valgrind will be able to find any symbols in the midst of the practically-anonymous mapping that DOSEMU creates, especially since the only executables that would be remotely likely to have symbols it might understand would be in what objdump calls "coff-go32-exe" format... and I certainly don't want any redirections applied to them, in any case ;-). (Not to mention that, for some strange reason, they all seem to be statically linked...)

And if it thinks it can stuff a guest code address in a UWord ... why even link any of the PPC64 and AMD64 guest code when compiling on a 32-bit host?
Comment 6 Nicholas Nethercote 2009-06-29 06:39:08 UTC
(In reply to comment #5)
> 
> And if it thinks it can stuff a guest code address in a UWord ... why even link
> any of the PPC64 and AMD64 guest code when compiling on a 32-bit host?

We compile the code for every arch to make sure no compile errors on any arch creep in.  And we link all the code because there's no easy way (AFAIK) via automake to compile the code for the other archs but not link it.