Class AssemblyPatternBlock

java.lang.Object
ghidra.app.plugin.assembler.sleigh.sem.AssemblyPatternBlock
All Implemented Interfaces:
Comparable<AssemblyPatternBlock>

public class AssemblyPatternBlock extends Object implements Comparable<AssemblyPatternBlock>
The analog of PatternBlock, designed for use by the assembler

It is suitable for the assembler because it is represented byte-by-byte, and it offers a number of useful conversions and operations.

TODO: A lot of this could probably be factored into the PatternBlock class, but it was best to experiment in another class altogether to avoid breaking things.

  • Field Details

  • Constructor Details

    • AssemblyPatternBlock

      protected AssemblyPatternBlock(int offset, byte[] mask, byte[] vals)
      Construct a new pattern block with the given mask, values, and offset
      Parameters:
      offset - an offset (0-up, left-to-right) where the pattern actually starts
      mask - a mask: only 1 bits are included in the pattern
      vals - the value, excluding corresponding 0 bits in the mask
    • AssemblyPatternBlock

      protected AssemblyPatternBlock(int offset, int capacity)
      Construct a new empty pattern block at the given offset, prepared with the given capacity
      Parameters:
      offset - an offset (0-up, left-to-right) where the pattern will start
      capacity - the space to allocate for the mask and values
  • Method Details

    • nop

      public static AssemblyPatternBlock nop()
      Get an empty pattern block
      Returns:
      the pattern block
    • fromBytes

      public static AssemblyPatternBlock fromBytes(int offset, byte[] vals)
      Get a pattern block with the given (fully-included) values at the given offset
      Parameters:
      offset - the offset (0-up, left-to-right)
      vals - the values
      Returns:
      a pattern block (having a full mask)
    • fromString

      public static AssemblyPatternBlock fromString(String str)
      Convert a string representation to a pattern block
      Parameters:
      str - the string to convert
      Returns:
      the resulting pattern block
      See Also:
    • fromPattern

      public static AssemblyPatternBlock fromPattern(DisjointPattern pat, int minLen, boolean context)
      Convert a block from a disjoint pattern into an assembly pattern block
      Parameters:
      pat - the pattern to convert
      minLen - the minimum byte length of the block
      context - true to select the context block, false to select the instruction block
      Returns:
      the converted pattern block
    • fromTokenField

      public static AssemblyPatternBlock fromTokenField(TokenField tf, MaskedLong val)
      Encode the given masked long into a pattern block as specified by a given token field
      Parameters:
      tf - the token field specifying the location of the value to encode
      val - the value to encode
      Returns:
      the pattern block with the encoded value
    • fromContextField

      public static AssemblyPatternBlock fromContextField(ContextField cf, MaskedLong val)
      Encode the given masked long into a pattern block as specified by a given context field
      Parameters:
      cf - the context field specifying the location of the value to encode
      val - the value to encode
      Returns:
      the pattern block with the encoded value
    • fromRegisterValue

      public static AssemblyPatternBlock fromRegisterValue(RegisterValue rv)
      Convert a register value into a pattern block

      This is used primarily to compute default context register values, and pass them into an assembler.

      Parameters:
      rv - the register value
      Returns:
      the pattern block
    • fromLength

      public static AssemblyPatternBlock fromLength(int length)
      Allocate a fully-undefined pattern block of the given length
      Parameters:
      length - the length in bytes
      Returns:
      the block of all unknown bits
    • copy

      public AssemblyPatternBlock copy()
      Duplicate this pattern block
      Returns:
      the duplicate
    • length

      public int length()
      Get the length (plus the offset) of this pattern block
      Returns:
      the total length
    • shift

      public AssemblyPatternBlock shift(int amt)
      Shift, i.e., increase the offset of, this pattern block
      Parameters:
      amt - the amount to shift right
      Returns:
      the shifted pattern block
    • truncate

      public AssemblyPatternBlock truncate(int amt)
      Truncate (unshift) this pattern block by removing bytes from the left
      Parameters:
      amt - the amount to truncate or shift left
      Returns:
      the truncated pattern block
    • combine

      Combine this pattern block with another given block

      Two blocks can be combined in their corresponding defined bits agree. When blocks are combined, their bytes are aligned according to their shifts, and the defined bits are taken from either block. If neither block defines a bit (i.e., the mask bit at that position is 0 for both input blocks, then the output has an undefined bit in the corresponding position. If both blocks define the bit, but they have opposite values, then the result is an error.

      Parameters:
      that - the other block
      Returns:
      the new combined block, or null if the blocks disagree for any bit
    • toString

      public String toString()
      Overrides:
      toString in class Object
    • hashCode

      public int hashCode()
      Overrides:
      hashCode in class Object
    • equals

      public boolean equals(Object obj)
      Overrides:
      equals in class Object
    • compareTo

      public int compareTo(AssemblyPatternBlock that)
      Specified by:
      compareTo in interface Comparable<AssemblyPatternBlock>
    • checkRead

      protected static int checkRead(byte[] arr, int idx, int def)
      Read an array, returning a default if the index is out of bounds
      Parameters:
      arr - the array to read
      idx - the index
      def - the default value
      Returns:
      the read value
    • writeContextOp

      public AssemblyPatternBlock writeContextOp(ContextOp cop, MaskedLong val)
      Encode the given value into a copy of this pattern block as specified by a context operation

      NOTE: this method is given as a special operation, instead of a conversion factory method, because this is a write operation, not a combine operation. As such, the bits (including undefined bits) replace the bits in the existing pattern block. Were this a conversion method, we would lose the distinction between unknown bits being written, and bits whose values are simply not included in the write.

      Parameters:
      cop - the context operation specifying the location of the value to encode
      val - the value to encode
      Returns:
      the new copy with the encoded value
    • readContextOp

      public MaskedLong readContextOp(ContextOp cop)
      Read the input of a context operation from this pattern block
      Parameters:
      cop - the context operation
      Returns:
      the decoded input, as a masked value
    • maskOut

      public AssemblyPatternBlock maskOut(ContextOp cop)
      Set all bits read by a given context operation to unknown

      This is used during resolution to remove a context requirement passed upward by a child. When a parent constructor writes the required value to the context register, that requirement need not be passed further upward, since the write satisfies the requirement.

      Parameters:
      cop - the context operation
      Returns:
      the result
    • maskOut

      Set all bits that are known (1 in mask) in other to unknown.

      Other must have the same or shorter length than this.

      Parameters:
      other - the other pattern block whose mask bits are examined
      Returns:
      a copy of this pattern with mask bits set to unknown
    • trim

      public AssemblyPatternBlock trim()
      Remove all unknown bits from both left and right
      Returns:
      new value without any left or right unknown bits (but may have unknown bits in the middle)
    • getValsAll

      public byte[] getValsAll()
      Get an array representing the full value of the pattern

      This is a copy of the getVals() array, but with 0s prepended to apply the offset. See getOffset().

      Returns:
      the array
    • getMaskAll

      public byte[] getMaskAll()
      Get an array representing the full mask of the pattern

      This is a copy of the getMask() array, but with 0s prepended to apply the offset. See getOffset().

      Returns:
      the array
    • getVals

      public byte[] getVals()
      Get the values array

      Modifications to the returned array will affect the pattern block. It is not a copy. Furthermore, the offset is not incorporated. See getOffset(). For a copy of the array with offset applied, use getValsAll().

      Returns:
      the array
    • getMask

      public byte[] getMask()
      Get the mask array

      Modifications to the returned array will affect the pattern block. It is not a copy. Furthermore, the offset is not incorporated. See getOffset(). For a copy of the array with offset applied, use getMaskAll().

      Returns:
      the array
    • getMaskedValue

      public AssemblyPatternBlock getMaskedValue(byte[] unmasked)
      Mask the given unmasked value with the mask contained in this pattern block.

      The returned AssemblyPatternBlock has an identical mask as this but with a value taken from the given unmasked.

      Parameters:
      unmasked - the value to be masked into the result
      Returns:
      a combination of the given unmasked value and this mask
    • getOffset

      public int getOffset()
      Get the number of undefined bytes preceding the mask and values arrays
      Returns:
      the offset
    • readValBytes

      public long readValBytes(int start, int len)
      Decode len value bytes in big-endian format, beginning at start
      Parameters:
      start - the first byte to decode
      len - the number of bytes to decode
      Returns:
      the decoded long
    • readMaskBytes

      public long readMaskBytes(int start, int len)
      Decode len mask bytes in big-endian format, beginning at start
      Parameters:
      start - the first byte to decode
      len - the number of bytes to decode
      Returns:
      the decoded long
    • readBytes

      public MaskedLong readBytes(int start, int len)
      Decode len bytes (values and mask) in big-endian format, beginning at start
      Parameters:
      start - the first byte to decode
      len - the number of bytes to decode
      Returns:
      the decoded masked long
    • fillMask

      public AssemblyPatternBlock fillMask()
      Fill all unknown bits with 0 bits
      Returns:
      the result
    • isFullMask

      public boolean isFullMask()
      Check if there are any unknown bits
      Returns:
      true if no unknown bits are present, false otherwise
    • isZero

      public boolean isZero()
      Check if all bits are 0 bits
      Returns:
      true if all are 0, false otherwise
    • toBigInteger

      public BigInteger toBigInteger(int n)
      Decode the values array into a BigInteger of length n bytes

      The array is either truncated or zero-extended on the right to match the requested number of bytes, then decoded in big-endian format as an unsigned value.

      Parameters:
      n - the number of bytes (left-to-right) to decode
      Returns:
      the decoded big integer
    • getSpecificity

      public int getSpecificity()
      Counts the total number of known bits in the pattern

      At a slightly lower level, counts the number of 1-bits in the mask.

      Returns:
      the count
    • countPossibleVals

      public int countPossibleVals()
    • possibleVals

      public Iterable<byte[]> possibleVals()
      Get an iterable over all the possible fillings of the value, given a partial mask

      This is meant to be used idiomatically, as in an enhanced for loop:

       for (byte[] val : pattern.possibleVals()) {
              System.out.println(format(val));
       }
       

      NOTE: A single byte array is instantiated with the call to Iterable.iterator(). Each call to Iterator.next() modifies the one byte array and returns it. As such, if you intend to preserve the value in the array for later use, you must make a copy.

      Returns:
      the iterable.