java.lang.Object | |
↳ | com.pnfsoftware.jeb.core.units.code.asm.processor.AbstractProcessor<InsnType extends com.pnfsoftware.jeb.core.units.code.IInstruction> |
An abstract implementation of a processor
. It is recommended to inherit from
this class. The implementor simply needs to implement a
IProcessor#parseAtInternal(byte[], int, int) 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.)
TODO: consider decoupling mode/endianness/alignment/etc. attribute updates and make this class immutable after construction. Concurrency would be allowed by design. There are downsides (eg, how do implementors maintain efficient caching?) not to mention additional complexities of implementing and managing IProcessor factories... just a though, for if/when concurrent caching is needed
[Expand]
Inherited Constants | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
![]() |
Fields | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
protected int | defaultMode | ||||||||||
protected int | mode | ||||||||||
protected Collection<Integer> | supportedModes | ||||||||||
protected Collection<ProcessorVariant> | supportedVariants | ||||||||||
protected ProcessorVariant | variant |
Public Constructors | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
AbstractProcessor(int parseCacheLength, int defaultMode, Endianness endianness, int instructionAlign)
Create a processor.
| |||||||||||
AbstractProcessor(int parseCacheLength, int defaultMode, IUnitCreator parent, int instructionAlign) | |||||||||||
AbstractProcessor(int parseCacheLength, int defaultMode, IUnitCreator parent, int instructionAlign, int parseBufferBefore)
Create a processor, retrieving Endianness from parent
IUnitCreator . |
Public Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
boolean |
clearInstructionCache()
Clear the instruction cache, if this processed uses one.
| ||||||||||
EntryPointDescription |
createEntryPoint(long address, int defaultMode)
Create an entry-point from a provided native address.
| ||||||||||
EntryPointDescription |
createEntryPoint(long address)
The default implementation creates an entry-point using the exact provided address, with a
default processor mode.
| ||||||||||
final int |
getDefaultMode()
Get the default processor mode.
| ||||||||||
final Endianness |
getEndianness()
Get the endianness this processor operates in.
| ||||||||||
int |
getGPRegisterBitsize()
Retrieve the size of a General Purpose register, in bits.
| ||||||||||
final int |
getInstructionAlignment()
Retrieve the instruction alignment, in bytes.
| ||||||||||
int | getInstructionAlignmentMask() | ||||||||||
final int |
getMode()
Get the processor mode.
| ||||||||||
int |
getPCRegisterBitsize()
Retrieve the size of the Program Counter register, in bits.
| ||||||||||
IRegisterBank |
getRegisterBank()
The default implementation attempts to find an appropriate hard-coded bank (from
getType() ) using RegisterUtil . | ||||||||||
String |
getRegisterName(long registerCode)
The default implementation attempts to find a name using
getRegisterBank() . | ||||||||||
ICodeResolver<InsnType> |
getResolver()
The default implementation returns null.
| ||||||||||
Collection<Integer> |
getSupportedModes()
Get the list of valid modes that this processor supports.
| ||||||||||
Collection<ProcessorVariant> |
getSupportedVariants()
Retrieve a list of supported processor variants.
| ||||||||||
ProcessorType |
getType()
The default implementation returns
UNKNOWN . | ||||||||||
ProcessorVariant |
getVariant()
Get the processor variant used by this object.
| ||||||||||
boolean |
isRISC()
The default implementation returns false (i.e.
| ||||||||||
final InsnType |
parseAt(byte[] bytes, int index, int end)
Parse a single instruction.
| ||||||||||
InsnType |
parseAt(IVirtualMemory vm, long address)
Parse a single instruction at the specified address in memory.
| ||||||||||
InsnType |
parseWithContext(IMachineContext context)
Parse a single instruction given a machine context.
| ||||||||||
final void |
setEndianness(Endianness endianness)
Set the endianness of this processor.
| ||||||||||
final void |
setInstructionAlignment(int align)
Set the instruction alignment, in bytes.
| ||||||||||
int |
setMode(int newMode)
Set the processor mode.
| ||||||||||
void |
setVariant(ProcessorVariant variant)
Set the new variant used by this processor.
|
Protected Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
abstract InsnType |
parseAtInternal(byte[] bytes, int index, int end)
Decode bytes as instructions.
| ||||||||||
InsnType |
parseWithContextInternal(IMachineContext context)
The default implementation throws UnsupportedOperationException.@return
| ||||||||||
final void |
setDefaultMode(int defaultMode)
Set the default mode.
|
[Expand]
Inherited Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
![]() | |||||||||||
![]() |
Create a processor.
Create a processor, retrieving Endianness from parent IUnitCreator
. If the endianness
cannot be retrieved, default little-endian will be used.
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]
|
Clear the instruction cache, if this processed uses one.
The default implementation does nothing.
Create an entry-point from a provided native address.
address | address of the instruction |
---|---|
defaultMode | default processor mode if it cannot be determined by address |
The default implementation creates an entry-point using the exact provided address, with a default processor mode.
address | address of the instruction |
---|
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).
MODE_DEFAULT
(0)
Retrieve the size of a General Purpose register, in bits.
Retrieve the instruction alignment, in bytes.
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.
MODE_DEFAULT
(0)
Retrieve the size of the Program Counter register, in bits.
The default implementation attempts to find an appropriate hard-coded bank (from
getType()
) using RegisterUtil
.
The default implementation attempts to find a name using getRegisterBank()
.
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 |
---|
The default implementation returns null. Careful, access to this object is subject to locking.
Get the list of valid modes that this processor supports.
Retrieve a list of supported processor variants.
The default implementation returns UNKNOWN
. Most implementation will
want to override this default and return a proper processor type.
The default implementation returns false (i.e. assume the processor is not RISC unless explicitly specified).
Parse a single instruction.
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 |
ProcessorException |
---|
Parse a single instruction at the specified address in memory.
vm | the input virtual memory |
---|---|
address | the address to read at, with permission of read+write |
ProcessorException |
---|
Parse a single instruction given a machine context. The context provides access to at least:
ProcessorException |
---|
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
.
align | the alignment, must be a strictly positive power of 2 |
---|
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.
newMode | the mode, the value MODE_DEFAULT (0) can be provided to revert to the
default processor mode |
---|
ProcessorException |
---|
Set the new variant used by this processor.
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.@return
ProcessorException |
---|
The default implementation throws UnsupportedOperationException.@return
ProcessorException |
---|
Set the default mode. Only for implementors. This method is and should be called just once (at construction time).
defaultMode | the default processor mode, cannot be 0 |
---|