summaryrefslogtreecommitdiff
path: root/Libraries/LibX86
AgeCommit message (Collapse)Author
2020-12-25LibELF: Remove ELF::Loader and move everyone to ELF::ImageAndreas Kling
This commit gets rid of ELF::Loader entirely since its very ambiguous purpose was actually to load executables for the kernel, and that is now handled by the kernel itself. This patch includes some drive-by cleanup in LibDebug and CrashDaemon enabled by the fact that we no longer need to keep the ref-counted ELF::Loader around.
2020-11-17LibX86: Pack the Instruction data structureAndreas Kling
This patch shrinks X86::Instruction from 56 to 28 bytes by packing data members more tightly and removing some entirely. There is still some data duplication between Instruction and the corresponding InstructionDescriptor but it will be a bit tricky to get much more out of it. This looks like a 1-2% improvement on general emulation speed. :^)
2020-10-20Everywhere: Redundant inline specifier on constexpr functions (#3807)Lenny Maiorani
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-20LibX86: clang-formatAndreas Kling
2020-10-19LibX86: malloc a bit lessNico Weber
This reduces malloc()/free() calls in `disasm /bin/id` by 30% according to LIBC_DUMP_MALLOC_STATS. No measurable performance change (the number of empty block hits remains unchanged, and that's what's slow), but maybe a nice change regardless?
2020-09-23UserspaceEmulator+LibX86: Clean up some obnoxious template spamAndreas Kling
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-23UserspaceEmulator+LibX86: Add support for 64-bit memory reads and writes (#3584)Nico Weber
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-08-16LibX86: Remove some allocations from Instruction::to_stringNico Weber
Instruction::to_string used to copy a string literal into a String, and then the String into a StringBuilder. Copy it to the StringBuilder directly. No measurable performance benefit, but it's also less code.
2020-08-16X86+Profiler+UserspaceEmulator: Deduplicate ELFSymbolProvider to LibX86Nico Weber
From a layering perspective, it's maybe a bit surprising that the X86::SymbolProvider implementation also lives in LibX86, but since everything depends on LibELF via LibC, and since all current LibX86-based disassemblers want to use ELFSymbolProvider, it makes some amount of sense to put it there.
2020-08-06AK: Rename MakeUnsigned::type to MakeUnsigned::Type.asynts
Also renames MakeSigned::type to MakeSigned::Type.
2020-08-04LibX86: Remove unused private fields m_segment, m_handlerNico Weber
2020-07-30LibX86: FPU instructions never have a lock prefixNico Weber
2020-07-30LibX86: Disassemble most remaining FPU instructionsNico Weber
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-28LibX86: Disassemble most FPU instructions starting with D9Nico Weber
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-26LibX86: Support disassembling a few FPU opcodes betterNico Weber
2020-07-21UserspaceEmulator+LibX86: Start tracking uninitialized memory :^)Andreas Kling
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-15LibX86: Don't cache whether instruction have a sub-opcodeAndreas Kling
We can just check if the first opcode byte is 0x0f to know this.
2020-07-15LibX86+UserspaceEmulator: Don't store a32 in MemoryOrRegisterReferenceAndreas Kling
The a32 bit tells us whether a memory address is 32-bit or not. We already have this information in Instruction, so just plumb that around instead of double-caching the bit.
2020-07-15LibX86: Don't store the prefix/imm1/imm2 byte counts individuallyAndreas Kling
We can shrink and simplify Instruction a bit by combining these into a single "extra bytes" count.
2020-07-15LibX86: Remove Instruction::m_handlerAndreas Kling
We can fetch the handler via Instruction::m_descriptor.
2020-07-13LibX86+UserspaceEmulator: Devirtualize and inline more instruction codeAndreas Kling
Use some template hacks to force GCC to inline more of the instruction decoding stuff into the UserspaceEmulator main execution loop. This is my last optimization for today, and we've gone from ~60 seconds when running "UserspaceEmulator UserspaceEmulator id" to ~8 seconds :^)
2020-07-13LibX86: Don't build_opcode_table_if_needed() every instruction decodeAndreas Kling
Instead, just do this once at startup. :^)
2020-07-13LibX86: Apply aggressive inlining to Instruction decoding functionsAndreas Kling
These functions really benefit from being inlined together instead of being separated. This yields roughly a ~2x speedup.
2020-07-13UserspaceEmulator+LibX86: Turn on -O3 optimization for emulation codeAndreas Kling
Since this code is performance-sensitive, let's have the compiler do whatever it can to help us with the most important files. This yields a ~8% speedup.
2020-07-13LibX86: ALWAYS_INLINE some Instruction membersAndreas Kling
2020-07-11UserspaceEmulator+LibX86: Implement the LEA instructionAndreas Kling
This piggybacks nicely on Instruction's ModR/M resolution code. :^)
2020-07-10UserspaceEmulator+LibX86: Implement all the forms of XORAndreas Kling
And they're all generic, which will make it easy to support more ops.
2020-07-10LibX86: Add a templatized way to resolve ModR/M memory referencesAndreas Kling
Hopefully this will be flexible enough for our SoftCPU. :^)
2020-07-10LibX86: Store Instruction's segment prefix as Optional<SegmentRegister>Andreas Kling
Instead of having a dedicated enum value for the empty state.
2020-07-09UserspaceEmulator: Tidy up SoftCPU's general purpose registersAndreas Kling
This patch adds a PartAddressableRegister type, which divides a 32-bit value into separate parts needed for the EAX/AX/AL/AH register splits. Clean up the code around register access to make it a little less cumbersome to use.
2020-07-07LibX86: Expose some more things on X86::InstructionAndreas Kling
2020-07-07LibX86: Add an abstract X86::Interpreter classAndreas Kling
This abstract class has a pure virtual member function for all of the X86 instructions. This can be used to implement.. something. :^)
2020-06-28LibX86: Disassemble the XADD instructionAndreas Kling
This makes functrace usable again :^)
2020-05-14Build: Switch to CMake :^)Sergey Bugaev
Closes https://github.com/SerenityOS/serenity/issues/2080
2020-05-07LibX86: Rename build0FSlash() to build_0f_slash()Linus Groh
As spotted by @heavyk this was missed in 57b2b96.
2020-05-04LibX86: Simplify "register index to string" functions a bitAndreas Kling
2020-05-04LibX86: Remove accidental camelCase in some namesAndreas Kling
2020-04-30LibX86: Disassemble BSWAPAndreas Kling
2020-04-15LibX86: Use MakeUnsigned<T> from AK instead of making a custom oneAndreas Kling
2020-04-12LibX86: Add a way for Instruction::to_string() to symbolicate addressesAndreas Kling
This patch adds a pure virtual X86::SymbolProvider that can be passed to Instruction::to_string(). If the instruction contains what appears to be a program address, stringification will try to symbolicate that address via the SymbolProvider. This makes it possible (and very flexible) to add symbolication to clients of the disassembler. :^)
2020-04-11LibX86: Decode RDRAND instructionAndreas Kling
I was looking at Kernel::get_good_random_bytes() and wondering where the RDRAND instruction was. :^)
2020-04-11LibX86: Fix duplicate '+' in SIB byte disassemblyAndreas Kling
For SIB bytes with base but no index, we were emitting two '+' chars which looked very off.
2020-04-11LibX86: When there are multiple REPZ/REPNZ prefixes, the last one winsAndreas Kling
2020-04-11LibX86: Tolerate invalid segment register indices when disassemblingAndreas Kling
While #6 and #7 are not valid segment register, they can still be encoded in otherwise-valid instructions, so let's tolerate it.
2020-04-11LibX86: Disassemble unknown opcodes as "db %#02x"Andreas Kling
2020-04-11LibX86: Decode PADDB, PADDW and PADDDAndreas Kling
2020-04-11LibX86: Don't choke on invalid LOCK prefixes for nowAndreas Kling
This might be interesting information later, but I'm not sure how to encode it at the moment.
2020-04-11LibX86: Fix backwards arguments to ENTER imm16,imm8Andreas Kling
2020-04-11LibX86: Add 8-bit CMPXCHG and allow LOCK CMPXCHGAndreas Kling
2020-04-11LibX86: Support decoding basic MMX instructions like MOVQAndreas Kling