mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 12:00:04 +02:00
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:
commit
ad1af902bd
251 changed files with 5550 additions and 7982 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) & masks[i]) {
|
||||
* return false;
|
||||
* }
|
||||
* }
|
||||
* return false;
|
||||
* for(int i=0;i<bytes.length;i++) { if (bytes[i] != memory.getByte(addr+i) & 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<>();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue