mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-28 17:11:11 -09:00
Merge remote-tracking branch
'origin/GP-4712_emteere_PR-6650_sad-dev_ParallelPerf' (Closes #6650, Closes #6649, #2791)
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -16,19 +15,19 @@
|
|||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.processors.sleigh;
|
package ghidra.app.plugin.processors.sleigh;
|
||||||
|
|
||||||
import ghidra.program.model.address.Address;
|
|
||||||
import ghidra.program.model.lang.*;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import generic.stl.Pair;
|
||||||
|
import ghidra.program.model.address.Address;
|
||||||
|
import ghidra.program.model.lang.*;
|
||||||
|
|
||||||
public class ContextCache {
|
public class ContextCache {
|
||||||
private int context_size = 0;
|
private int context_size = 0;
|
||||||
private Register contextBaseRegister = null;
|
private Register contextBaseRegister = null;
|
||||||
|
|
||||||
private BigInteger lastContextValue;
|
Pair <BigInteger, int []> lastValue = null;
|
||||||
private int[] lastContextWords;
|
|
||||||
|
|
||||||
public ContextCache() {
|
public ContextCache() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,12 +56,15 @@ public class ContextCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized int[] getWords(BigInteger value) {
|
private int[] getWords(BigInteger value) {
|
||||||
if (value.equals(lastContextValue)) {
|
|
||||||
return lastContextWords;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Pair <BigInteger, int []> lastValueTmp = lastValue;
|
||||||
|
if (lastValueTmp != null && value.equals(lastValueTmp.first)) {
|
||||||
|
return lastValueTmp.second;
|
||||||
|
}
|
||||||
|
|
||||||
int[] words = new int[context_size];
|
int[] words = new int[context_size];
|
||||||
|
|
||||||
byte[] bytes = value.toByteArray();
|
byte[] bytes = value.toByteArray();
|
||||||
int byteIndexDiff = context_size * 4 - bytes.length;
|
int byteIndexDiff = context_size * 4 - bytes.length;
|
||||||
for (int i = 0; i < context_size; i++) {
|
for (int i = 0; i < context_size; i++) {
|
||||||
@@ -73,8 +75,10 @@ public class ContextCache {
|
|||||||
}
|
}
|
||||||
words[i] = word;
|
words[i] = word;
|
||||||
}
|
}
|
||||||
lastContextValue = value;
|
|
||||||
lastContextWords = words;
|
lastValueTmp = new Pair<BigInteger, int[]>(value, words);
|
||||||
|
lastValue = lastValueTmp;
|
||||||
|
|
||||||
return words;
|
return words;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import static ghidra.pcode.utils.SlaFormat.*;
|
|||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
@@ -88,7 +89,7 @@ public class SleighLanguage implements Language {
|
|||||||
/**
|
/**
|
||||||
* Cached instruction prototypes
|
* Cached instruction prototypes
|
||||||
*/
|
*/
|
||||||
private LinkedHashMap<Integer, SleighInstructionPrototype> instructProtoMap;
|
private ConcurrentHashMap<Integer, SleighInstructionPrototype> instructProtoMap;
|
||||||
private DecisionNode root = null;
|
private DecisionNode root = null;
|
||||||
/**
|
/**
|
||||||
* table of AddressSpaces
|
* table of AddressSpaces
|
||||||
@@ -148,7 +149,7 @@ public class SleighLanguage implements Language {
|
|||||||
buildVolatileSymbolAddresses();
|
buildVolatileSymbolAddresses();
|
||||||
xrefRegisters();
|
xrefRegisters();
|
||||||
|
|
||||||
instructProtoMap = new LinkedHashMap<>();
|
instructProtoMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
initParallelHelper();
|
initParallelHelper();
|
||||||
}
|
}
|
||||||
@@ -374,20 +375,15 @@ public class SleighLanguage implements Language {
|
|||||||
new SleighInstructionPrototype(this, buf, context, contextcache, inDelaySlot, null);
|
new SleighInstructionPrototype(this, buf, context, contextcache, inDelaySlot, null);
|
||||||
Integer hashcode = newProto.hashCode();
|
Integer hashcode = newProto.hashCode();
|
||||||
|
|
||||||
if (!instructProtoMap.containsKey(hashcode)) {
|
// get existing proto and use it
|
||||||
newProto.cacheInfo(buf, context, true);
|
// if doesn't exist in map, cache info and store new proto
|
||||||
}
|
res = instructProtoMap.computeIfAbsent(hashcode, h -> {
|
||||||
|
newProto.cacheInfo(buf, context, true);
|
||||||
synchronized (instructProtoMap) {
|
return newProto;
|
||||||
res = instructProtoMap.get(hashcode);
|
});
|
||||||
if (res == null) { // We have a prototype we have never seen
|
|
||||||
// before, build it fully
|
if (inDelaySlot && res.hasDelaySlots()) {
|
||||||
instructProtoMap.put(hashcode, newProto);
|
throw new NestedDelaySlotException();
|
||||||
res = newProto;
|
|
||||||
}
|
|
||||||
if (inDelaySlot && res.hasDelaySlots()) {
|
|
||||||
throw new NestedDelaySlotException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (MemoryAccessException e) {
|
catch (MemoryAccessException e) {
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ public class HighFunction extends PcodeSyntaxTree {
|
|||||||
private GlobalSymbolMap globalSymbols;
|
private GlobalSymbolMap globalSymbols;
|
||||||
private List<JumpTable> jumpTables;
|
private List<JumpTable> jumpTables;
|
||||||
private List<DataTypeSymbol> protoOverrides;
|
private List<DataTypeSymbol> protoOverrides;
|
||||||
|
private Address entryPoint;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param function function associated with the higher level function abstraction.
|
* @param function function associated with the higher level function abstraction.
|
||||||
@@ -64,6 +65,7 @@ public class HighFunction extends PcodeSyntaxTree {
|
|||||||
this.language = language;
|
this.language = language;
|
||||||
this.compilerSpec = compilerSpec;
|
this.compilerSpec = compilerSpec;
|
||||||
AddressSpace stackSpace = function.getProgram().getAddressFactory().getStackSpace();
|
AddressSpace stackSpace = function.getProgram().getAddressFactory().getStackSpace();
|
||||||
|
entryPoint = function.getEntryPoint();
|
||||||
localSymbols = new LocalSymbolMap(this, stackSpace);
|
localSymbols = new LocalSymbolMap(this, stackSpace);
|
||||||
globalSymbols = new GlobalSymbolMap(this);
|
globalSymbols = new GlobalSymbolMap(this);
|
||||||
proto = new FunctionPrototype(localSymbols, function);
|
proto = new FunctionPrototype(localSymbols, function);
|
||||||
@@ -87,7 +89,7 @@ public class HighFunction extends PcodeSyntaxTree {
|
|||||||
if (func instanceof FunctionDB) {
|
if (func instanceof FunctionDB) {
|
||||||
return func.getSymbol().getID();
|
return func.getSymbol().getID();
|
||||||
}
|
}
|
||||||
return func.getProgram().getSymbolTable().getDynamicSymbolID(func.getEntryPoint());
|
return func.getProgram().getSymbolTable().getDynamicSymbolID(entryPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -255,7 +257,7 @@ public class HighFunction extends PcodeSyntaxTree {
|
|||||||
}
|
}
|
||||||
if (subel == ELEM_ADDR.id()) {
|
if (subel == ELEM_ADDR.id()) {
|
||||||
Address addr = AddressXML.decode(decoder);
|
Address addr = AddressXML.decode(decoder);
|
||||||
if (!func.getEntryPoint().equals(addr)) {
|
if (!entryPoint.equals(addr)) {
|
||||||
throw new DecoderException("Mismatched address in function tag");
|
throw new DecoderException("Mismatched address in function tag");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -300,7 +302,7 @@ public class HighFunction extends PcodeSyntaxTree {
|
|||||||
private void decodeJumpTableList(Decoder decoder) throws DecoderException {
|
private void decodeJumpTableList(Decoder decoder) throws DecoderException {
|
||||||
int el = decoder.openElement(ELEM_JUMPTABLELIST);
|
int el = decoder.openElement(ELEM_JUMPTABLELIST);
|
||||||
while (decoder.peekElement() != 0) {
|
while (decoder.peekElement() != 0) {
|
||||||
JumpTable table = new JumpTable(func.getEntryPoint().getAddressSpace());
|
JumpTable table = new JumpTable(entryPoint.getAddressSpace());
|
||||||
table.decode(decoder);
|
table.decode(decoder);
|
||||||
if (!table.isEmpty()) {
|
if (!table.isEmpty()) {
|
||||||
if (jumpTables == null) {
|
if (jumpTables == null) {
|
||||||
@@ -318,10 +320,10 @@ public class HighFunction extends PcodeSyntaxTree {
|
|||||||
pcaddr = rep.getPCAddress();
|
pcaddr = rep.getPCAddress();
|
||||||
if (pcaddr == Address.NO_ADDRESS) {
|
if (pcaddr == Address.NO_ADDRESS) {
|
||||||
try {
|
try {
|
||||||
pcaddr = func.getEntryPoint().add(-1);
|
pcaddr = entryPoint.add(-1);
|
||||||
}
|
}
|
||||||
catch (AddressOutOfBoundsException e) {
|
catch (AddressOutOfBoundsException e) {
|
||||||
pcaddr = func.getEntryPoint();
|
pcaddr = entryPoint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -446,7 +448,7 @@ public class HighFunction extends PcodeSyntaxTree {
|
|||||||
encoder.writeBool(ATTRIB_NORETURN, true);
|
encoder.writeBool(ATTRIB_NORETURN, true);
|
||||||
}
|
}
|
||||||
if (entryPoint == null) {
|
if (entryPoint == null) {
|
||||||
AddressXML.encode(encoder, func.getEntryPoint());
|
AddressXML.encode(encoder, this.entryPoint);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
AddressXML.encode(encoder, entryPoint); // Address is forced on XML
|
AddressXML.encode(encoder, entryPoint); // Address is forced on XML
|
||||||
|
|||||||
Reference in New Issue
Block a user