Class AbstractProcessor<InsnType extends IInstruction>

java.lang.Object
com.pnfsoftware.jeb.core.units.code.asm.processor.AbstractProcessor<InsnType>
Type Parameters:
InsnType -
All Implemented Interfaces:
IProcessor<InsnType>

@Ser public abstract class AbstractProcessor<InsnType extends IInstruction> extends Object implements IProcessor<InsnType>
An abstract implementation of a processor. It is recommended to inherit from this class. The implementor simply needs to implement a parseAt() method. Instruction alignment is enforced.

Implementations of parseAtInternal(byte[], int, int) cannot be guaranteed to be thread-safe. Because of that, parsing is synchronized to allow concurrent threads to parse safely. Use lock instead of `synchronized(this)` for locking. (This will allow us to offer implementors a way to disable locking/synchronizing when the implementation is truly concurrent.)

  • Field Details

  • Constructor Details

    • AbstractProcessor

      public AbstractProcessor(int parseCacheLength, int defaultMode, Endianness endianness, int instructionAlign)
      Create a processor.
      Parameters:
      parseCacheLength -
      defaultMode -
      endianness -
      instructionAlign -
    • AbstractProcessor

      public AbstractProcessor(int parseCacheLength, int defaultMode, IUnitCreator parent, int instructionAlign)
    • AbstractProcessor

      public AbstractProcessor(int parseCacheLength, int defaultMode, IUnitCreator parent, int instructionAlign, int parseBufferBefore)
      Create a processor, retrieving Endianness from parent IUnitCreator. If the endianness cannot be retrieved, default little-endian will be used.
      Parameters:
      parseCacheLength - Total byte length to retrieve when parseAt(IVirtualMemory, long) method is called.
      defaultMode - Default Processor Mode
      parent - Creator of the processor
      instructionAlign - Minimum instruction alignment allowed.
      parseBufferBefore - number of bytes to parse before current address when parseAt(IVirtualMemory, long) method is called. Note than the byte range will be [address-parseBufferBefore, address+parseCacheLength]
  • Method Details

    • getRegisterName

      public String getRegisterName(long registerCode)
      The default implementation attempts to find a name using getRegisterBank().
      Specified by:
      getRegisterName in interface IProcessor<InsnType extends IInstruction>
      Parameters:
      registerCode - register code used by this processor object as well as generated instruction and operand objects. Not to be confused with standardized register indices defined in register bank objects
      Returns:
      a name or null (on error or if the implementation is not provided)
    • parseAt

      public InsnType parseAt(IVirtualMemory vm, long address) throws ProcessorException
      Description copied from interface: IProcessor
      Parse a single instruction at the specified address in memory.
      Specified by:
      parseAt in interface IProcessor<InsnType extends IInstruction>
      Parameters:
      vm - the input virtual memory
      address - the address to read at, with permission of read+write
      Returns:
      the instruction, never null. On parsing error, an exception is raised
      Throws:
      ProcessorException - on parsing error
    • parseAt

      public final InsnType parseAt(byte[] bytes, int index, int end) throws ProcessorException
      Description copied from interface: IProcessor
      Parse a single instruction.
      Specified by:
      parseAt in interface IProcessor<InsnType extends IInstruction>
      Parameters:
      bytes - input code buffer
      index - where to parse in the input buffer
      end - exclusive end offset in the buffer: if parsing at the given index offset requires bytes past the end offset, an exception is raised
      Returns:
      the instruction, never null - on parsing error, an exception is raised
      Throws:
      ProcessorException - on parsing error
    • parseAtInternal

      protected abstract InsnType parseAtInternal(byte[] bytes, int index, int end) throws ProcessorException
      Decode bytes as instructions. The one and only method all processors must implement. This method is not synchronized; implementations should keep its protection level to `protected`, unless they want client code to be able to do fast(er), albeit unsafe, parsing. Most implementations should keep this method protected, and client code should call parseAt(byte[], int, int) or other similar, safe methods.
      Parameters:
      bytes -
      index -
      end -
      Returns:
      Throws:
      ProcessorException
    • parseWithContext

      public InsnType parseWithContext(IMachineContext context) throws ProcessorException
      Description copied from interface: IProcessor
      Parse a single instruction given a machine context. The context provides access to at least:
      • memory data
      • a register bank, including the program counter
      When using this method, other settings determined by this interface, such as the processor mode or endianness, can be disregarded: the context has higher priority. However, an implementor is allowed to raise a processor exception if mismatches are detected (typically, the endianness).
      Specified by:
      parseWithContext in interface IProcessor<InsnType extends IInstruction>
      Returns:
      Throws:
      ProcessorException
    • parseWithContextInternal

      protected InsnType parseWithContextInternal(IMachineContext context) throws ProcessorException
      The default implementation throws UnsupportedOperationException.
      Parameters:
      context -
      Returns:
      Throws:
      ProcessorException
    • getType

      public ProcessorType getType()
      The default implementation returns ProcessorType.UNKNOWN. Most implementation will want to override this default and return a proper processor type.
      Specified by:
      getType in interface IProcessor<InsnType extends IInstruction>
      Returns:
    • getRegisterBank

      public IRegisterBank getRegisterBank()
      The default implementation attempts to find an appropriate hard-coded bank (from getType()) using RegisterUtil.
      Specified by:
      getRegisterBank in interface IProcessor<InsnType extends IInstruction>
      Returns:
    • isRISC

      public boolean isRISC()
      The default implementation returns false (i.e. assume the processor is not RISC unless explicitly specified).
      Specified by:
      isRISC in interface IProcessor<InsnType extends IInstruction>
      Returns:
    • getSupportedVariants

      public Collection<ProcessorVariant> getSupportedVariants()
      Description copied from interface: IProcessor
      Retrieve a list of supported processor variants.
      Specified by:
      getSupportedVariants in interface IProcessor<InsnType extends IInstruction>
      Returns:
    • getVariant

      public ProcessorVariant getVariant()
      Description copied from interface: IProcessor
      Get the processor variant used by this object.
      Specified by:
      getVariant in interface IProcessor<InsnType extends IInstruction>
      Returns:
    • setVariant

      public void setVariant(ProcessorVariant variant) throws ProcessorException
      Description copied from interface: IProcessor
      Set the new variant used by this processor.
      Specified by:
      setVariant in interface IProcessor<InsnType extends IInstruction>
      Throws:
      ProcessorException - if the variant is not supported
    • getSupportedModes

      public Collection<Integer> getSupportedModes()
      Description copied from interface: IProcessor
      Get the list of valid modes that this processor supports.
      Specified by:
      getSupportedModes in interface IProcessor<InsnType extends IInstruction>
      Returns:
    • getDefaultMode

      public final int getDefaultMode()
      Description copied from interface: IProcessor
      Get the default processor mode. The mode indicates the current operating size of the processor. Typically, this represents the size in bits of general purpose (GP) registers, as well as the size of the program counter (PC).
      Specified by:
      getDefaultMode in interface IProcessor<InsnType extends IInstruction>
      Returns:
      the default processor mode, never IProcessor.MODE_DEFAULT (0)
    • setDefaultMode

      protected final void setDefaultMode(int defaultMode)
      Set the default mode. Only for implementors. This method is and should be called just once (at construction time).
      Parameters:
      defaultMode - the default processor mode, cannot be 0
    • getPCRegisterBitsize

      public int getPCRegisterBitsize()
      Description copied from interface: IProcessor
      Retrieve the size of the Program Counter register, in bits.
      Specified by:
      getPCRegisterBitsize in interface IProcessor<InsnType extends IInstruction>
      Returns:
    • getGPRegisterBitsize

      public int getGPRegisterBitsize()
      Description copied from interface: IProcessor
      Retrieve the size of a General Purpose register, in bits.
      Specified by:
      getGPRegisterBitsize in interface IProcessor<InsnType extends IInstruction>
      Returns:
    • setMode

      public int setMode(int newMode) throws ProcessorException
      Description copied from interface: IProcessor
      Set the processor mode. Implementors may override this class, if they have other/better/proper ways to determine the processor operating mode. In that case, the mode provided by this method may be regarded as a hint - or disregarded entirely.
      Specified by:
      setMode in interface IProcessor<InsnType extends IInstruction>
      Parameters:
      newMode - the mode, the value IProcessor.MODE_DEFAULT (0) can be provided to revert to the default processor mode
      Returns:
      the previous processor mode
      Throws:
      ProcessorException - if the mode is not supported
    • getMode

      public final int getMode()
      Description copied from interface: IProcessor
      Get the processor mode. Typically, the processor mode is a size in bits that indicates how instructions are parsed and/or the size of general-purpose registers used for arithmetic operations and/or how memory slots are addressed are accessed. Typical processor modes are 8-, 16-, 32- or 64- bits). Note: A 'processor mode' could have a different semantic, but anything non-standard is unlikely to be understood by client code. This function will never return 0 See MODE_Xxx for common constants.
      Specified by:
      getMode in interface IProcessor<InsnType extends IInstruction>
      Returns:
      the processor mode, never IProcessor.MODE_DEFAULT (0)
    • getEndianness

      public final Endianness getEndianness()
      Description copied from interface: IProcessor
      Get the endianness this processor operates in.
      Specified by:
      getEndianness in interface IProcessor<InsnType extends IInstruction>
      Returns:
    • setEndianness

      public final void setEndianness(Endianness endianness)
      Description copied from interface: IProcessor
      Set the endianness of this processor.
      Specified by:
      setEndianness in interface IProcessor<InsnType extends IInstruction>
    • getInstructionAlignment

      public final int getInstructionAlignment()
      Description copied from interface: IProcessor
      Retrieve the instruction alignment, in bytes.
      Specified by:
      getInstructionAlignment in interface IProcessor<InsnType extends IInstruction>
      Returns:
      the instruction alignment, eg, 1, 2, 4, 8, etc.
    • getInstructionAlignmentMask

      public int getInstructionAlignmentMask()
    • setInstructionAlignment

      public final void setInstructionAlignment(int align)
      Description copied from interface: IProcessor
      Set the instruction alignment, in bytes. The implementation may decide to enforce alignment, or ignore it. If alignment is enforced, attempting to parse an unaligned instruction should raise a ProcessorException.
      Specified by:
      setInstructionAlignment in interface IProcessor<InsnType extends IInstruction>
      Parameters:
      align - the alignment, must be a strictly positive power of 2
    • getResolver

      public ICodeResolver<InsnType> getResolver()
      The default implementation returns null. Careful, access to this object is subject to locking.
      Specified by:
      getResolver in interface IProcessor<InsnType extends IInstruction>
      Returns:
      a resolver
    • createEntryPoint

      public CodePointer createEntryPoint(long address)
      The default implementation creates an entry-point using the exact provided address, with a default processor mode.
      Specified by:
      createEntryPoint in interface IProcessor<InsnType extends IInstruction>
      Parameters:
      address - address of the instruction
      Returns:
      the entry point (careful! may contain an address different -adjusted- than the input parameter)
    • createEntryPoint

      public CodePointer createEntryPoint(long address, int defaultMode)
      Description copied from interface: IProcessor
      Create an entry-point from a provided native address.
      Specified by:
      createEntryPoint in interface IProcessor<InsnType extends IInstruction>
      Parameters:
      address - address of the instruction
      defaultMode - default processor mode if it cannot be determined by address
      Returns:
      the entry point (careful! may contain an address different -adjusted- than the input parameter)
    • clearInstructionCache

      public boolean clearInstructionCache()
      Clear the instruction cache, if this processed uses one.

      The default implementation does nothing.

      Returns:
      true if a cache was in place, was used, and was cleared; false otherwise