Package ghidra.pcode.emu.jit.decode

# Class DecoderUseropLibrary

java.lang.Object
ghidra.pcode.exec.AnnotatedPcodeUseropLibrary<Object>
ghidra.pcode.emu.jit.decode.DecoderUseropLibrary

All Implemented Interfaces:
  `PcodeUseropLibrary<Object>`

public class DecoderUseropLibrary extends AnnotatedPcodeUseropLibrary<Object>
The decoder's wrapper around the emulator's userop library

This library serves two purposes: 1) to override `DefaultPcodeThread.PcodeEmulationLibrary.emu_exec_decoded()` and `DefaultPcodeThread.PcodeEmulationLibrary.emu_skip_decoded()`, and 2) to check and inline p-code userops that `allow` it.

We accomplish the first purpose simply by adding the two userops using the usual annotations. The two built-in userops regarding the decoded instruction are easily inlinable, so we will mark them as such. Note, however, that they are separate from the wrappers we mention for the second purpose (inlining), and so we must implement that inlining in the actual userop. We still mark them for informational purposes and because the translator needs to know.

We accomplish the second purpose of inlining by accepting the emulator's userop library and individually wrapping each of its userops, excluding the two we override. We allow each userop's attributes to pass through, but when executed, we check if the userop allows inlining. If so, then we feed the userop's p-code into the decoder's interpreter. This effectively inlines the op, control flow ops and all, into the passage. Note we do not actually replace the `callother` op, for bookkeeping purposes. Instead we will map it to a `nop` during translation.

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Class
  Description
  `protected class`
  `DecoderUseropLibrary.WrappedUseropDefinition`
  The wrapper around one of the emulator's userops

  ## Nested classes/interfaces inherited from class ghidra.pcode.exec.AnnotatedPcodeUseropLibrary

  `AnnotatedPcodeUseropLibrary.AnnotatedPcodeUseropDefinition<T>, AnnotatedPcodeUseropLibrary.FixedArgsAnnotatedPcodeUseropDefinition<T>, AnnotatedPcodeUseropLibrary.OpExecutor, AnnotatedPcodeUseropLibrary.OpLibrary, AnnotatedPcodeUseropLibrary.OpOutput, AnnotatedPcodeUseropLibrary.OpState, AnnotatedPcodeUseropLibrary.PcodeUserop, AnnotatedPcodeUseropLibrary.VariadicAnnotatedPcodeUseropDefinition<T>`

  ## Nested classes/interfaces inherited from interface ghidra.pcode.exec.PcodeUseropLibrary

  `PcodeUseropLibrary.EmptyPcodeUseropLibrary, PcodeUseropLibrary.PcodeUseropDefinition<T>`

- ## Field Summary

  ### Fields inherited from class ghidra.pcode.exec.AnnotatedPcodeUseropLibrary

  `ops`

  ### Fields inherited from interface ghidra.pcode.exec.PcodeUseropLibrary

  `NIL`

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `DecoderUseropLibrary(PcodeUseropLibrary<byte[]> rtLib)`
  Wrap the given userop library

- ## Method Summary

  Modifier and Type
  Method
  Description
  `void`
  `emu_exec_decoded(PcodeExecutor<Object> executor)`
  The replacement for `DefaultPcodeThread.PcodeEmulationLibrary.emu_exec_decoded()`.
  `void`
  `emu_skip_decoded(PcodeExecutor<Object> executor)`
  The replacement for `DefaultPcodeThread.PcodeEmulationLibrary.emu_skip_decoded()`.

  ### Methods inherited from class ghidra.pcode.exec.AnnotatedPcodeUseropLibrary

  `getMethodLookup, getOperandType, getUserops`

  ### Methods inherited from class java.lang.Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

  ### Methods inherited from interface ghidra.pcode.exec.PcodeUseropLibrary

  `compose, getSymbols`

- ## Constructor Details

  - ### DecoderUseropLibrary

    public DecoderUseropLibrary(PcodeUseropLibrary<byte[]> rtLib)
    Wrap the given userop library
    Parameters:
      `rtLib` - the actual library provided by the user or emulator

- ## Method Details

  - ### emu_exec_decoded

    public void emu_exec_decoded(PcodeExecutor<Object> executor)
    The replacement for `DefaultPcodeThread.PcodeEmulationLibrary.emu_exec_decoded()`.

    The one built into the emulator would have the thread interpret the decoded instruction directly. While this might "work," it totally missed the purpose of JIT translation. We instead inline the userop's p-code into the rest of the passage. We accomplish this by having the decoder interpret the p-code instead. We also need to ensure the decoded instruction is added into the passage.

    Note that the `callother` op will be mapped to a `nop` during translation because we have set `canInline`.

    Parameters:
      `executor` - the decoder's executor

  - ### emu_skip_decoded

    public void emu_skip_decoded(PcodeExecutor<Object> executor)
    The replacement for `DefaultPcodeThread.PcodeEmulationLibrary.emu_skip_decoded()`.

    The one built into the emulator would have the thread drop and skip the decoded instruction directly. This would not have the intended effect, because the decoder is the thing that needs to skip and advance to the next address. We instead "inline" nothing, but we must still decode the instruction. Because the executor provides the decode routine, it can internally work out fall through. We will not add the instruction to the passage, though, because we will not have the executor interpret any of the instructon's p-code. As for fall through, the `DecoderExecutor.checkFallthroughAndAccumulate(PcodeProgram)` routine just does its usual. If the inject falls through, `DecoderExecutor.getAdvancedAddress()` considers the decoded instruction, even though it was never interpreted.

    Note that the `callother` op will still be mapped to a `nop` during translation because we have set `canInline`.

    Parameters:
      `executor` - the decoder's executor