1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-24 13:45:07 +00:00
Commit graph

148 commits

Author SHA1 Message Date
Andreas Kling
d14695f823 UserspaceEmulator: Cache the region we're executing code from
Instead of caching a raw pointer to the next instruction, cache the
region we're fetching instructions from, and a pointer to its base.
This way we don't need to keep invalidating and reloading the cache
whenever the CPU jumps.
2020-11-16 15:11:02 +01:00
Andreas Kling
fe7036d8f4 UserspaceEmulator: Improve error text on jump to non-executable memory
The memory is non-executable, not non-readable. :^)
2020-11-16 09:10:49 +01:00
Nico Weber
6252e5b1f6 UserspaceEmulator: Implement 32-bit FIDIV, 16-bit FIADD/FISUB/FISUBR/FIDIV/FIDIVR/FISTP, and fix 32-bit FIADD
Not motivated by anything in particular, they just looked easy to fill
in. With this, all arithmetic FI* FPU instructions are implemented.

Switch to the mXXint style in a few more functions, this part is no-op.
2020-11-15 20:16:55 +01:00
Andreas Kling
6dab0af9af UserspaceEmulator: Add a fast path for forward REP STOSD
Same as REP STOSB, except for 32-bit fills instead.
2020-11-15 18:09:15 +01:00
Andreas Kling
102e1d330c UserspaceEmulator: Add a fast path for forward REP STOSB
This is used by memset() so we get a lot of mileage out of optimizing
this instruction.

Note that we currently audit every individual byte accessed separately.
This could be greatly improved by adding a range auditing mechanism to
MallocTracer.
2020-11-15 18:09:08 +01:00
Nico Weber
be73f9f544 UserspaceEmulator: Implement FISUBR_RM32
Fixes crash when playing `ue Breakout` with the mouse.
2020-11-15 09:36:37 +01:00
Andreas Kling
12d923bb7e UserspaceEmulator: Fix some FPU instructions' handling of RM32/RM64
m32int is a 32-bit integer stored in memory, and should not be mistaken
for a floating point number. :^)

Also add missing handling of 64-bit FPU register operands to some of
the RM64 instructions.
2020-11-14 23:47:50 +01:00
Andreas Kling
b5b535aa81 UserspaceEmulator: Untaint flags in FCOMI and FUCOMI for now
This makes UE logging bearable until we can get proper shadow data
support for the FPU stack.
2020-11-14 23:11:07 +01:00
Andreas Kling
677af891b4 UserspaceEmulator: Implement FISUB_RM32 2020-11-14 15:34:53 +01:00
Andreas Kling
ca85ecc032 UserspaceEmulator: Remove some FPU debug spam 2020-11-14 15:34:53 +01:00
Andreas Kling
a031c6c754 UserspaceEmulator: Implement FABS 2020-11-14 15:34:48 +01:00
Andreas Kling
60ff27c633 UserspaceEmulator: Improve FCOMI/FCOMIP/FUCOMI/FUCOMIP
These instructions now operate on the specified FPU stack entry instead
of always using ST(0) and ST(1).

FUCOMI and FUCOMIP also handle NaN values slightly better.
2020-11-14 15:33:56 +01:00
Andreas Kling
d4509647d8 UserspaceEmulator: Honor the read/write/execute bits in mmap regions
UE will now correctly crash when accessing an mmap memory region in
some way it's not supposed to be accessed.
2020-11-14 15:33:56 +01:00
Andreas Kling
df3a70eac2 UserspaceEmulator: Support FCMOVBE and FCMOVNBE 2020-11-13 11:05:46 +01:00
Andreas Kling
04d9af79ac UserspaceEmulator: Initial FPU support (by @nico)
Start fleshing out basic support for floating-point instructions in the
UserspaceEmulator CPU.

This is all work done by @nico for #3576. I'm just merging it all in
this patch since it's a decent foundation to continue working on. :^)
2020-11-13 11:05:46 +01:00
Andreas Kling
9af1a4b9b1 UserspaceEmulator: Support the first two levels of CPUID
GCC uses these when deciding which memcpy implementation to use.
2020-11-08 22:47:02 +01:00
Andreas Kling
c4dd77a170 UserspaceEmulator+LibC: Have UE notice realloc() and update accounting
When a mallocation is shrunk/grown without moving, UE needs to update
its precise metadata about the mallocation, since it tracks *exactly*
how many bytes were allocated, not just the malloc chunk size.
2020-11-08 10:43:15 +01:00
AnotherTest
9afe9069a9 UserspaceEmulator: Optionally write reports to the debug log
...and take a flag '--report-to-debug' that determines this behaviour.
2020-10-25 10:13:03 +01:00
Lenny Maiorani
d1fe6a0b53
Everywhere: Redundant inline specifier on constexpr functions (#3807)
Problem:
- `constexpr` functions are decorated with the `inline` specifier
  keyword. This is redundant because `constexpr` functions are
  implicitly `inline`.
- [dcl.constexpr], §7.1.5/2 in the C++11 standard): "constexpr
  functions and constexpr constructors are implicitly inline (7.1.2)".

Solution:
- Remove the redundant `inline` keyword.
2020-10-20 18:08:13 +02:00
Paul Scharnofske
d94f674bbb
Use new format functions in remaining DevTools. (#3755)
* AK: Add formatter for JsonValue.

* Inspector: Use new format functions.

* Profiler: Use new format functions.

* UserspaceEmulator: Use new format functions.
2020-10-13 18:34:27 +02:00
asynts
e089855af0 UserspaceEmulator: Remove remaining printf calls. 2020-10-04 17:04:55 +02:00
asynts
d5ffb51a83 AK: Don't add newline for outf/dbgf/warnf.
In the future all (normal) output should be written by any of the
following functions:

    out    (currently called new_out)
    outln
    dbg    (currently called new_dbg)
    dbgln
    warn   (currently called new_warn)
    warnln

However, there are still a ton of uses of the old out/warn/dbg in the
code base so the new functions are called new_out/new_warn/new_dbg. I am
going to rename them as soon as all the other usages are gone (this
might take a while.)

I also added raw_out/raw_dbg/raw_warn which don't do any escaping,
this should be useful if no formatting is required and if the input
contains tons of curly braces. (I am not entirely sure if this function
will stay, but I am adding it for now.)
2020-10-04 17:04:55 +02:00
asynts
ba3488a6d5 UserspaceEmulator: Replace printf usages with format.
This replaces almost all usages. Some have to remain because 'outf'
always appends a newline. (It inherits this behaviour from LogStream.)
2020-10-02 13:44:42 +02:00
Andreas Kling
60c2fba9b9 UserspaceEmulator+LibX86: Clean up some obnoxious template spam
Don't require clients to templatize modrm().read{8,16,32,64}() with
the ValueWithShadow type when we can figure it out automatically.
The main complication here is that ValueWithShadow is a UE concept
while the MemoryOrRegisterReference inlines exist at the lower LibX86
layer and so doesn't have direct access to those types. But that's
nothing we can't solve with some simple template trickery. :^)
2020-09-23 21:15:01 +02:00
Nico Weber
f1c0f661f4
UserspaceEmulator+LibX86: Add support for 64-bit memory reads and writes (#3584)
This is useful for reading and writing doubles for #3329.
It is also useful for emulating 64-bit binaries.

MemoryOrRegisterReference assumes that 64-bit values are always
memory references since that's enough for fpu support. If we
ever want to emulate 64-bit binaries, that part will need minor
updating.
2020-09-23 20:45:43 +02:00
Nico Weber
4b5cfce6b1 UserspaceEmulator: Emulate two FPU instructions! 2020-08-30 19:48:59 +02:00
Nico Weber
f8084cc083 UserspaceEmulator: Remove some silly semicolons 2020-08-11 21:04:38 +02:00
Andreas Kling
c6ee6c0b42 UserspaceEmulator: Log unimplemented instructions with proper backtrace 2020-08-11 20:29:14 +02:00
Andreas Kling
5ba2022b8e UserspaceEmulator: Result is initialized after OR with all-1 immediate
When compiling with "-Os", GCC produces the following pattern for
atomic decrement (which is used by our RefCounted template):

    or eax, -1
    lock xadd [destination], eax

Since or-ing with -1 will always produce the same output (-1), we can
mark the result of these operations as initialized. This stops us from
complaining about false positives when running the shell in UE. :^)
2020-08-07 15:41:53 +02:00
Andreas Kling
c7e4c0734b UserspaceEmulator: Use a report() function instead of dbgprintf()
Ultimately we'll want to make it a bit easier to add more reporting.
This at least makes it easier to redirect the logging.
2020-07-31 20:56:48 +02:00
Nico Weber
8593bdb711 LibX86: Disassemble most remaining FPU instructions
Some of the remaining instructions have different behavior for
register and non-register ops.  Since we already have the
two-level flags tables, model this by setting all handlers in
the two-level table to the register op handler, while the
first-level flags table stores the action for the non-reg handler.
2020-07-30 16:53:33 +02:00
Nico Weber
c99a3efc5b LibX86: Disassemble most FPU instructions starting with D9
Some of these don't just use the REG bits of the mod/rm byte
as slashes, but also the R/M bits to have up to 9 different
instructions per opcode/slash combination (1 opcode requires
that MOD is != 11, the other 8 have MODE == 11).

This is done by making the slashes table two levels deep for
these cases.

Some of this is cosmetic (e.g "FST st0" has no effect already,
but its bit pattern gets disassembled as "FNOP"), but for
most uses it isn't.

FSTENV and FSTCW have an extraordinary 0x9b prefix. This is
not yet handled in this patch.
2020-07-28 18:55:29 +02:00
Andreas Kling
31b94114c0 UserspaceEmulator: Recognize xor/sub zeroing idioms and don't taint
"xor reg,reg" or "sub reg,reg" both zero out the register, which means
we know for sure the result is 0. So mark the value as initialized,
and make sure we don't taint the CPU flags.

This removes some false positives from the uninitialized memory use
detection mechanism.

Fixes #2850.
2020-07-27 13:20:23 +02:00
Nico Weber
f6db97b8a9 LibX86: Support disassembling a few FPU opcodes better 2020-07-26 11:29:03 +02:00
Andreas Kling
9fc00d5d12 UserspaceEmulator: XLAT BX should not check full EBX shadow bits
Thanks to Rick van Schijndel for pointing this out. :^)
2020-07-22 00:07:15 +02:00
Andreas Kling
9c155c8f35 UserspaceEmulator: Tweak some output strings 2020-07-21 23:35:09 +02:00
Andreas Kling
a819c35904 UserspaceEmulator: Include flag taint state in dump output 2020-07-21 19:21:52 +02:00
Andreas Kling
5c29f4e326 UserspaceEmulator: Add a newline before uninitialized op warnings 2020-07-21 19:08:01 +02:00
Andreas Kling
d1dd5013ea UserspaceEmulator: Remove unnecessary local getpid() caches
Now that LibC caches this for us, we can stop worrying.
2020-07-21 19:08:01 +02:00
Andreas Kling
e634fe6072 UserspaceEmulator: Warn on conditional op with uninitialized dependency
We now track whether the flags register is tainted by the use of one or
more uninitialized values in a computation.

For now, the state is binary; the flags are either tainted or not.
We could be more precise about this and only taint the specific flags
that get updated by each instruction, but I think this will already get
us 99% of the results we want. :^)
2020-07-21 16:40:09 +02:00
Andreas Kling
48eec58bdc UserspaceEmulator: Flush stdout in SoftCPU::dump()
This makes the CPU dump output interleave correctly with instructions.
2020-07-21 16:38:39 +02:00
Andreas Kling
6c8a0e8c56 UserspaceEmulator: Mark all registers as initialized from boot
Since we zero out all the register values, let's also mark them all
as fully initialized.
2020-07-21 16:35:23 +02:00
Andreas Kling
be5f42adea UserspaceEmulator+LibX86: Start tracking uninitialized memory :^)
This patch introduces the concept of shadow bits. For every byte of
memory there is a corresponding shadow byte that contains metadata
about that memory.

Initially, the only metadata is whether the byte has been initialized
or not. That's represented by the least significant shadow bit.

Shadow bits travel together with regular values throughout the entire
CPU and MMU emulation. There are two main helper classes to facilitate
this: ValueWithShadow and ValueAndShadowReference.

ValueWithShadow<T> is basically a struct { T value; T shadow; } whereas
ValueAndShadowReference<T> is struct { T& value; T& shadow; }.

The latter is used as a wrapper around general-purpose registers, since
they can't use the plain ValueWithShadow memory as we need to be able
to address individual 8-bit and 16-bit subregisters (EAX, AX, AL, AH.)

Whenever a computation is made using uninitialized inputs, the result
is tainted and becomes uninitialized as well. This allows us to track
this state as it propagates throughout memory and registers.

This patch doesn't yet keep track of tainted flags, that will be an
important upcoming improvement to this.

I'm sure I've messed up some things here and there, but it seems to
basically work, so we have a place to start! :^)
2020-07-21 02:37:29 +02:00
Andreas Kling
e4b068aec5 UserspaceEmulator: Fix buggy IDIV instructions
These were not doing mashing together the signed double-size results
correctly and lost bits in the signed/unsigned casting process.
2020-07-18 17:57:40 +02:00
Andreas Kling
9e6d002660 UserspaceEmulator: Fix buggy IMUL instructions
These were not recording the higher part of the result correctly.
Since the flags are much less complicated than the inline assembly
here, just implement IMUL in C++ instead.
2020-07-18 17:57:40 +02:00
Andreas Kling
02882d5345 UserspaceEmulator: Add single-operand MUL and DIV instructions
These are the unsigned variants. Signed variants sold separately.
2020-07-18 17:57:40 +02:00
Andreas Kling
30d512144e UserspaceEmulator: Implement the BSF and BSF instructions
BSF maps nicely to __builtin_ctz(), but for BSR we have to bust out
some inline assembly to get exactly what we want.
2020-07-18 17:57:40 +02:00
Andreas Kling
becbf36711 UserspaceEmulator: Fix XCHG_AX_reg16 overwriting entire EAX
This instruction should only write to the lower 16 bits (AX)
2020-07-18 00:25:02 +02:00
Andreas Kling
8959f9950a UserspaceEmulator: Simplify the STOSB/STOSW/STOSD instructions 2020-07-18 00:25:02 +02:00
Andreas Kling
79290696cf UserspaceEmulator: Simplify MOVSB/MOVSW/MOVSD instructions
Use the new loop instruction helpers.
2020-07-18 00:25:02 +02:00