Merge remote-tracking branch 'origin/Ghidra_10.1'

Conflicts:
	Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerStaticMappingService.java
	Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/SleighAssembler.java
This commit is contained in:
Ryan Kurtz 2021-11-30 10:51:40 -05:00
commit ad1af902bd
251 changed files with 5550 additions and 7982 deletions

View file

@ -49,7 +49,6 @@ public class SleighAssembler implements Assembler {
protected Program program;
protected Listing listing;
protected Memory memory;
protected Disassembler dis;
protected AssemblyParser parser;
protected AssemblyDefaultContext defaultContext;
protected AssemblyContextGraph ctxGraph;
@ -71,8 +70,6 @@ public class SleighAssembler implements Assembler {
this.listing = program.getListing();
this.memory = program.getMemory();
this.dis = Disassembler.getDisassembler(program, TaskMonitor.DUMMY,
DisassemblerMessageListener.IGNORE);
}
/**
@ -114,6 +111,10 @@ public class SleighAssembler implements Assembler {
listing.clearCodeUnits(at, end, false);
memory.setBytes(at, insbytes);
AddressSet set = new AddressSet(at, end);
// Creating this at construction causes it to assess memory flags too early.
Disassembler dis = Disassembler.getDisassembler(program, TaskMonitor.DUMMY,
DisassemblerMessageListener.IGNORE);
dis.disassemble(at, set);
return listing.getInstructions(set, true);
}

View file

@ -46,9 +46,10 @@ public class AssemblyConstructorSemantic implements Comparable<AssemblyConstruct
/**
* Build a new SLEIGH constructor semantic
*
* @param cons the SLEIGH constructor
* @param indices the indices of RHS non-terminals in the associated production that represent an
* operand in the SLEIGH constructor
* @param indices the indices of RHS non-terminals in the associated production that represent
* an operand in the SLEIGH constructor
*/
public AssemblyConstructorSemantic(Constructor cons, List<Integer> indices) {
this.cons = cons;
@ -73,6 +74,7 @@ public class AssemblyConstructorSemantic implements Comparable<AssemblyConstruct
/**
* Get the SLEIGH constructor
*
* @return the constructor
*/
public Constructor getConstructor() {
@ -81,6 +83,7 @@ public class AssemblyConstructorSemantic implements Comparable<AssemblyConstruct
/**
* Get the associated encoding patterns for the constructor
*
* @return the patterns
*/
public Collection<AssemblyResolvedConstructor> getPatterns() {
@ -92,6 +95,7 @@ public class AssemblyConstructorSemantic implements Comparable<AssemblyConstruct
/**
* Convert the index of a print piece to its associated operand index
*
* @param printpos position excluding whitespace and string tokens.
* @return the operand index
*/
@ -101,6 +105,7 @@ public class AssemblyConstructorSemantic implements Comparable<AssemblyConstruct
/**
* Get the list of operand indices in print piece order
*
* @return the list
*/
public List<Integer> getOperandIndices() {
@ -111,8 +116,9 @@ public class AssemblyConstructorSemantic implements Comparable<AssemblyConstruct
* Get an iterator over the operand indices
*
* If this iterator is advanced for each non-terminal, while simultaneously iterating over the
* RHS of the associated production, then this will identify the corresponding operand index
* for each non-terminal
* RHS of the associated production, then this will identify the corresponding operand index for
* each non-terminal
*
* @return the iterator
*/
public Iterator<Integer> getOperandIndexIterator() {
@ -142,17 +148,17 @@ public class AssemblyConstructorSemantic implements Comparable<AssemblyConstruct
* than ("specializes") another, i.e., it matches on more bits than another pattern, the more
* specific pattern is chosen. Second, if the two are equally special, then the one that occurs
* first in the SLEIGH specification is taken. So, during resolution, if a less-special or
* later-occurring constructor is chosen, we must prevent continued resolution from matching
* the more-special or earlier-occurring pattern(s).
* later-occurring constructor is chosen, we must prevent continued resolution from matching the
* more-special or earlier-occurring pattern(s).
*
* Essentially, this states, "you may choose any value matching my pattern, except those that
* match these forbidden patterns."
*
* This takes a given pattern, and searches the rest of the language for any patterns that
* would take precedence, and combines them as forbidden patterns with the given pattern.
* This takes a given pattern, and searches the rest of the language for any patterns that would
* take precedence, and combines them as forbidden patterns with the given pattern.
*
* @param pat the given pattern
* @return the same pattern with forbidden records added
* @return the same pattern with forbidden records added
*/
protected AssemblyResolvedConstructor withComputedForbids(AssemblyResolvedConstructor pat) {
// Forbid anything more specific (or otherwise takes precedence) over me.
@ -194,7 +200,7 @@ public class AssemblyConstructorSemantic implements Comparable<AssemblyConstruct
// OK, they overlap. Let's see if its a strict subset
if (comb.bitsEqual(sibpat)) {
forbids.add(sibpat.withDescription(
cons + " forbids " + sibcons + " by pattern specificity"));
sibcons + " forbids " + cons + " by pattern specificity"));
return CONTINUE;
}
else if (comb.bitsEqual(pat)) {
@ -205,7 +211,7 @@ public class AssemblyConstructorSemantic implements Comparable<AssemblyConstruct
// Finally, check the line number
if (sibcons.getId() < cons.getId()) {
forbids.add(
sibpat.withDescription(cons + " forbids " + sibcons + " by rule position"));
sibpat.withDescription(sibcons + " forbids " + cons + " by rule position"));
return CONTINUE;
}
@ -219,22 +225,24 @@ public class AssemblyConstructorSemantic implements Comparable<AssemblyConstruct
/**
* Solve this constructor's context changes
*
* @param res the combined resolution requirements derived from the subconstructors
* @param vals any defined symbols (usually {@code inst_start}, and {@code inst_next})
* @param opvals a map from operand index to operand value
* @return the resolution with context changes applied in reverse, or an error
*
* Each value in {@code opvals} must either be a numeric value, e.g., an index from a varnode
* list, or another {@link AssemblyResolvedConstructor} for a subconstructor operand.
* Each value in {@code opvals} must either be a numeric value, e.g., an index from a
* varnode list, or another {@link AssemblyResolvedConstructor} for a subconstructor
* operand.
*
* It's helpful to think of the SLEIGH disassembly process here. Normally, once the appropriate
* constructor has been identified (by matching patterns), its context changes are applied, and
* then its operands parsed (possibly parsing subconstructor operands). Thus, {@code res} can
* be thought of as the intermediate result between applying context changes and parsing
* operands, except in reverse. The output of this method corresponds to the state before
* context changes were applied, i.e., immediately after selecting the constructor. Thus, in
* reverse, the context is solved immediately before applying the selected constructor
* patterns.
* It's helpful to think of the SLEIGH disassembly process here. Normally, once the
* appropriate constructor has been identified (by matching patterns), its context
* changes are applied, and then its operands parsed (possibly parsing subconstructor
* operands). Thus, {@code res} can be thought of as the intermediate result between
* applying context changes and parsing operands, except in reverse. The output of this
* method corresponds to the state before context changes were applied, i.e.,
* immediately after selecting the constructor. Thus, in reverse, the context is solved
* immediately before applying the selected constructor patterns.
*
* @see AssemblyTreeResolver#resolveSelectedChildren(AssemblyProduction, List, List, Collection)
*/
@ -300,10 +308,11 @@ public class AssemblyConstructorSemantic implements Comparable<AssemblyConstruct
* @param outer the state before context changes
* @return the state after context changes
*
* Unlike the usual disassembly process, this method does not take into account any information
* from the instruction encoding. Any context bits that depend on it are set to unknown
* ({@code x}) in the output. This method is used to pre-compute a context transition graph in
* order to quickly resolve purely-recursive semantics on the root constructor table.
* Unlike the usual disassembly process, this method does not take into account any
* information from the instruction encoding. Any context bits that depend on it are set
* to unknown ({@code x}) in the output. This method is used to pre-compute a context
* transition graph in order to quickly resolve purely-recursive semantics on the root
* constructor table.
*/
public AssemblyResolvedConstructor applyForward(AssemblyResolvedConstructor outer) {
AssemblyResolvedConstructor res = outer;

View file

@ -75,6 +75,7 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
/**
* Constructs a new MemoryMapDB
*
* @param handle the open database handle.
* @param addrMap the address map.
* @param openMode the open mode for the program.
@ -146,14 +147,16 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
}
/**
* Update the <code>allInitializedAddrSet</code> and <code>initializedLoadedAddrSet</code>
* with relevant initialized addresses from the specified memory block. If block is not
* a mapped-block and it may be a source to existing mapped-blocks then
* <code>scanAllMappedBlocksIfNeeded</code> should be passed as <code>true</code> unless
* all mapped blocks will be processed separately.
* Update the <code>allInitializedAddrSet</code> and <code>initializedLoadedAddrSet</code> with
* relevant initialized addresses from the specified memory block. If block is not a
* mapped-block and it may be a source to existing mapped-blocks then
* <code>scanAllMappedBlocksIfNeeded</code> should be passed as <code>true</code> unless all
* mapped blocks will be processed separately.
*
* @param block memory block
* @param scanAllMappedBlocksIfNeeded if true and block is initialized and not a mapped block all
* mapped blocks will be processed for possible introduction of newly initialized mapped regions.
* @param scanAllMappedBlocksIfNeeded if true and block is initialized and not a mapped block
* all mapped blocks will be processed for possible introduction of newly initialized
* mapped regions.
*/
private void addBlockAddresses(MemoryBlockDB block, boolean scanAllMappedBlocksIfNeeded) {
AddressSet blockSet = new AddressSet(block.getStart(), block.getEnd());
@ -193,11 +196,12 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
}
/**
* Update initialized address set for those mapped blocks which map onto the
* specified block which has just completed a transition of its' initialized state.
* Update initialized address set for those mapped blocks which map onto the specified block
* which has just completed a transition of its' initialized state.
*
* @param block block whose initialized state has changed
* @param isInitialized true if block transitioned from uninitialized to initialized,
* else transition is from initialized to uninitialized.
* @param isInitialized true if block transitioned from uninitialized to initialized, else
* transition is from initialized to uninitialized.
*/
private void updateMappedAddresses(MemoryBlockDB block, boolean isInitialized) {
@ -285,6 +289,7 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
/**
* Returns the address factory for the program.
*
* @return program address factory
*/
AddressFactory getAddressFactory() {
@ -293,6 +298,7 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
/**
* Returns the AddressMap from the program.
*
* @return program address map
*/
AddressMapDB getAddressMap() {
@ -331,7 +337,7 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
throw new MemoryAccessException(block.getName() + " does not contain range " +
start.toString(true) + "-" + endAddr);
}
if (block.isMapped()) {
checkMemoryWriteMappedBlock(block, start, endAddr);
}
@ -368,7 +374,7 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
mappedEndAddress =
byteMappingScheme.getMappedSourceAddress(mappedRangeMinAddr, endOffset);
}
for (MemoryBlockDB b : getBlocks(mappedStartAddress, mappedEndAddress)) {
Address minAddr = Address.min(b.getEnd(), mappedEndAddress);
Address maxAddr = Address.max(b.getStart(), mappedStartAddress);
@ -381,9 +387,9 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
throws MemoryAccessException {
// TODO: could contain uninitialized region which is illegal to write to although block.isInitialized
// may not be of much help since it reflects the first sub-block only - seems like mixing is a bad idea
checkRangeForInstructions(start, endAddr);
// Check all mapped-block address ranges which map onto the range to be modified
Collection<MemoryBlockDB> mappedBlocks = nonMappedBlock.getMappedBlocks();
if (mappedBlocks != null) {
@ -480,8 +486,9 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
}
/**
* Two blocks have been joined producing newBlock. The block which was
* eliminated can be identified using the oldBlockStartAddr.
* Two blocks have been joined producing newBlock. The block which was eliminated can be
* identified using the oldBlockStartAddr.
*
* @param newBlock new joined memory block
* @param oldBlockStartAddr original start address of affected block
*/
@ -798,6 +805,7 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
/**
* Check new block name for validity
*
* @param name new block name
* @throws IllegalArgumentException if invalid block name specified
*/
@ -1246,25 +1254,19 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
}
/**
* Tests if the memory contains a sequence of contiguous bytes that match the
* given byte array at all bit positions where the mask contains an "on" bit.
* The test will be something like
* Tests if the memory contains a sequence of contiguous bytes that match the given byte array
* at all bit positions where the mask contains an "on" bit. The test will be something like
*
* for(int i=0;i<bytes.length;i++) {
* if (bytes[i] != memory.getByte(addr+i) &amp; masks[i]) {
* return false;
* }
* }
* return false;
* for(int i=0;i<bytes.length;i++) { if (bytes[i] != memory.getByte(addr+i) &amp; masks[i]) {
* return false; } } return false;
*
* @param addr The beginning address in memory to test against.
* @param bytes the array of bytes to test for.
* @param masks the array of masks. (One for each byte in the byte array)
* @param forward if true, the matching is going forward, otherwise backward
*
* @return 1 if there is a match
* 0 if there is no match
* -i if no match is found, this is the number of bytes that can be safely skipped
* @return 1 if there is a match 0 if there is no match -i if no match is found, this is the
* number of bytes that can be safely skipped
*/
private int match(Address addr, byte[] bytes, byte[] masks, byte[] data, boolean forward) {
try {
@ -1645,10 +1647,11 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
throw new MemoryAccessException(
"Address " + addr.toString(true) + " does not exist in memory");
}
n -= block.getSize() - addr.subtract(block.getStart());
if (n <= 0) {
long advanced = block.getSize() - addr.subtract(block.getStart());
if (advanced >= n) {
break;
}
n -= advanced;
try {
addr = block.getEnd().addNoWrap(1);
}
@ -1879,8 +1882,9 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
}
/**
* Tests if the given addressSpace (overlay space) is used by any blocks. If not, it
* removes the space.
* Tests if the given addressSpace (overlay space) is used by any blocks. If not, it removes the
* space.
*
* @param addressSpace overlay address space to be removed
*/
private void checkRemoveAddressSpace(AddressSpace addressSpace) {
@ -1930,8 +1934,8 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
}
/**
* Gets the intersected set of addresses between a mapped memory block, and some other
* address set.
* Gets the intersected set of addresses between a mapped memory block, and some other address
* set.
*
* @param mappedBlock The mapped memory block to use in the intersection.
* @param set Some other address set to use in the intersection.
@ -1954,9 +1958,10 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
}
/**
* Converts the given address range back from the source range back to the mapped range.
* NOTE: It is important that the specified mappedSourceRange is restricted to the
* mapped source area of the specified mappedBlock.
* Converts the given address range back from the source range back to the mapped range. NOTE:
* It is important that the specified mappedSourceRange is restricted to the mapped source area
* of the specified mappedBlock.
*
* @param mappedBlock mapped memory block
* @param mappedSourceRange source range which maps into mappedBlock.
* @return mapped range or null if source range not mapped to block
@ -2225,9 +2230,10 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
/**
* Returns a list of all memory blocks that contain any addresses in the given range
*
* @param start the start address
* @param end the end address
* @return a list of all memory blocks that contain any addresses in the given range
* @return a list of all memory blocks that contain any addresses in the given range
*/
List<MemoryBlockDB> getBlocks(Address start, Address end) {
List<MemoryBlockDB> list = new ArrayList<>();