mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 01:39:21 +02:00
Merge remote-tracking branch 'origin/Ghidra_12.0'
This commit is contained in:
commit
f41f7c9eab
38 changed files with 776 additions and 351 deletions
|
@ -52,7 +52,7 @@ import ghidra.util.task.TaskMonitor;
|
||||||
public abstract class AbstractDBTraceSymbol extends DBAnnotatedObject
|
public abstract class AbstractDBTraceSymbol extends DBAnnotatedObject
|
||||||
implements TraceSymbol, DecodesAddresses {
|
implements TraceSymbol, DecodesAddresses {
|
||||||
|
|
||||||
private static final byte SOURCE_MASK = 0x0F;
|
private static final byte SOURCE_MASK = 0x0F; // see SourceType
|
||||||
private static final int SOURCE_SHIFT = 0;
|
private static final int SOURCE_SHIFT = 0;
|
||||||
private static final byte SOURCE_CLEAR = ~(SOURCE_MASK << SOURCE_SHIFT);
|
private static final byte SOURCE_CLEAR = ~(SOURCE_MASK << SOURCE_SHIFT);
|
||||||
|
|
||||||
|
@ -311,7 +311,7 @@ public abstract class AbstractDBTraceSymbol extends DBAnnotatedObject
|
||||||
public DBTraceReference[] getReferences() {
|
public DBTraceReference[] getReferences() {
|
||||||
return getReferences(TaskMonitor.DUMMY);
|
return getReferences(TaskMonitor.DUMMY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("hiding")
|
@SuppressWarnings("hiding")
|
||||||
void rawSet(String name, long parentID) {
|
void rawSet(String name, long parentID) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
@ -365,8 +365,8 @@ public abstract class AbstractDBTraceSymbol extends DBAnnotatedObject
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void doSetSource(SourceType newSource) {
|
protected void doSetSource(SourceType newSource) {
|
||||||
flags =
|
flags = (byte) ((flags & SOURCE_CLEAR) |
|
||||||
(byte) ((flags & SOURCE_CLEAR) | (newSource.ordinal() & SOURCE_MASK) << SOURCE_SHIFT);
|
(newSource.getStorageId() & SOURCE_MASK) << SOURCE_SHIFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -502,7 +502,7 @@ public abstract class AbstractDBTraceSymbol extends DBAnnotatedObject
|
||||||
@Override
|
@Override
|
||||||
public SourceType getSource() {
|
public SourceType getSource() {
|
||||||
assertNotGlobal();
|
assertNotGlobal();
|
||||||
return SourceType.values()[(flags >> SOURCE_SHIFT) & SOURCE_MASK];
|
return SourceType.getSourceType((flags >> SOURCE_SHIFT) & SOURCE_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -103,14 +103,14 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
||||||
implements DecodesAddresses {
|
implements DecodesAddresses {
|
||||||
private static final String TABLE_NAME = "References";
|
private static final String TABLE_NAME = "References";
|
||||||
|
|
||||||
private static final byte SOURCE_MASK = 0x0F;
|
private static final byte SOURCE_MASK = 0x0F; // see SourceType
|
||||||
private static final byte SOURCE_SHIFT = 0;
|
private static final byte SOURCE_SHIFT = 0;
|
||||||
//private static final byte SOURCE_CLEAR = ~(SOURCE_MASK << SOURCE_SHIFT);
|
//private static final byte SOURCE_CLEAR = ~(SOURCE_MASK << SOURCE_SHIFT);
|
||||||
|
|
||||||
private static final byte PRIMARY_MASK = 0x10;
|
private static final byte PRIMARY_MASK = 0x10;
|
||||||
private static final byte PRIMARY_CLEAR = ~PRIMARY_MASK;
|
private static final byte PRIMARY_CLEAR = ~PRIMARY_MASK;
|
||||||
|
|
||||||
private static final byte TYPE_MASK = 0x3;
|
private static final byte TYPE_MASK = 0x3; // See DBTraceReferenceSpace.TypeEnum
|
||||||
private static final byte TYPE_SHIFT = 5;
|
private static final byte TYPE_SHIFT = 5;
|
||||||
//private static final byte TYPE_CLEAR = ~(TYPE_MASK << TYPE_SHIFT);
|
//private static final byte TYPE_CLEAR = ~(TYPE_MASK << TYPE_SHIFT);
|
||||||
|
|
||||||
|
@ -142,15 +142,9 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
||||||
return DBTraceUtils.tableName(TABLE_NAME, space);
|
return DBTraceUtils.tableName(TABLE_NAME, space);
|
||||||
}
|
}
|
||||||
|
|
||||||
@DBAnnotatedField(
|
@DBAnnotatedField(column = TO_ADDR_MIN_COLUMN_NAME, indexed = true, codec = AddressDBFieldCodec.class)
|
||||||
column = TO_ADDR_MIN_COLUMN_NAME,
|
|
||||||
indexed = true,
|
|
||||||
codec = AddressDBFieldCodec.class)
|
|
||||||
protected Address toAddrMin = Address.NO_ADDRESS;
|
protected Address toAddrMin = Address.NO_ADDRESS;
|
||||||
@DBAnnotatedField(
|
@DBAnnotatedField(column = TO_ADDR_MAX_COLUMN_NAME, indexed = true, codec = AddressDBFieldCodec.class)
|
||||||
column = TO_ADDR_MAX_COLUMN_NAME,
|
|
||||||
indexed = true,
|
|
||||||
codec = AddressDBFieldCodec.class)
|
|
||||||
protected Address toAddrMax = Address.NO_ADDRESS;
|
protected Address toAddrMax = Address.NO_ADDRESS;
|
||||||
@DBAnnotatedField(column = SYMBOL_ID_COLUMN_NAME, indexed = true)
|
@DBAnnotatedField(column = SYMBOL_ID_COLUMN_NAME, indexed = true)
|
||||||
protected long symbolId; // TODO: Is this at the from or to address? I think TO...
|
protected long symbolId; // TODO: Is this at the from or to address? I think TO...
|
||||||
|
@ -201,8 +195,8 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void set(AddressRange toRange, long symbolId, RefType refType,
|
protected void set(AddressRange toRange, long symbolId, RefType refType, int opIndex,
|
||||||
int opIndex, long ext, boolean isPrimary, TypeEnum type, SourceType sourceType) {
|
long ext, boolean isPrimary, TypeEnum type, SourceType sourceType) {
|
||||||
this.toAddrMin = toRange.getMinAddress();
|
this.toAddrMin = toRange.getMinAddress();
|
||||||
this.toAddrMax = toRange.getMaxAddress();
|
this.toAddrMax = toRange.getMaxAddress();
|
||||||
this.symbolId = symbolId;
|
this.symbolId = symbolId;
|
||||||
|
@ -210,7 +204,7 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
||||||
this.opIndex = (byte) opIndex;
|
this.opIndex = (byte) opIndex;
|
||||||
this.ext = ext;
|
this.ext = ext;
|
||||||
this.flags = (byte) ((isPrimary ? PRIMARY_MASK : 0) |
|
this.flags = (byte) ((isPrimary ? PRIMARY_MASK : 0) |
|
||||||
(sourceType.ordinal() << SOURCE_SHIFT) | type.ordinal() << TYPE_SHIFT);
|
(sourceType.getStorageId() << SOURCE_SHIFT) | type.ordinal() << TYPE_SHIFT);
|
||||||
update(TO_ADDR_MIN_COLUMN, TO_ADDR_MAX_COLUMN, SYMBOL_ID_COLUMN, REF_TYPE_COLUMN,
|
update(TO_ADDR_MIN_COLUMN, TO_ADDR_MAX_COLUMN, SYMBOL_ID_COLUMN, REF_TYPE_COLUMN,
|
||||||
OP_INDEX_COLUMN, EXT_COLUMN, FLAGS_COLUMN);
|
OP_INDEX_COLUMN, EXT_COLUMN, FLAGS_COLUMN);
|
||||||
|
|
||||||
|
@ -243,8 +237,8 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
||||||
TraceEvents.SYMBOL_ASSOCIATION_REMOVED, space.space, oldSymbol, ref));
|
TraceEvents.SYMBOL_ASSOCIATION_REMOVED, space.space, oldSymbol, ref));
|
||||||
}
|
}
|
||||||
if (newSymbol != null) {
|
if (newSymbol != null) {
|
||||||
space.trace.setChanged(new TraceChangeRecord<>(
|
space.trace.setChanged(new TraceChangeRecord<>(TraceEvents.SYMBOL_ASSOCIATION_ADDED,
|
||||||
TraceEvents.SYMBOL_ASSOCIATION_ADDED, space.space, newSymbol, ref));
|
space.space, newSymbol, ref));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,7 +270,7 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
||||||
}
|
}
|
||||||
|
|
||||||
public SourceType getSourceType() {
|
public SourceType getSourceType() {
|
||||||
return SourceType.values()[(flags >> SOURCE_SHIFT) & SOURCE_MASK];
|
return SourceType.getSourceType((flags >> SOURCE_SHIFT) & SOURCE_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void doDelete() {
|
protected void doDelete() {
|
||||||
|
@ -375,16 +369,15 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
||||||
referenceMapSpace.getUserIndex(long.class, DBTraceReferenceEntry.SYMBOL_ID_COLUMN);
|
referenceMapSpace.getUserIndex(long.class, DBTraceReferenceEntry.SYMBOL_ID_COLUMN);
|
||||||
|
|
||||||
this.xrefMapSpace = new DBTraceAddressSnapRangePropertyMapSpace<>(
|
this.xrefMapSpace = new DBTraceAddressSnapRangePropertyMapSpace<>(
|
||||||
DBTraceXRefEntry.tableName(space), trace, factory, lock, space,
|
DBTraceXRefEntry.tableName(space), trace, factory, lock, space, DBTraceXRefEntry.class,
|
||||||
DBTraceXRefEntry.class, (t, s, r) -> new DBTraceXRefEntry(this, t, s, r));
|
(t, s, r) -> new DBTraceXRefEntry(this, t, s, r));
|
||||||
this.xrefsByRefKey = xrefMapSpace.getUserIndex(long.class, DBTraceXRefEntry.REF_KEY_COLUMN);
|
this.xrefsByRefKey = xrefMapSpace.getUserIndex(long.class, DBTraceXRefEntry.REF_KEY_COLUMN);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void doAddXRef(DBTraceReferenceEntry refEnt) {
|
protected void doAddXRef(DBTraceReferenceEntry refEnt) {
|
||||||
// Note: called from manager on relevant space
|
// Note: called from manager on relevant space
|
||||||
DBTraceXRefEntry xrefEnt = xrefMapSpace.put(refEnt.toRange, refEnt.getLifespan(), null);
|
DBTraceXRefEntry xrefEnt = xrefMapSpace.put(refEnt.toRange, refEnt.getLifespan(), null);
|
||||||
xrefEnt.set((short) refEnt.getRange().getAddressSpace().getSpaceID(),
|
xrefEnt.set((short) refEnt.getRange().getAddressSpace().getSpaceID(), refEnt.getKey());
|
||||||
refEnt.getKey());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void doDelXRef(DBTraceReferenceEntry refEnt) {
|
protected void doDelXRef(DBTraceReferenceEntry refEnt) {
|
||||||
|
@ -451,11 +444,11 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
||||||
int operandIndex) {
|
int operandIndex) {
|
||||||
// Do I consider "compatibility?" as in ReferenceDBManager?
|
// Do I consider "compatibility?" as in ReferenceDBManager?
|
||||||
// NOTE: Always call with the write lock
|
// NOTE: Always call with the write lock
|
||||||
for (DBTraceReferenceEntry ent : referenceMapSpace.reduce(
|
for (DBTraceReferenceEntry ent : referenceMapSpace
|
||||||
TraceAddressSnapRangeQuery.intersecting(new AddressRangeImpl(fromAddress, fromAddress),
|
.reduce(TraceAddressSnapRangeQuery
|
||||||
span)).values()) {
|
.intersecting(new AddressRangeImpl(fromAddress, fromAddress), span))
|
||||||
if (!ent.toRange.equals(toRange) ||
|
.values()) {
|
||||||
ent.opIndex != operandIndex) {
|
if (!ent.toRange.equals(toRange) || ent.opIndex != operandIndex) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -585,10 +578,10 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
||||||
public DBTraceReference getReference(long snap, Address fromAddress, AddressRange toRange,
|
public DBTraceReference getReference(long snap, Address fromAddress, AddressRange toRange,
|
||||||
int operandIndex) {
|
int operandIndex) {
|
||||||
try (LockHold hold = LockHold.lock(lock.readLock())) {
|
try (LockHold hold = LockHold.lock(lock.readLock())) {
|
||||||
for (DBTraceReferenceEntry entry : referenceMapSpace.reduce(
|
for (DBTraceReferenceEntry entry : referenceMapSpace
|
||||||
TraceAddressSnapRangeQuery.at(fromAddress, snap)).values()) {
|
.reduce(TraceAddressSnapRangeQuery.at(fromAddress, snap))
|
||||||
if (!entry.toRange.equals(toRange) ||
|
.values()) {
|
||||||
entry.opIndex != operandIndex) {
|
if (!entry.toRange.equals(toRange) || entry.opIndex != operandIndex) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return entry.ref;
|
return entry.ref;
|
||||||
|
@ -641,8 +634,7 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
||||||
@Override
|
@Override
|
||||||
public Collection<? extends DBTraceReference> getFlowReferencesFrom(long snap,
|
public Collection<? extends DBTraceReference> getFlowReferencesFrom(long snap,
|
||||||
Address fromAddress) {
|
Address fromAddress) {
|
||||||
return streamReferencesFrom(snap, fromAddress)
|
return streamReferencesFrom(snap, fromAddress).filter(r -> r.getReferenceType().isFlow())
|
||||||
.filter(r -> r.getReferenceType().isFlow())
|
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -650,8 +642,9 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
||||||
public void clearReferencesFrom(Lifespan span, AddressRange range) {
|
public void clearReferencesFrom(Lifespan span, AddressRange range) {
|
||||||
try (LockHold hold = manager.getTrace().lockWrite()) {
|
try (LockHold hold = manager.getTrace().lockWrite()) {
|
||||||
long startSnap = span.lmin();
|
long startSnap = span.lmin();
|
||||||
for (DBTraceReferenceEntry ref : referenceMapSpace.reduce(
|
for (DBTraceReferenceEntry ref : referenceMapSpace
|
||||||
TraceAddressSnapRangeQuery.intersecting(range, span)).values()) {
|
.reduce(TraceAddressSnapRangeQuery.intersecting(range, span))
|
||||||
|
.values()) {
|
||||||
truncateOrDeleteEntry(ref, startSnap);
|
truncateOrDeleteEntry(ref, startSnap);
|
||||||
}
|
}
|
||||||
// TODO: Coalesce events?
|
// TODO: Coalesce events?
|
||||||
|
@ -682,21 +675,19 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
||||||
@Override
|
@Override
|
||||||
public Collection<? extends DBTraceReference> getReferencesToRange(Lifespan span,
|
public Collection<? extends DBTraceReference> getReferencesToRange(Lifespan span,
|
||||||
AddressRange range, Rectangle2DDirection order) {
|
AddressRange range, Rectangle2DDirection order) {
|
||||||
return new LazyCollection<>(
|
return new LazyCollection<>(() -> xrefMapSpace
|
||||||
() -> xrefMapSpace
|
.reduce(TraceAddressSnapRangeQuery.intersecting(range, span).starting(order))
|
||||||
.reduce(TraceAddressSnapRangeQuery.intersecting(range, span).starting(order))
|
.values()
|
||||||
.values()
|
.stream()
|
||||||
.stream()
|
.map(this::getRefForXRefEntry));
|
||||||
.map(this::getRefForXRefEntry));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void truncateOrDeleteEntry(DBTraceReferenceEntry ref, long otherStartSnap) {
|
protected void truncateOrDeleteEntry(DBTraceReferenceEntry ref, long otherStartSnap) {
|
||||||
if (ref.getLifespan().lmin() < otherStartSnap) {
|
if (ref.getLifespan().lmin() < otherStartSnap) {
|
||||||
Lifespan oldSpan = ref.getLifespan();
|
Lifespan oldSpan = ref.getLifespan();
|
||||||
ref.setEndSnap(otherStartSnap - 1);
|
ref.setEndSnap(otherStartSnap - 1);
|
||||||
trace.setChanged(new TraceChangeRecord<>(
|
trace.setChanged(new TraceChangeRecord<>(TraceEvents.REFERENCE_LIFESPAN_CHANGED, space,
|
||||||
TraceEvents.REFERENCE_LIFESPAN_CHANGED, space, ref.ref, oldSpan,
|
ref.ref, oldSpan, ref.getLifespan()));
|
||||||
ref.getLifespan()));
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ref.ref.delete();
|
ref.ref.delete();
|
||||||
|
@ -707,8 +698,9 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
||||||
public void clearReferencesTo(Lifespan span, AddressRange range) {
|
public void clearReferencesTo(Lifespan span, AddressRange range) {
|
||||||
try (LockHold hold = manager.getTrace().lockWrite()) {
|
try (LockHold hold = manager.getTrace().lockWrite()) {
|
||||||
long startSnap = span.lmin();
|
long startSnap = span.lmin();
|
||||||
for (DBTraceXRefEntry xref : xrefMapSpace.reduce(
|
for (DBTraceXRefEntry xref : xrefMapSpace
|
||||||
TraceAddressSnapRangeQuery.intersecting(range, span)).values()) {
|
.reduce(TraceAddressSnapRangeQuery.intersecting(range, span))
|
||||||
|
.values()) {
|
||||||
DBTraceReferenceEntry ref = getRefEntryForXRefEntry(xref);
|
DBTraceReferenceEntry ref = getRefEntryForXRefEntry(xref);
|
||||||
truncateOrDeleteEntry(ref, startSnap);
|
truncateOrDeleteEntry(ref, startSnap);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,8 +43,7 @@ import ghidra.program.model.symbol.*;
|
||||||
public class AutoRenameSimpleLabels extends GhidraScript {
|
public class AutoRenameSimpleLabels extends GhidraScript {
|
||||||
|
|
||||||
boolean isDefaultName(Symbol symbol) {
|
boolean isDefaultName(Symbol symbol) {
|
||||||
return symbol.getSource() == SourceType.DEFAULT ||
|
return symbol.getSource().isLowerOrEqualPriorityThan(SourceType.ANALYSIS);
|
||||||
symbol.getSource() == SourceType.ANALYSIS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -61,6 +60,9 @@ public class AutoRenameSimpleLabels extends GhidraScript {
|
||||||
//get this instruction's info
|
//get this instruction's info
|
||||||
Symbol s = iter.next();
|
Symbol s = iter.next();
|
||||||
Address startAddr = s.getAddress();
|
Address startAddr = s.getAddress();
|
||||||
|
if (!startAddr.isLoadedMemoryAddress()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// read the instruction type and operand
|
// read the instruction type and operand
|
||||||
Instruction inst = getInstructionAt(startAddr);
|
Instruction inst = getInstructionAt(startAddr);
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
* 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.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -43,13 +43,12 @@ public class LabelDataScript extends GhidraScript {
|
||||||
(!data.getBaseDataType().getName().toLowerCase().contains("string")) &&
|
(!data.getBaseDataType().getName().toLowerCase().contains("string")) &&
|
||||||
(!data.getBaseDataType().getName().toLowerCase().contains("unicode"))) {
|
(!data.getBaseDataType().getName().toLowerCase().contains("unicode"))) {
|
||||||
Symbol sym = symbolTable.getPrimarySymbol(data.getMinAddress());
|
Symbol sym = symbolTable.getPrimarySymbol(data.getMinAddress());
|
||||||
if ((sym != null) && ((sym.getSource() == SourceType.DEFAULT) ||
|
if (sym != null &&
|
||||||
(sym.getSource() == SourceType.ANALYSIS))) {
|
sym.getSource().isLowerOrEqualPriorityThan(SourceType.ANALYSIS)) {
|
||||||
String newLabel =
|
String newLabel = data.getDefaultLabelPrefix(null) +
|
||||||
data.getDefaultLabelPrefix(null) + "_" +
|
"_" + SymbolUtilities
|
||||||
SymbolUtilities.replaceInvalidChars(
|
.replaceInvalidChars(data.getDefaultValueRepresentation(), false) +
|
||||||
data.getDefaultValueRepresentation(), false) +
|
"_" + data.getMinAddress().toString();
|
||||||
"_" + data.getMinAddress().toString();
|
|
||||||
Symbol newSym = symbolTable.createLabel(data.getMinAddress(), newLabel,
|
Symbol newSym = symbolTable.createLabel(data.getMinAddress(), newLabel,
|
||||||
SourceType.ANALYSIS);
|
SourceType.ANALYSIS);
|
||||||
println(data.getMinAddress().toString() + " " + newLabel);
|
println(data.getMinAddress().toString() + " " + newLabel);
|
||||||
|
|
|
@ -448,7 +448,7 @@
|
||||||
<TD align="left" height="21" width="22%">Function</TD>
|
<TD align="left" height="21" width="22%">Function</TD>
|
||||||
|
|
||||||
<TD align="left" height="21" width="56%">Indicates the source-type associated with the
|
<TD align="left" height="21" width="56%">Indicates the source-type associated with the
|
||||||
function signature (i.e., DEFAULT, ANALYSIS, IMPORTED, USER_DEFINED).</TD>
|
function signature (i.e., DEFAULT, AI_ASSIST, ANALYSIS, IMPORTED, USER_DEFINED).</TD>
|
||||||
</TR>
|
</TR>
|
||||||
|
|
||||||
<TR>
|
<TR>
|
||||||
|
|
|
@ -44,7 +44,7 @@ public class NewFunctionStackAnalysisCmd extends BackgroundCommand<Program> {
|
||||||
private static final int MAX_LOCAL_OFFSET = -(64 * 1024); // max size of local reference space
|
private static final int MAX_LOCAL_OFFSET = -(64 * 1024); // max size of local reference space
|
||||||
|
|
||||||
private final static String X86_NAME = "x86";
|
private final static String X86_NAME = "x86";
|
||||||
|
|
||||||
private boolean dontCreateNewVariables = false;
|
private boolean dontCreateNewVariables = false;
|
||||||
|
|
||||||
private final boolean forceProcessing;
|
private final boolean forceProcessing;
|
||||||
|
@ -55,7 +55,7 @@ public class NewFunctionStackAnalysisCmd extends BackgroundCommand<Program> {
|
||||||
private Program program;
|
private Program program;
|
||||||
private Register stackReg;
|
private Register stackReg;
|
||||||
private int purge = 0;
|
private int purge = 0;
|
||||||
|
|
||||||
private boolean isX86 = false;
|
private boolean isX86 = false;
|
||||||
|
|
||||||
static String DEFAULT_FUNCTION_COMMENT = " FUNCTION";
|
static String DEFAULT_FUNCTION_COMMENT = " FUNCTION";
|
||||||
|
@ -105,7 +105,7 @@ public class NewFunctionStackAnalysisCmd extends BackgroundCommand<Program> {
|
||||||
@Override
|
@Override
|
||||||
public boolean applyTo(Program p, TaskMonitor monitor) {
|
public boolean applyTo(Program p, TaskMonitor monitor) {
|
||||||
program = p;
|
program = p;
|
||||||
|
|
||||||
isX86 = checkForX86(p);
|
isX86 = checkForX86(p);
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
@ -145,8 +145,10 @@ public class NewFunctionStackAnalysisCmd extends BackgroundCommand<Program> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkForX86(Program p) {
|
private boolean checkForX86(Program p) {
|
||||||
return program.getLanguage().getProcessor().equals(
|
return program.getLanguage()
|
||||||
Processor.findOrPossiblyCreateProcessor(X86_NAME)) && program.getDefaultPointerSize() <= 32;
|
.getProcessor()
|
||||||
|
.equals(Processor.findOrPossiblyCreateProcessor(X86_NAME)) &&
|
||||||
|
program.getDefaultPointerSize() <= 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -221,7 +223,7 @@ public class NewFunctionStackAnalysisCmd extends BackgroundCommand<Program> {
|
||||||
|
|
||||||
private boolean isProtectedVariable(Variable var) {
|
private boolean isProtectedVariable(Variable var) {
|
||||||
return !var.isStackVariable() || !Undefined.isUndefined(var.getDataType()) ||
|
return !var.isStackVariable() || !Undefined.isUndefined(var.getDataType()) ||
|
||||||
var.getSource() == SourceType.IMPORTED || var.getSource() == SourceType.USER_DEFINED ||
|
var.getSource().isHigherOrEqualPriorityThan(SourceType.IMPORTED) ||
|
||||||
var.isCompoundVariable();
|
var.isCompoundVariable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,9 +341,11 @@ public class NewFunctionStackAnalysisCmd extends BackgroundCommand<Program> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
long extendedOffset = extendOffset(address.getOffset(), stackReg.getBitLength());
|
long extendedOffset =
|
||||||
|
extendOffset(address.getOffset(), stackReg.getBitLength());
|
||||||
defineFuncVariable(symEval, func, instr, opIndex, (int) extendedOffset, sortedVariables);
|
|
||||||
|
defineFuncVariable(symEval, func, instr, opIndex, (int) extendedOffset,
|
||||||
|
sortedVariables);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -634,8 +638,8 @@ public class NewFunctionStackAnalysisCmd extends BackgroundCommand<Program> {
|
||||||
// return true;
|
// return true;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
private void defineFuncVariable(SymbolicPropogator symEval, Function func, Instruction instr, int opIndex, int stackOffset,
|
private void defineFuncVariable(SymbolicPropogator symEval, Function func, Instruction instr,
|
||||||
List<Variable> sortedVariables) {
|
int opIndex, int stackOffset, List<Variable> sortedVariables) {
|
||||||
|
|
||||||
ReferenceManager refMgr = program.getReferenceManager();
|
ReferenceManager refMgr = program.getReferenceManager();
|
||||||
int refSize = getRefSize(symEval, instr, opIndex);
|
int refSize = getRefSize(symEval, instr, opIndex);
|
||||||
|
|
|
@ -224,7 +224,7 @@ public abstract class AbstractDemanglerAnalyzer extends AbstractAnalyzer {
|
||||||
if (symbol.getSymbolType() == SymbolType.FUNCTION) {
|
if (symbol.getSymbolType() == SymbolType.FUNCTION) {
|
||||||
Function function = (Function) symbol.getObject();
|
Function function = (Function) symbol.getObject();
|
||||||
if (!function.isThunk() &&
|
if (!function.isThunk() &&
|
||||||
function.getSignatureSource().isHigherPriorityThan(SourceType.ANALYSIS)) {
|
function.getSignatureSource().isHigherOrEqualPriorityThan(SourceType.IMPORTED)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -297,8 +297,7 @@ public abstract class AbstractDemanglerAnalyzer extends AbstractAnalyzer {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String errorString = demangled.getErrorMessage();
|
String errorString = demangled.getErrorMessage();
|
||||||
logApplyErrorMessage(log, demangled, mangledContext.getAddress(), null,
|
logApplyErrorMessage(log, demangled, mangledContext.getAddress(), null, errorString);
|
||||||
errorString);
|
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
logApplyErrorMessage(log, demangled, mangledContext.getAddress(), e, null);
|
logApplyErrorMessage(log, demangled, mangledContext.getAddress(), e, null);
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
* 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.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -427,7 +427,7 @@ public class ConstantPropagationContextEvaluator extends ContextEvaluatorAdapter
|
||||||
}
|
}
|
||||||
|
|
||||||
SourceType mostTrusted = getMostTrustedParameterSource(func);
|
SourceType mostTrusted = getMostTrustedParameterSource(func);
|
||||||
if (SourceType.ANALYSIS.isLowerPriorityThan(mostTrusted)) {
|
if (mostTrusted.isHigherOrEqualPriorityThan(SourceType.IMPORTED)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -225,6 +225,8 @@ public class GolangSymbolAnalyzer extends AbstractAnalyzer {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: DWARF may have applied function signature with IMPORTED source type but
|
||||||
|
// this analyzer must apply more details
|
||||||
Function func = markupSession.createFunctionIfMissing(funcname, funcns, funcAddr);
|
Function func = markupSession.createFunctionIfMissing(funcname, funcns, funcAddr);
|
||||||
if (func == null ||
|
if (func == null ||
|
||||||
func.getSignatureSource().isHigherPriorityThan(SourceType.IMPORTED)) {
|
func.getSignatureSource().isHigherPriorityThan(SourceType.IMPORTED)) {
|
||||||
|
@ -503,8 +505,8 @@ public class GolangSymbolAnalyzer extends AbstractAnalyzer {
|
||||||
Address mbStart = max.subtract(offset_from_eom + len - 1);
|
Address mbStart = max.subtract(offset_from_eom + len - 1);
|
||||||
MemoryBlock newMB =
|
MemoryBlock newMB =
|
||||||
MemoryBlockUtils.createUninitializedBlock(program, false, "ARTIFICAL_GOLANG_CONTEXT",
|
MemoryBlockUtils.createUninitializedBlock(program, false, "ARTIFICAL_GOLANG_CONTEXT",
|
||||||
mbStart, len, "Artifical memory block created to hold Go context data types",
|
mbStart, len, "Artifical memory block created to hold Go context data types", null,
|
||||||
null, true, true, false, null);
|
true, true, false, null);
|
||||||
newMB.setArtificial(true);
|
newMB.setArtificial(true);
|
||||||
return newMB.getStart();
|
return newMB.getStart();
|
||||||
}
|
}
|
||||||
|
@ -1034,7 +1036,6 @@ public class GolangSymbolAnalyzer extends AbstractAnalyzer {
|
||||||
Register register, java.util.function.Function<GoType, DataType> returnTypeMapper) {
|
Register register, java.util.function.Function<GoType, DataType> returnTypeMapper) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private GoRttiMapper goBinary;
|
private GoRttiMapper goBinary;
|
||||||
private Program program;
|
private Program program;
|
||||||
private MarkupSession markupSession;
|
private MarkupSession markupSession;
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
* 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.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -109,8 +109,9 @@ public class PefAnalyzer extends AbstractAnalyzer {
|
||||||
}
|
}
|
||||||
Function function = functions.next();
|
Function function = functions.next();
|
||||||
try {
|
try {
|
||||||
program.getProgramContext().setRegisterValue(function.getEntryPoint(),
|
program.getProgramContext()
|
||||||
function.getEntryPoint(), regVal);
|
.setRegisterValue(function.getEntryPoint(), function.getEntryPoint(),
|
||||||
|
regVal);
|
||||||
}
|
}
|
||||||
catch (ContextChangeException e) {
|
catch (ContextChangeException e) {
|
||||||
// should never happen when changing r2 register
|
// should never happen when changing r2 register
|
||||||
|
@ -149,11 +150,8 @@ public class PefAnalyzer extends AbstractAnalyzer {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Function function = listing.getFunctionContaining(instruction.getMinAddress());
|
Function function = listing.getFunctionContaining(instruction.getMinAddress());
|
||||||
if (function == null) {
|
if (function == null ||
|
||||||
return;
|
function.getSymbol().getSource().isHigherOrEqualPriorityThan(SourceType.IMPORTED)) {
|
||||||
}
|
|
||||||
if (function.getSymbol().getSource() == SourceType.IMPORTED ||
|
|
||||||
function.getSymbol().getSource() == SourceType.USER_DEFINED) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Symbol symbol = symbolTable.getPrimarySymbol(symbolAddress);
|
Symbol symbol = symbolTable.getPrimarySymbol(symbolAddress);
|
||||||
|
|
|
@ -717,11 +717,9 @@ public class ClearFlowAndRepairCmd extends BackgroundCommand<Program> {
|
||||||
continue; // do not include data
|
continue; // do not include data
|
||||||
}
|
}
|
||||||
Symbol s = symbolTable.getPrimarySymbol(blockAddr);
|
Symbol s = symbolTable.getPrimarySymbol(blockAddr);
|
||||||
if (s != null && s.getSymbolType() == SymbolType.FUNCTION) {
|
if (s != null && s.getSymbolType() == SymbolType.FUNCTION &&
|
||||||
SourceType source = s.getSource();
|
s.getSource().isHigherOrEqualPriorityThan(SourceType.IMPORTED)) {
|
||||||
if (source == SourceType.USER_DEFINED || source == SourceType.IMPORTED) {
|
continue;
|
||||||
continue; // keep imported or user-defined function
|
|
||||||
}
|
|
||||||
// TODO: GP-5872 Clearing thunks explicitly created by loader or pattern
|
// TODO: GP-5872 Clearing thunks explicitly created by loader or pattern
|
||||||
// generally have default SourceType and may not have references
|
// generally have default SourceType and may not have references
|
||||||
// to them. We need to prevent these thunks from getting cleared.
|
// to them. We need to prevent these thunks from getting cleared.
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
* 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.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -29,11 +29,12 @@ public class NewSymbolFilter implements SymbolFilter {
|
||||||
|
|
||||||
private static final String XML_NAME = "SYMBOL_TABLE_FILTER";
|
private static final String XML_NAME = "SYMBOL_TABLE_FILTER";
|
||||||
|
|
||||||
private Filter userDefinedFilter;
|
private Filter defaultLabelSourceFilter;
|
||||||
private Filter analysisFilter;
|
private Filter defaultFunctionSourceFilter;
|
||||||
private Filter defaultFunctionFilter;
|
private Filter aiSourceFilter;
|
||||||
private Filter defaultLabelFilter;
|
private Filter analysisSourceFilter;
|
||||||
private Filter importedFilter;
|
private Filter importedSourceFilter;
|
||||||
|
private Filter userDefinedSourceFilter;
|
||||||
|
|
||||||
private Filter[] labelFilters;
|
private Filter[] labelFilters;
|
||||||
private Filter[] nonLabelFilters;
|
private Filter[] nonLabelFilters;
|
||||||
|
@ -67,19 +68,21 @@ public class NewSymbolFilter implements SymbolFilter {
|
||||||
for (Filter advancedFilter : advancedFilters) {
|
for (Filter advancedFilter : advancedFilters) {
|
||||||
filterMap.put(advancedFilter.getName(), advancedFilter);
|
filterMap.put(advancedFilter.getName(), advancedFilter);
|
||||||
}
|
}
|
||||||
filterMap.put(userDefinedFilter.getName(), userDefinedFilter);
|
filterMap.put(defaultLabelSourceFilter.getName(), defaultLabelSourceFilter);
|
||||||
filterMap.put(importedFilter.getName(), importedFilter);
|
filterMap.put(defaultFunctionSourceFilter.getName(), defaultFunctionSourceFilter);
|
||||||
filterMap.put(analysisFilter.getName(), analysisFilter);
|
filterMap.put(aiSourceFilter.getName(), aiSourceFilter);
|
||||||
filterMap.put(defaultLabelFilter.getName(), defaultLabelFilter);
|
filterMap.put(analysisSourceFilter.getName(), analysisSourceFilter);
|
||||||
filterMap.put(defaultFunctionFilter.getName(), defaultFunctionFilter);
|
filterMap.put(importedSourceFilter.getName(), importedSourceFilter);
|
||||||
|
filterMap.put(userDefinedSourceFilter.getName(), userDefinedSourceFilter);
|
||||||
|
|
||||||
if (oldFilter instanceof NewSymbolFilter) {
|
if (oldFilter instanceof NewSymbolFilter) {
|
||||||
NewSymbolFilter filter = (NewSymbolFilter) oldFilter;
|
NewSymbolFilter filter = (NewSymbolFilter) oldFilter;
|
||||||
userDefinedFilter.setActive(filter.userDefinedFilter.isActive());
|
defaultLabelSourceFilter.setActive(filter.defaultLabelSourceFilter.isActive());
|
||||||
importedFilter.setActive(filter.importedFilter.isActive());
|
defaultFunctionSourceFilter.setActive(filter.defaultFunctionSourceFilter.isActive());
|
||||||
analysisFilter.setActive(filter.analysisFilter.isActive());
|
aiSourceFilter.setActive(filter.aiSourceFilter.isActive());
|
||||||
defaultLabelFilter.setActive(filter.defaultLabelFilter.isActive());
|
analysisSourceFilter.setActive(filter.analysisSourceFilter.isActive());
|
||||||
defaultFunctionFilter.setActive(filter.defaultFunctionFilter.isActive());
|
importedSourceFilter.setActive(filter.importedSourceFilter.isActive());
|
||||||
|
userDefinedSourceFilter.setActive(filter.userDefinedSourceFilter.isActive());
|
||||||
|
|
||||||
for (int i = 0; i < labelFilters.length; i++) {
|
for (int i = 0; i < labelFilters.length; i++) {
|
||||||
labelFilters[i].setActive(filter.labelFilters[i].isActive());
|
labelFilters[i].setActive(filter.labelFilters[i].isActive());
|
||||||
|
@ -156,8 +159,8 @@ public class NewSymbolFilter implements SymbolFilter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean acceptsOnlyCodeSymbols() {
|
public boolean acceptsOnlyCodeSymbols() {
|
||||||
for (int i = 0; i < activeTypeFilters.length; i++) {
|
for (Filter activeTypeFilter : activeTypeFilters) {
|
||||||
if (!activeTypeFilters[i].onlyCodeSymbols) {
|
if (!activeTypeFilter.onlyCodeSymbols) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,7 +169,7 @@ public class NewSymbolFilter implements SymbolFilter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean acceptsDefaultLabelSymbols() {
|
public boolean acceptsDefaultLabelSymbols() {
|
||||||
if (!defaultLabelFilter.isActive()) {
|
if (!defaultLabelSourceFilter.isActive()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (Filter activeTypeFilter : activeTypeFilters) {
|
for (Filter activeTypeFilter : activeTypeFilters) {
|
||||||
|
@ -183,10 +186,10 @@ public class NewSymbolFilter implements SymbolFilter {
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] getSourceFilterNames() {
|
String[] getSourceFilterNames() {
|
||||||
return new String[] { userDefinedFilter.getName(), defaultFunctionFilter.getName(),
|
return new String[] { defaultLabelSourceFilter.getName(),
|
||||||
importedFilter.getName(), defaultLabelFilter.getName(), analysisFilter.getName(),
|
defaultFunctionSourceFilter.getName(), aiSourceFilter.getName(),
|
||||||
|
analysisSourceFilter.getName(), userDefinedSourceFilter.getName(),
|
||||||
};
|
importedSourceFilter.getName() };
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] getLabelTypeFilterNames() {
|
String[] getLabelTypeFilterNames() {
|
||||||
|
@ -283,31 +286,38 @@ public class NewSymbolFilter implements SymbolFilter {
|
||||||
for (Filter advancedFilter : advancedFilters) {
|
for (Filter advancedFilter : advancedFilters) {
|
||||||
advancedFilter.setActive(false);
|
advancedFilter.setActive(false);
|
||||||
}
|
}
|
||||||
userDefinedFilter.setActive(true);
|
defaultFunctionSourceFilter.setActive(true);
|
||||||
importedFilter.setActive(true);
|
defaultLabelSourceFilter.setActive(false);
|
||||||
analysisFilter.setActive(true);
|
aiSourceFilter.setActive(true);
|
||||||
defaultFunctionFilter.setActive(true);
|
analysisSourceFilter.setActive(true);
|
||||||
defaultLabelFilter.setActive(false);
|
importedSourceFilter.setActive(true);
|
||||||
|
userDefinedSourceFilter.setActive(true);
|
||||||
|
|
||||||
rebuildActiveFilters();
|
rebuildActiveFilters();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void rebuildActiveFilters() {
|
private void rebuildActiveFilters() {
|
||||||
ArrayList<Filter> originList = new ArrayList<>(3);
|
ArrayList<Filter> originList = new ArrayList<>(3);
|
||||||
if (userDefinedFilter.isActive()) {
|
|
||||||
originList.add(userDefinedFilter);
|
if (defaultLabelSourceFilter.isActive()) {
|
||||||
|
originList.add(defaultLabelSourceFilter);
|
||||||
}
|
}
|
||||||
if (importedFilter.isActive()) {
|
if (defaultFunctionSourceFilter.isActive()) {
|
||||||
originList.add(importedFilter);
|
originList.add(defaultFunctionSourceFilter);
|
||||||
}
|
}
|
||||||
if (analysisFilter.isActive()) {
|
if (aiSourceFilter.isActive()) {
|
||||||
originList.add(analysisFilter);
|
originList.add(aiSourceFilter);
|
||||||
}
|
}
|
||||||
if (defaultLabelFilter.isActive()) {
|
if (analysisSourceFilter.isActive()) {
|
||||||
originList.add(defaultLabelFilter);
|
originList.add(analysisSourceFilter);
|
||||||
}
|
}
|
||||||
if (defaultFunctionFilter.isActive()) {
|
if (importedSourceFilter.isActive()) {
|
||||||
originList.add(defaultFunctionFilter);
|
originList.add(importedSourceFilter);
|
||||||
}
|
}
|
||||||
|
if (userDefinedSourceFilter.isActive()) {
|
||||||
|
originList.add(userDefinedSourceFilter);
|
||||||
|
}
|
||||||
|
|
||||||
activeOriginFilters = new Filter[originList.size()];
|
activeOriginFilters = new Filter[originList.size()];
|
||||||
originList.toArray(activeOriginFilters);
|
originList.toArray(activeOriginFilters);
|
||||||
|
|
||||||
|
@ -339,49 +349,16 @@ public class NewSymbolFilter implements SymbolFilter {
|
||||||
advancedList.toArray(activeAdvancedFilters);
|
advancedList.toArray(activeAdvancedFilters);
|
||||||
|
|
||||||
acceptsAllTypes = activeTypeFilters.length == labelFilters.length + nonLabelFilters.length;
|
acceptsAllTypes = activeTypeFilters.length == labelFilters.length + nonLabelFilters.length;
|
||||||
acceptsAllSources = userDefinedFilter.isActive() && analysisFilter.isActive() &&
|
acceptsAllSources =
|
||||||
defaultLabelFilter.isActive() && defaultFunctionFilter.isActive() &&
|
defaultLabelSourceFilter.isActive() && defaultFunctionSourceFilter.isActive() &&
|
||||||
importedFilter.isActive();
|
importedSourceFilter.isActive() && aiSourceFilter.isActive() &&
|
||||||
|
analysisSourceFilter.isActive() && userDefinedSourceFilter.isActive();
|
||||||
acceptsAll = acceptsAllTypes && acceptsAllSources && activeAdvancedFilters.length == 0;
|
acceptsAll = acceptsAllTypes && acceptsAllSources && activeAdvancedFilters.length == 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createFilters() {
|
private void createFilters() {
|
||||||
userDefinedFilter = new Filter("User Defined", false, false) {
|
defaultLabelSourceFilter = new Filter("Default (Labels)", true, false) {
|
||||||
@Override
|
|
||||||
boolean matches(Program program, Symbol symbol) {
|
|
||||||
return symbol.getSource() == SourceType.USER_DEFINED;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
String getDescription() {
|
|
||||||
return "Include Symbols named by the user.";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
importedFilter = new Filter("Imported", false, false) {
|
|
||||||
@Override
|
|
||||||
boolean matches(Program program, Symbol symbol) {
|
|
||||||
return symbol.getSource() == SourceType.IMPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
String getDescription() {
|
|
||||||
return "Include Symbols imported from external information.";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
analysisFilter = new Filter("Analysis", false, false) {
|
|
||||||
@Override
|
|
||||||
boolean matches(Program program, Symbol symbol) {
|
|
||||||
return symbol.getSource() == SourceType.ANALYSIS;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
String getDescription() {
|
|
||||||
return "Include Symbols named by auto-analysis.";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
defaultLabelFilter = new Filter("Default (Labels)", true, false) {
|
|
||||||
@Override
|
@Override
|
||||||
boolean matches(Program program, Symbol symbol) {
|
boolean matches(Program program, Symbol symbol) {
|
||||||
return symbol.getSymbolType() != SymbolType.FUNCTION &&
|
return symbol.getSymbolType() != SymbolType.FUNCTION &&
|
||||||
|
@ -394,7 +371,7 @@ public class NewSymbolFilter implements SymbolFilter {
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
defaultFunctionFilter = new Filter("Default (Functions)", true, false) {
|
defaultFunctionSourceFilter = new Filter("Default (Functions)", true, false) {
|
||||||
@Override
|
@Override
|
||||||
boolean matches(Program program, Symbol symbol) {
|
boolean matches(Program program, Symbol symbol) {
|
||||||
return symbol.getSymbolType() == SymbolType.FUNCTION &&
|
return symbol.getSymbolType() == SymbolType.FUNCTION &&
|
||||||
|
@ -405,8 +382,52 @@ public class NewSymbolFilter implements SymbolFilter {
|
||||||
String getDescription() {
|
String getDescription() {
|
||||||
return "Include Symbols that have default names.";
|
return "Include Symbols that have default names.";
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
aiSourceFilter = new Filter(SourceType.AI.getDisplayString(), false, false) {
|
||||||
|
@Override
|
||||||
|
boolean matches(Program program, Symbol symbol) {
|
||||||
|
return symbol.getSource() == SourceType.AI;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String getDescription() {
|
||||||
|
return "Include Symbols named by auto-analysis.";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
analysisSourceFilter = new Filter(SourceType.ANALYSIS.getDisplayString(), false, false) {
|
||||||
|
@Override
|
||||||
|
boolean matches(Program program, Symbol symbol) {
|
||||||
|
return symbol.getSource() == SourceType.ANALYSIS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String getDescription() {
|
||||||
|
return "Include Symbols named by auto-analysis.";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
importedSourceFilter = new Filter(SourceType.IMPORTED.getDisplayString(), false, false) {
|
||||||
|
@Override
|
||||||
|
boolean matches(Program program, Symbol symbol) {
|
||||||
|
return symbol.getSource() == SourceType.IMPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String getDescription() {
|
||||||
|
return "Include Symbols imported from external information.";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
userDefinedSourceFilter =
|
||||||
|
new Filter(SourceType.USER_DEFINED.getDisplayString(), false, false) {
|
||||||
|
@Override
|
||||||
|
boolean matches(Program program, Symbol symbol) {
|
||||||
|
return symbol.getSource() == SourceType.USER_DEFINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String getDescription() {
|
||||||
|
return "Include Symbols named by the user.";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Filter instructionFilter = new Filter("Instruction Labels", true, true) {
|
Filter instructionFilter = new Filter("Instruction Labels", true, true) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -902,9 +923,7 @@ public class NewSymbolFilter implements SymbolFilter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean isEnabled() {
|
boolean isEnabled() {
|
||||||
Iterator<Filter> it = applicableFilters.iterator();
|
for (Filter filter : applicableFilters) {
|
||||||
while (it.hasNext()) {
|
|
||||||
Filter filter = it.next();
|
|
||||||
if (filter.isActive()) {
|
if (filter.isActive()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
* 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.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -378,8 +378,7 @@ public class DemangledFunction extends DemangledObject {
|
||||||
if (f != null && f.getSymbol().getSource() == SourceType.USER_DEFINED) {
|
if (f != null && f.getSymbol().getSource() == SourceType.USER_DEFINED) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (f == null || f.getSignatureSource() == SourceType.DEFAULT ||
|
if (f == null || f.getSignatureSource().isLowerOrEqualPriorityThan(SourceType.ANALYSIS)) {
|
||||||
f.getSignatureSource() == SourceType.ANALYSIS) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return super.isAlreadyDemangled(program, address);
|
return super.isAlreadyDemangled(program, address);
|
||||||
|
@ -809,7 +808,7 @@ public class DemangledFunction extends DemangledObject {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// if the parameters source is higher than
|
// if the parameters source is higher than
|
||||||
if (parameter.getSource().isHigherPriorityThan(SourceType.ANALYSIS)) {
|
if (parameter.getSource().isHigherOrEqualPriorityThan(SourceType.IMPORTED)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1286,6 +1286,8 @@
|
||||||
<li class="listitem" style="list-style-type: none">
|
<li class="listitem" style="list-style-type: none">
|
||||||
<span class="emphasis"><em>DEFAULT</em></span> - for basic or no information</li>
|
<span class="emphasis"><em>DEFAULT</em></span> - for basic or no information</li>
|
||||||
<li class="listitem" style="list-style-type: none">
|
<li class="listitem" style="list-style-type: none">
|
||||||
|
<span class="emphasis"><em>AI</em></span> - for information that is produced with AI assistance</li>
|
||||||
|
<li class="listitem" style="list-style-type: none">
|
||||||
<span class="emphasis"><em>ANALYSIS</em></span> - for information derived by an Analyzer</li>
|
<span class="emphasis"><em>ANALYSIS</em></span> - for information derived by an Analyzer</li>
|
||||||
<li class="listitem" style="list-style-type: none">
|
<li class="listitem" style="list-style-type: none">
|
||||||
<span class="emphasis"><em>IMPORTED</em></span> - for information imported from an external source</li>
|
<span class="emphasis"><em>IMPORTED</em></span> - for information imported from an external source</li>
|
||||||
|
|
|
@ -150,12 +150,12 @@ public class DecompilerParameterIdCmd extends BackgroundCommand<Program> {
|
||||||
// since decompile could fail and leave the source types changed.
|
// since decompile could fail and leave the source types changed.
|
||||||
Parameter retParam = func.getReturn();
|
Parameter retParam = func.getReturn();
|
||||||
if (retParam != null) {
|
if (retParam != null) {
|
||||||
if (!retParam.getSource().isHigherPriorityThan(sourceTypeClearLevel)) {
|
if (retParam.getSource().isLowerOrEqualPriorityThan(sourceTypeClearLevel)) {
|
||||||
func.setReturn(retParam.getDataType(), retParam.getVariableStorage(),
|
func.setReturn(retParam.getDataType(), retParam.getVariableStorage(),
|
||||||
SourceType.DEFAULT);
|
SourceType.DEFAULT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!func.getSignatureSource().isHigherPriorityThan(sourceTypeClearLevel)) {
|
if (func.getSignatureSource().isLowerOrEqualPriorityThan(sourceTypeClearLevel)) {
|
||||||
func.setSignatureSource(SourceType.DEFAULT);
|
func.setSignatureSource(SourceType.DEFAULT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
* 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.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -36,7 +36,7 @@ import ghidra.util.exception.InvalidInputException;
|
||||||
public class OverridePrototypeAction extends AbstractDecompilerAction {
|
public class OverridePrototypeAction extends AbstractDecompilerAction {
|
||||||
|
|
||||||
public OverridePrototypeAction() {
|
public OverridePrototypeAction() {
|
||||||
super("Override Signature");
|
super("Override Signature");
|
||||||
setHelpLocation(new HelpLocation(HelpTopics.DECOMPILER, "ActionOverrideSignature"));
|
setHelpLocation(new HelpLocation(HelpTopics.DECOMPILER, "ActionOverrideSignature"));
|
||||||
setPopupMenuData(new MenuData(new String[] { "Override Signature" }, "Decompile"));
|
setPopupMenuData(new MenuData(new String[] { "Override Signature" }, "Decompile"));
|
||||||
}
|
}
|
||||||
|
@ -174,11 +174,9 @@ public class OverridePrototypeAction extends AbstractDecompilerAction {
|
||||||
// for the initial signature. HighFunction does not make it easy to grab
|
// for the initial signature. HighFunction does not make it easy to grab
|
||||||
// existing override prototype
|
// existing override prototype
|
||||||
|
|
||||||
if (calledfunc != null) {
|
if (calledfunc != null &&
|
||||||
SourceType signatureSource = calledfunc.getSignatureSource();
|
calledfunc.getSignatureSource().isLowerOrEqualPriorityThan(SourceType.ANALYSIS)) {
|
||||||
if (signatureSource == SourceType.DEFAULT || signatureSource == SourceType.ANALYSIS) {
|
calledfunc = null; // ignore
|
||||||
calledfunc = null; // ignore
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuffer buf = new StringBuffer();
|
StringBuffer buf = new StringBuffer();
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
* 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.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -63,6 +63,8 @@ public class DecompilerParameterIDValidator extends PostAnalysisValidator {
|
||||||
|
|
||||||
if (inst != null) {
|
if (inst != null) {
|
||||||
final SourceType signatureSource = func.getSignatureSource();
|
final SourceType signatureSource = func.getSignatureSource();
|
||||||
|
// TODO: There is a misconception that ANALYSIS source type can be used to
|
||||||
|
// determine if Param ID Analyzer has been used. This should be re-examined.
|
||||||
if (signatureSource == SourceType.ANALYSIS) {
|
if (signatureSource == SourceType.ANALYSIS) {
|
||||||
++numFuncsWithParameterID;
|
++numFuncsWithParameterID;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
* 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.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -273,9 +273,8 @@ public class ApplyFidEntriesCommand extends BackgroundCommand<Program> {
|
||||||
SymbolTable symbolTable = program.getSymbolTable();
|
SymbolTable symbolTable = program.getSymbolTable();
|
||||||
SymbolIterator symbols = symbolTable.getSymbolsAsIterator(function.getEntryPoint());
|
SymbolIterator symbols = symbolTable.getSymbolsAsIterator(function.getEntryPoint());
|
||||||
for (Symbol symbol : symbols) {
|
for (Symbol symbol : symbols) {
|
||||||
SourceType sourceType = symbol.getSource();
|
if (symbol.getSource().isHigherOrEqualPriorityThan(SourceType.IMPORTED)) {
|
||||||
if (sourceType == SourceType.USER_DEFINED || sourceType == SourceType.IMPORTED) {
|
return true; // symbol has trusted source
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
* 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.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -50,8 +50,8 @@ public class GhidraJythonInterpreter extends InteractiveInterpreter {
|
||||||
private PyModule introspectModule;
|
private PyModule introspectModule;
|
||||||
private PyModule builtinModule;
|
private PyModule builtinModule;
|
||||||
private PyObject interrupt;
|
private PyObject interrupt;
|
||||||
private boolean scriptMethodsInjected;
|
|
||||||
private boolean cleanedUp;
|
private boolean cleanedUp;
|
||||||
|
private Stack<PyObject> localStack = new Stack<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a new GhidraPythonInterpreter instance.
|
* Gets a new GhidraPythonInterpreter instance.
|
||||||
|
@ -126,6 +126,7 @@ public class GhidraJythonInterpreter extends InteractiveInterpreter {
|
||||||
/**
|
/**
|
||||||
* Initializes/resets the python path to include all known Ghidra script paths.
|
* Initializes/resets the python path to include all known Ghidra script paths.
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
private void initializePythonPath() {
|
private void initializePythonPath() {
|
||||||
|
|
||||||
// Restore the python path back to default.
|
// Restore the python path back to default.
|
||||||
|
@ -359,24 +360,20 @@ public class GhidraJythonInterpreter extends InteractiveInterpreter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add public methods (only once). Ignore inner classes.
|
// Add public methods. Ignore inner classes.
|
||||||
//
|
//
|
||||||
// NOTE: We currently do not have a way to safely add protected methods. Disabling
|
// NOTE: We currently do not have a way to safely add protected methods. Disabling
|
||||||
// python.security.respectJavaAccessibility and adding in protected methods in the below
|
// python.security.respectJavaAccessibility and adding in protected methods in the below
|
||||||
// loop caused an InaccessibleObjectException for some users (relating to core Java
|
// loop caused an InaccessibleObjectException for some users (relating to core Java
|
||||||
// modules, not the GhidraScript class hierarchy).
|
// modules, not the GhidraScript class hierarchy).
|
||||||
if (!scriptMethodsInjected) {
|
for (Method method : scriptClass.getDeclaredMethods()) {
|
||||||
for (Method method : scriptClass.getDeclaredMethods()) {
|
if (!method.getName().contains("$") &&
|
||||||
if (!method.getName().contains("$") &&
|
Modifier.isPublic(method.getModifiers())) {
|
||||||
Modifier.isPublic(method.getModifiers())) {
|
method.setAccessible(true);
|
||||||
method.setAccessible(true);
|
setMethod(script, method);
|
||||||
setMethod(script, method);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scriptMethodsInjected = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -395,6 +392,29 @@ public class GhidraJythonInterpreter extends InteractiveInterpreter {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the interpreter's locals to a stack. These locals can be restored with the
|
||||||
|
* {@link #restoreLocals()} method.
|
||||||
|
*/
|
||||||
|
public void saveLocals() {
|
||||||
|
localStack.push(getLocals());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the interpreter's locals
|
||||||
|
*/
|
||||||
|
public void clearLocals() {
|
||||||
|
setLocals(new PyStringMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restores the locals that were last saved with the {@link #saveLocals()} method, and removes
|
||||||
|
* them from the stack.
|
||||||
|
*/
|
||||||
|
public void restoreLocals() {
|
||||||
|
setLocals(localStack.pop());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a bound (callback/function pointer) method as a local variable in the interpreter.
|
* Sets a bound (callback/function pointer) method as a local variable in the interpreter.
|
||||||
*
|
*
|
||||||
|
@ -427,6 +447,8 @@ public class GhidraJythonInterpreter extends InteractiveInterpreter {
|
||||||
Msg.error(this,
|
Msg.error(this,
|
||||||
"Method " + methodName + " of " + obj + " attempting to shadow method " +
|
"Method " + methodName + " of " + obj + " attempting to shadow method " +
|
||||||
pyMethod.__func__ + " of " + pyMethod.__self__);
|
pyMethod.__func__ + " of " + pyMethod.__self__);
|
||||||
|
set(methodName, new PyMethod(new PyReflectedFunction(method), Py.java2py(obj),
|
||||||
|
Py.java2py(obj.getClass())));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!(pyMethod.__func__ instanceof PyReflectedFunction)) {
|
if (!(pyMethod.__func__ instanceof PyReflectedFunction)) {
|
||||||
|
|
|
@ -71,13 +71,20 @@ public class JythonScript extends GhidraScript {
|
||||||
updateStateFromVariables();
|
updateStateFromVariables();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ghidraScript instanceof JythonScript) {
|
try {
|
||||||
ghidraScript.set(scriptState);
|
interpreter.saveLocals();
|
||||||
JythonScript jythonScript = (JythonScript) ghidraScript;
|
interpreter.clearLocals();
|
||||||
interpreter.execFile(jythonScript.getSourceFile(), jythonScript);
|
if (ghidraScript instanceof JythonScript) {
|
||||||
|
ghidraScript.set(scriptState);
|
||||||
|
JythonScript jythonScript = (JythonScript) ghidraScript;
|
||||||
|
interpreter.execFile(jythonScript.getSourceFile(), jythonScript);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ghidraScript.execute(scriptState, getControls());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
finally {
|
||||||
ghidraScript.execute(scriptState, getControls());
|
interpreter.restoreLocals();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scriptState == state) {
|
if (scriptState == state) {
|
||||||
|
|
|
@ -2341,25 +2341,6 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//==============================================================================================
|
|
||||||
boolean shouldForcePrimarySymbol(Address address, boolean forceIfMangled) {
|
|
||||||
Symbol primarySymbol = program.getSymbolTable().getPrimarySymbol(address);
|
|
||||||
if (primarySymbol != null) {
|
|
||||||
|
|
||||||
if (primarySymbol.getName().startsWith("?") && forceIfMangled &&
|
|
||||||
applicatorOptions.allowDemotePrimaryMangledSymbols()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
SourceType primarySymbolSource = primarySymbol.getSource();
|
|
||||||
|
|
||||||
if (!SourceType.ANALYSIS.isHigherPriorityThan(primarySymbolSource)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==============================================================================================
|
//==============================================================================================
|
||||||
boolean addToPlateUnique(Address address, String comment) {
|
boolean addToPlateUnique(Address address, String comment) {
|
||||||
if (StringUtils.isBlank(comment)) {
|
if (StringUtils.isBlank(comment)) {
|
||||||
|
@ -2411,8 +2392,8 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
|
|
||||||
Function existingFunction = program.getListing().getFunctionAt(address);
|
Function existingFunction = program.getListing().getFunctionAt(address);
|
||||||
if (existingFunction != null) { // Maybe I should care if there is a data type there too.
|
if (existingFunction != null) { // Maybe I should care if there is a data type there too.
|
||||||
if (existingFunction.getSignatureSource().isHigherPriorityThan(SourceType.ANALYSIS)) {
|
if (existingFunction.getSignatureSource()
|
||||||
// Existing is USER or IMPORTED
|
.isHigherOrEqualPriorityThan(SourceType.IMPORTED)) {
|
||||||
return doCreateSymbol(address, symbolPath, false, plateAddition);
|
return doCreateSymbol(address, symbolPath, false, plateAddition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,8 +79,7 @@ public class FunctionSymbolApplier extends AbstractBlockContextApplier
|
||||||
return applicator.getAddress(symbol);
|
return applicator.getAddress(symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processSymbol(MsSymbolIterator iter)
|
private void processSymbol(MsSymbolIterator iter) throws CancelledException, PdbException {
|
||||||
throws CancelledException, PdbException {
|
|
||||||
|
|
||||||
Address address = applicator.getAddress(symbol);
|
Address address = applicator.getAddress(symbol);
|
||||||
String name = symbol.getName();
|
String name = symbol.getName();
|
||||||
|
@ -186,8 +185,7 @@ public class FunctionSymbolApplier extends AbstractBlockContextApplier
|
||||||
}
|
}
|
||||||
// Remaining are non-thunks
|
// Remaining are non-thunks
|
||||||
|
|
||||||
if (function.getSignatureSource().isHigherPriorityThan(SourceType.ANALYSIS)) {
|
if (function.getSignatureSource().isHigherOrEqualPriorityThan(SourceType.IMPORTED)) {
|
||||||
// return if IMPORTED or USER_DEFINED
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
* 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.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -86,8 +86,7 @@ public class ManagedProcedureSymbolApplier extends AbstractBlockContextApplier
|
||||||
|
|
||||||
// TODO. Investigate more. This is not working for at least one CLI dll in that we are
|
// TODO. Investigate more. This is not working for at least one CLI dll in that we are
|
||||||
// not getting correct addresses. There is no omap and the one section is unnamed.
|
// not getting correct addresses. There is no omap and the one section is unnamed.
|
||||||
private void processSymbol(MsSymbolIterator iter)
|
private void processSymbol(MsSymbolIterator iter) throws CancelledException, PdbException {
|
||||||
throws CancelledException, PdbException {
|
|
||||||
|
|
||||||
Address address = applicator.getAddress(symbol);
|
Address address = applicator.getAddress(symbol);
|
||||||
String name = symbol.getName();
|
String name = symbol.getName();
|
||||||
|
@ -124,8 +123,7 @@ public class ManagedProcedureSymbolApplier extends AbstractBlockContextApplier
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deferredApply(MsSymbolIterator iter)
|
public void deferredApply(MsSymbolIterator iter) throws PdbException, CancelledException {
|
||||||
throws PdbException, CancelledException {
|
|
||||||
// Pealing the symbol off again, as the iterator is coming in fresh, and we need the symbol
|
// Pealing the symbol off again, as the iterator is coming in fresh, and we need the symbol
|
||||||
getValidatedSymbol(iter, true);
|
getValidatedSymbol(iter, true);
|
||||||
|
|
||||||
|
@ -260,9 +258,8 @@ public class ManagedProcedureSymbolApplier extends AbstractBlockContextApplier
|
||||||
return; // silently return.
|
return; // silently return.
|
||||||
}
|
}
|
||||||
// Currently just placing a comment.
|
// Currently just placing a comment.
|
||||||
String comment =
|
String comment = context.getIndent(symbolBlockNestingLevel + 1) +
|
||||||
context.getIndent(symbolBlockNestingLevel + 1) + "static local (stored at " +
|
"static local (stored at " + address + ") " + dataType.getName() + " " + name;
|
||||||
address + ") " + dataType.getName() + " " + name;
|
|
||||||
context.getComments().addPreComment(currentBlockAddress, comment);
|
context.getComments().addPreComment(currentBlockAddress, comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,8 +297,7 @@ public class ManagedProcedureSymbolApplier extends AbstractBlockContextApplier
|
||||||
private boolean setFunctionDefinition(Function function, Address address,
|
private boolean setFunctionDefinition(Function function, Address address,
|
||||||
AbstractManagedProcedureMsSymbol symbol) throws CancelledException, PdbException {
|
AbstractManagedProcedureMsSymbol symbol) throws CancelledException, PdbException {
|
||||||
|
|
||||||
if (function.getSignatureSource().isHigherPriorityThan(SourceType.ANALYSIS)) {
|
if (function.getSignatureSource().isHigherOrEqualPriorityThan(SourceType.IMPORTED)) {
|
||||||
// return if IMPORTED or USER_DEFINED
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
* 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.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -106,8 +106,7 @@ public class SimilarSymbolNameProgramCorrelator extends VTAbstractProgramCorrela
|
||||||
if (!addressSet.contains(symbol.getAddress())) {
|
if (!addressSet.contains(symbol.getAddress())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (symbol.getSource() == SourceType.DEFAULT ||
|
if (symbol.getSource().isLowerOrEqualPriorityThan(SourceType.ANALYSIS)) {
|
||||||
symbol.getSource() == SourceType.ANALYSIS) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
* 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.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -979,38 +979,29 @@ public class FunctionSignatureStringable extends Stringable {
|
||||||
|
|
||||||
private boolean isFirstHigherPriorityWhenUserPriority(SourceType first, SourceType second,
|
private boolean isFirstHigherPriorityWhenUserPriority(SourceType first, SourceType second,
|
||||||
boolean replaceSamePriorityNames) {
|
boolean replaceSamePriorityNames) {
|
||||||
if (first == second && first != SourceType.DEFAULT) {
|
if (first == SourceType.DEFAULT) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (first == second) {
|
||||||
return replaceSamePriorityNames;
|
return replaceSamePriorityNames;
|
||||||
}
|
}
|
||||||
if (first == SourceType.USER_DEFINED) {
|
return first.isHigherPriorityThan(second);
|
||||||
return (second == SourceType.IMPORTED || second == SourceType.ANALYSIS ||
|
|
||||||
second == SourceType.DEFAULT);
|
|
||||||
}
|
|
||||||
if (first == SourceType.IMPORTED) {
|
|
||||||
return (second == SourceType.ANALYSIS || second == SourceType.DEFAULT);
|
|
||||||
}
|
|
||||||
if (first == SourceType.ANALYSIS) {
|
|
||||||
return (second == SourceType.DEFAULT);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isFirstHigherPriorityWhenImportedPriority(SourceType first, SourceType second,
|
private boolean isFirstHigherPriorityWhenImportedPriority(SourceType first, SourceType second,
|
||||||
boolean replaceSamePriorityNames) {
|
boolean replaceSamePriorityNames) {
|
||||||
if (first == second && first != SourceType.DEFAULT) {
|
if (first == SourceType.DEFAULT) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (first == second) {
|
||||||
return replaceSamePriorityNames;
|
return replaceSamePriorityNames;
|
||||||
}
|
}
|
||||||
|
// NOTE: If a new SourceType is added with a priority in between IMPORTED and USER_DEFINED
|
||||||
|
// VT and this code will need to change.
|
||||||
if (first == SourceType.IMPORTED) {
|
if (first == SourceType.IMPORTED) {
|
||||||
return (second == SourceType.USER_DEFINED || second == SourceType.ANALYSIS ||
|
return true; // IMPORTED is highest priority
|
||||||
second == SourceType.DEFAULT);
|
|
||||||
}
|
}
|
||||||
if (first == SourceType.USER_DEFINED) {
|
return first.isHigherPriorityThan(second);
|
||||||
return (second == SourceType.ANALYSIS || second == SourceType.DEFAULT);
|
|
||||||
}
|
|
||||||
if (first == SourceType.ANALYSIS) {
|
|
||||||
return (second == SourceType.DEFAULT);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void replaceParameterComments(Function toFunction, CommentChoices commentChoice) {
|
private void replaceParameterComments(Function toFunction, CommentChoices commentChoice) {
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
* 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.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -17,6 +17,7 @@ package ghidra.feature.vt.gui.provider.matchtable;
|
||||||
|
|
||||||
import java.awt.event.ItemEvent;
|
import java.awt.event.ItemEvent;
|
||||||
import java.awt.event.ItemListener;
|
import java.awt.event.ItemListener;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
import javax.swing.JCheckBox;
|
import javax.swing.JCheckBox;
|
||||||
|
|
||||||
|
@ -48,6 +49,7 @@ public class SymbolTypeFilter extends CheckBoxBasedAncillaryFilter<VTMatch> {
|
||||||
};
|
};
|
||||||
|
|
||||||
SourceType[] values = SourceType.values();
|
SourceType[] values = SourceType.values();
|
||||||
|
Arrays.sort(values, (s1, s2) -> s1.getPriority() - s2.getPriority());
|
||||||
for (SourceType type : values) {
|
for (SourceType type : values) {
|
||||||
GCheckBox checkBox = new GCheckBox(type.getDisplayString(), true);
|
GCheckBox checkBox = new GCheckBox(type.getDisplayString(), true);
|
||||||
checkBox.addItemListener(listener);
|
checkBox.addItemListener(listener);
|
||||||
|
|
|
@ -116,8 +116,10 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM
|
||||||
* 13-Dec-2024 - version 29 Added source file manager.
|
* 13-Dec-2024 - version 29 Added source file manager.
|
||||||
* 3-Jun-2025 - version 30 Symbol Table schema V4 with external symbol data indexing
|
* 3-Jun-2025 - version 30 Symbol Table schema V4 with external symbol data indexing
|
||||||
* 15-Sep-2025 - version 31 Code Mananger dropped Composites property map use
|
* 15-Sep-2025 - version 31 Code Mananger dropped Composites property map use
|
||||||
|
* 19-Sep-2025 - version 32 Expanded number of SourceType values and record storage affecting
|
||||||
|
* SymbolDB, FunctionDB and RefListFlagsV0
|
||||||
*/
|
*/
|
||||||
static final int DB_VERSION = 31;
|
static final int DB_VERSION = 32;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UPGRADE_REQUIRED_BFORE_VERSION should be changed to DB_VERSION anytime the
|
* UPGRADE_REQUIRED_BFORE_VERSION should be changed to DB_VERSION anytime the
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
* 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.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -46,10 +46,12 @@ abstract class FunctionAdapter {
|
||||||
static final byte FUNCTION_INLINE_FLAG = (byte) 0x2; // Bit 1 is flag for "is inline".
|
static final byte FUNCTION_INLINE_FLAG = (byte) 0x2; // Bit 1 is flag for "is inline".
|
||||||
static final byte FUNCTION_NO_RETURN_FLAG = (byte) 0x4; // Bit 2 is flag for "has no return".
|
static final byte FUNCTION_NO_RETURN_FLAG = (byte) 0x4; // Bit 2 is flag for "has no return".
|
||||||
static final byte FUNCTION_CUSTOM_PARAM_STORAGE_FLAG = (byte) 0x8; // Bit 3 is flag for "has custom storage"
|
static final byte FUNCTION_CUSTOM_PARAM_STORAGE_FLAG = (byte) 0x8; // Bit 3 is flag for "has custom storage"
|
||||||
static final byte FUNCTION_SIGNATURE_SOURCE = (byte) 0x30; // Bits 4-5 are storage for "signature SourceType"
|
static final byte FUNCTION_SIGNATURE_SOURCE = (byte) 0x70; // Bits 4-6 are storage for "signature SourceType"
|
||||||
|
|
||||||
static final int FUNCTION_SIGNATURE_SOURCE_SHIFT = 4; // bit shift for flag storage of "signature SourceType"
|
static final int FUNCTION_SIGNATURE_SOURCE_SHIFT = 4; // bit shift for flag storage of "signature SourceType"
|
||||||
|
|
||||||
|
private static final int MAX_SOURCE_VALUE = 7; // value limit based upon 3-bit storage capacity
|
||||||
|
|
||||||
final static Schema FUNCTION_SCHEMA = new Schema(CURRENT_VERSION, "ID",
|
final static Schema FUNCTION_SCHEMA = new Schema(CURRENT_VERSION, "ID",
|
||||||
new Field[] { LongField.INSTANCE, IntField.INSTANCE, IntField.INSTANCE, IntField.INSTANCE,
|
new Field[] { LongField.INSTANCE, IntField.INSTANCE, IntField.INSTANCE, IntField.INSTANCE,
|
||||||
ByteField.INSTANCE, ByteField.INSTANCE, StringField.INSTANCE },
|
ByteField.INSTANCE, ByteField.INSTANCE, StringField.INSTANCE },
|
||||||
|
@ -94,8 +96,11 @@ abstract class FunctionAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
static byte getSignatureSourceFlagBits(SourceType signatureSource) {
|
static byte getSignatureSourceFlagBits(SourceType signatureSource) {
|
||||||
return (byte) (signatureSource
|
int sourceTypeId = signatureSource.getStorageId();
|
||||||
.ordinal() << FunctionAdapter.FUNCTION_SIGNATURE_SOURCE_SHIFT);
|
if (sourceTypeId > MAX_SOURCE_VALUE) {
|
||||||
|
throw new RuntimeException("Unsupported SourceType storage ID: " + sourceTypeId);
|
||||||
|
}
|
||||||
|
return (byte) (sourceTypeId << FunctionAdapter.FUNCTION_SIGNATURE_SOURCE_SHIFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static FunctionAdapter findReadOnlyAdapter(DBHandle handle, AddressMap map)
|
static FunctionAdapter findReadOnlyAdapter(DBHandle handle, AddressMap map)
|
||||||
|
|
|
@ -585,12 +585,9 @@ public class FunctionDB extends DatabaseObject implements Function {
|
||||||
if (Undefined.isUndefined(variableDataType)) {
|
if (Undefined.isUndefined(variableDataType)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SourceType type = SourceType.ANALYSIS;
|
// TODO: It seems that the lowest parameter priority should win out (see GP-6013)
|
||||||
if (variableSourceType != type && variableSourceType.isHigherPriorityThan(type)) {
|
if (variableSourceType.isHigherPriorityThan(getStoredSignatureSource())) {
|
||||||
type = variableSourceType;
|
setSignatureSource(variableSourceType);
|
||||||
}
|
|
||||||
if (type.isHigherPriorityThan(getStoredSignatureSource())) {
|
|
||||||
setSignatureSource(type);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -604,14 +601,14 @@ public class FunctionDB extends DatabaseObject implements Function {
|
||||||
boolean isReturnUndefined = Undefined.isUndefined(returnType);
|
boolean isReturnUndefined = Undefined.isUndefined(returnType);
|
||||||
SourceType type = isReturnUndefined ? SourceType.DEFAULT : SourceType.ANALYSIS;
|
SourceType type = isReturnUndefined ? SourceType.DEFAULT : SourceType.ANALYSIS;
|
||||||
|
|
||||||
|
// TODO: It seems that the lowest parameter priority should win out (see GP-6013)
|
||||||
Parameter[] parameters = getParameters();
|
Parameter[] parameters = getParameters();
|
||||||
for (Parameter parameter : parameters) {
|
for (Parameter parameter : parameters) {
|
||||||
if (Undefined.isUndefined(parameter.getDataType())) {
|
if (Undefined.isUndefined(parameter.getDataType())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
SourceType paramSourceType = parameter.getSource();
|
SourceType paramSourceType = parameter.getSource();
|
||||||
if (paramSourceType != SourceType.ANALYSIS &&
|
if (paramSourceType.isHigherOrEqualPriorityThan(SourceType.IMPORTED)) {
|
||||||
paramSourceType.isHigherPriorityThan(SourceType.ANALYSIS)) {
|
|
||||||
type = paramSourceType;
|
type = paramSourceType;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1458,7 +1455,7 @@ public class FunctionDB extends DatabaseObject implements Function {
|
||||||
symbolMap.put(s, paramDb);
|
symbolMap.put(s, paramDb);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (source.isHigherPriorityThan(getStoredSignatureSource())) {
|
if (source != getStoredSignatureSource()) {
|
||||||
setSignatureSource(source);
|
setSignatureSource(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2448,9 +2445,9 @@ public class FunctionDB extends DatabaseObject implements Function {
|
||||||
|
|
||||||
SourceType getStoredSignatureSource() {
|
SourceType getStoredSignatureSource() {
|
||||||
byte flags = rec.getByteValue(FunctionAdapter.FUNCTION_FLAGS_COL);
|
byte flags = rec.getByteValue(FunctionAdapter.FUNCTION_FLAGS_COL);
|
||||||
int typeOrdinal = (flags &
|
int sourceTypeId = (flags &
|
||||||
FunctionAdapter.FUNCTION_SIGNATURE_SOURCE) >>> FunctionAdapter.FUNCTION_SIGNATURE_SOURCE_SHIFT;
|
FunctionAdapter.FUNCTION_SIGNATURE_SOURCE) >>> FunctionAdapter.FUNCTION_SIGNATURE_SOURCE_SHIFT;
|
||||||
return SourceType.values()[typeOrdinal];
|
return SourceType.getSourceType(sourceTypeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
/* ###
|
/* ###
|
||||||
* 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.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -20,13 +19,23 @@ import ghidra.program.model.symbol.SourceType;
|
||||||
|
|
||||||
class RefListFlagsV0 {
|
class RefListFlagsV0 {
|
||||||
|
|
||||||
private static final int SOURCE_LOBIT = 0x01;
|
// NOTE: Storage for SourceType has been expanded into upper zero-initialized bits
|
||||||
|
// with simple ProgramDB version change.
|
||||||
|
|
||||||
|
private static final int SOURCE_LOBIT = 0x01; // SourceType LO 1-bit
|
||||||
private static final int IS_PRIMARY = 0x02;
|
private static final int IS_PRIMARY = 0x02;
|
||||||
private static final int IS_OFFSET = 0x04;
|
private static final int IS_OFFSET = 0x04;
|
||||||
private static final int HAS_SYMBOL_ID = 0x08;
|
private static final int HAS_SYMBOL_ID = 0x08;
|
||||||
private static final int IS_SHIFT = 0x10;
|
private static final int IS_SHIFT = 0x10;
|
||||||
|
private static final int SOURCE_HIBITS = 0x60; // SourceType HI 2-bits
|
||||||
|
|
||||||
private static final int SOURCE_HIBIT = 0x20;
|
private static final int SOURCE_HIBIT = 0x20;
|
||||||
|
|
||||||
|
private static final int SOURCE_LOBIT_SHIFT = 0;
|
||||||
|
private static final int SOURCE_HIBITS_SHIFT = 5;
|
||||||
|
|
||||||
|
private static final int MAX_SOURCE_VALUE = 7; // value limit based upon 3-bit storage capacity
|
||||||
|
|
||||||
private int flags;
|
private int flags;
|
||||||
|
|
||||||
RefListFlagsV0(byte flags) {
|
RefListFlagsV0(byte flags) {
|
||||||
|
@ -36,12 +45,23 @@ class RefListFlagsV0 {
|
||||||
public RefListFlagsV0(boolean isPrimary, boolean isOffsetRef, boolean hasSymbolID,
|
public RefListFlagsV0(boolean isPrimary, boolean isOffsetRef, boolean hasSymbolID,
|
||||||
boolean isShiftRef, SourceType source) {
|
boolean isShiftRef, SourceType source) {
|
||||||
flags = 0;
|
flags = 0;
|
||||||
if (source == SourceType.USER_DEFINED || source == SourceType.IMPORTED) {
|
|
||||||
flags |= SOURCE_LOBIT;
|
// Get the storage ID to be used to encode source type
|
||||||
}
|
// NOTE: RefListV0 uses a storage ID in some cases that differs from SourceType storage ID
|
||||||
if (source == SourceType.ANALYSIS || source == SourceType.IMPORTED) {
|
int sourceId = switch (source) {
|
||||||
flags |= SOURCE_HIBIT;
|
case DEFAULT -> 0;
|
||||||
|
case ANALYSIS -> 2;
|
||||||
|
default -> source.getStorageId();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Encode SourceType value into split storage flags
|
||||||
|
if (sourceId > MAX_SOURCE_VALUE) {
|
||||||
|
throw new RuntimeException("Unsupported SourceType storage ID: " + sourceId);
|
||||||
}
|
}
|
||||||
|
int sourceTypeLoBit = (sourceId & 1) << SOURCE_LOBIT_SHIFT; // 1-bit
|
||||||
|
int sourceTypeHiBits = (sourceId >>> 1) << SOURCE_HIBITS_SHIFT; // remaining hi-bits
|
||||||
|
flags |= sourceTypeHiBits | sourceTypeLoBit;
|
||||||
|
|
||||||
if (isPrimary)
|
if (isPrimary)
|
||||||
flags |= IS_PRIMARY;
|
flags |= IS_PRIMARY;
|
||||||
if (isOffsetRef)
|
if (isOffsetRef)
|
||||||
|
@ -57,12 +77,18 @@ class RefListFlagsV0 {
|
||||||
}
|
}
|
||||||
|
|
||||||
SourceType getSource() {
|
SourceType getSource() {
|
||||||
boolean isLoBit = (flags & SOURCE_LOBIT) != 0;
|
|
||||||
boolean isHiBit = (flags & SOURCE_HIBIT) != 0;
|
// Decode storage ID from flags bits
|
||||||
if (isHiBit) {
|
int sourceTypeLoBit = (flags & SOURCE_LOBIT) >>> SOURCE_LOBIT_SHIFT; // 1-bit
|
||||||
return isLoBit ? SourceType.IMPORTED : SourceType.ANALYSIS;
|
int sourceTypeHiBits = (flags & SOURCE_HIBITS) >>> (SOURCE_HIBITS_SHIFT - 1); // remaining HI-bits
|
||||||
}
|
int sourceTypeId = sourceTypeHiBits | sourceTypeLoBit;
|
||||||
return isLoBit ? SourceType.USER_DEFINED : SourceType.DEFAULT;
|
|
||||||
|
// NOTE: RefListV0 uses a storage ID in some cases that differs from SourceType storage ID
|
||||||
|
return switch (sourceTypeId) {
|
||||||
|
case 0 -> SourceType.DEFAULT;
|
||||||
|
case 2 -> SourceType.ANALYSIS;
|
||||||
|
default -> SourceType.getSourceType(sourceTypeId);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasSymbolID() {
|
public boolean hasSymbolID() {
|
||||||
|
|
|
@ -169,7 +169,7 @@ public abstract class MemorySymbol extends SymbolDB {
|
||||||
newNamespace.getID());
|
newNamespace.getID());
|
||||||
}
|
}
|
||||||
if (newSource != null) {
|
if (newSource != null) {
|
||||||
setSourceFlagBit(newSource);
|
setSourceFlagBits(newSource);
|
||||||
}
|
}
|
||||||
updatePinnedFlag(pinned);
|
updatePinnedFlag(pinned);
|
||||||
updateRecord();
|
updateRecord();
|
||||||
|
|
|
@ -253,7 +253,7 @@ public abstract class SymbolDB extends DatabaseObject implements Symbol {
|
||||||
throw new IllegalArgumentException(msg);
|
throw new IllegalArgumentException(msg);
|
||||||
}
|
}
|
||||||
if (record != null) {
|
if (record != null) {
|
||||||
setSourceFlagBit(newSource);
|
setSourceFlagBits(newSource);
|
||||||
updateRecord();
|
updateRecord();
|
||||||
symbolMgr.symbolSourceChanged(this);
|
symbolMgr.symbolSourceChanged(this);
|
||||||
}
|
}
|
||||||
|
@ -263,10 +263,10 @@ public abstract class SymbolDB extends DatabaseObject implements Symbol {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setSourceFlagBit(SourceType newSource) {
|
protected void setSourceFlagBits(SourceType newSource) {
|
||||||
byte flags = record.getByteValue(SymbolDatabaseAdapter.SYMBOL_FLAGS_COL);
|
byte flags = record.getByteValue(SymbolDatabaseAdapter.SYMBOL_FLAGS_COL);
|
||||||
byte clearBits = SymbolDatabaseAdapter.SYMBOL_SOURCE_BITS;
|
byte clearBits = SymbolDatabaseAdapter.SYMBOL_SOURCE_MASK;
|
||||||
byte setBits = (byte) newSource.ordinal();
|
byte setBits = SymbolDatabaseAdapter.getSourceTypeFlagsBits(newSource);
|
||||||
flags &= ~clearBits;
|
flags &= ~clearBits;
|
||||||
flags |= setBits;
|
flags |= setBits;
|
||||||
record.setByteValue(SymbolDatabaseAdapter.SYMBOL_FLAGS_COL, flags);
|
record.setByteValue(SymbolDatabaseAdapter.SYMBOL_FLAGS_COL, flags);
|
||||||
|
@ -280,10 +280,8 @@ public abstract class SymbolDB extends DatabaseObject implements Symbol {
|
||||||
if (record == null) {
|
if (record == null) {
|
||||||
return SourceType.DEFAULT;
|
return SourceType.DEFAULT;
|
||||||
}
|
}
|
||||||
byte sourceBits = SymbolDatabaseAdapter.SYMBOL_SOURCE_BITS;
|
|
||||||
byte flags = record.getByteValue(SymbolDatabaseAdapter.SYMBOL_FLAGS_COL);
|
byte flags = record.getByteValue(SymbolDatabaseAdapter.SYMBOL_FLAGS_COL);
|
||||||
byte adapterSource = (byte) (flags & sourceBits);
|
return SymbolDatabaseAdapter.decodeSourceTypeFromFlags(flags);
|
||||||
return SourceType.values()[adapterSource];
|
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
lock.release();
|
lock.release();
|
||||||
|
@ -448,8 +446,8 @@ public abstract class SymbolDB extends DatabaseObject implements Symbol {
|
||||||
|
|
||||||
private void updateSymbolSource(DBRecord symbolRecord, SourceType source) {
|
private void updateSymbolSource(DBRecord symbolRecord, SourceType source) {
|
||||||
byte flags = record.getByteValue(SymbolDatabaseAdapter.SYMBOL_FLAGS_COL);
|
byte flags = record.getByteValue(SymbolDatabaseAdapter.SYMBOL_FLAGS_COL);
|
||||||
flags &= ~SymbolDatabaseAdapter.SYMBOL_SOURCE_BITS;
|
flags &= ~SymbolDatabaseAdapter.SYMBOL_SOURCE_MASK; // clear source type bits
|
||||||
flags |= (byte) source.ordinal();
|
flags |= SymbolDatabaseAdapter.getSourceTypeFlagsBits(source);
|
||||||
symbolRecord.setByteValue(SymbolDatabaseAdapter.SYMBOL_FLAGS_COL, flags);
|
symbolRecord.setByteValue(SymbolDatabaseAdapter.SYMBOL_FLAGS_COL, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,9 +56,18 @@ abstract class SymbolDatabaseAdapter {
|
||||||
|
|
||||||
static final Schema SYMBOL_SCHEMA = SymbolDatabaseAdapterV4.V4_SYMBOL_SCHEMA;
|
static final Schema SYMBOL_SCHEMA = SymbolDatabaseAdapterV4.V4_SYMBOL_SCHEMA;
|
||||||
|
|
||||||
// Bits 0 & 1 are used for the source of the symbol.
|
// Bits 0, 1 and 3 are used for the source of the symbol.
|
||||||
static final byte SYMBOL_SOURCE_BITS = (byte) 0x3;
|
// NOTE: On the next V5 adapter revision the source type bits should be made contiguous
|
||||||
|
static final byte SYMBOL_SOURCE_LO_BITS = (byte) 0x3; // bits 0-1 of SourceType storage ID
|
||||||
static final byte SYMBOL_PINNED_FLAG = (byte) 0x4; // Bit 2 is flag for "anchored to address".
|
static final byte SYMBOL_PINNED_FLAG = (byte) 0x4; // Bit 2 is flag for "anchored to address".
|
||||||
|
static final byte SYMBOL_SOURCE_HI_BIT = (byte) 0x8; // bit-3 of SourceType storage ID
|
||||||
|
|
||||||
|
static final byte SYMBOL_SOURCE_MASK = (byte) 0xB; // (01011) Storage mask for SourceType storage ID
|
||||||
|
|
||||||
|
static final int SYMBOL_SOURCE_LO_BITS_SHIFT = 0;
|
||||||
|
static final int SYMBOL_SOURCE_HI_BIT_SHIFT = 3;
|
||||||
|
|
||||||
|
static final int MAX_SOURCE_VALUE = 7; // value limit based upon 3-bit storage capacity
|
||||||
|
|
||||||
// Symbol type constants
|
// Symbol type constants
|
||||||
static final int SYMBOL_TYPE_LABEL = SymbolType.LABEL.getID();
|
static final int SYMBOL_TYPE_LABEL = SymbolType.LABEL.getID();
|
||||||
|
@ -219,6 +228,34 @@ abstract class SymbolDatabaseAdapter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms source type storage ID to V4 flag bits.
|
||||||
|
* @param sourceType source type
|
||||||
|
* @return storage ID flag bits
|
||||||
|
*/
|
||||||
|
static byte getSourceTypeFlagsBits(SourceType sourceType) {
|
||||||
|
// Encode SourceType value into split storage flags
|
||||||
|
int sourceTypeId = sourceType.getStorageId();
|
||||||
|
if (sourceTypeId > MAX_SOURCE_VALUE) {
|
||||||
|
throw new RuntimeException("Unsupported SourceType storage ID: " + sourceTypeId);
|
||||||
|
}
|
||||||
|
int sourceTypeLoBits = (sourceTypeId & 0x3) << SYMBOL_SOURCE_LO_BITS_SHIFT; // bits 0-1
|
||||||
|
int sourceTypeHiBit = (sourceTypeId >>> 2) << SYMBOL_SOURCE_HI_BIT_SHIFT; // remaining hi-bit
|
||||||
|
return (byte) (sourceTypeHiBit | sourceTypeLoBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode V4 flags source type
|
||||||
|
* @param flags symbol flags
|
||||||
|
* @return source type
|
||||||
|
*/
|
||||||
|
static SourceType decodeSourceTypeFromFlags(byte flags) {
|
||||||
|
int sourceTypeLoBits = (flags & SYMBOL_SOURCE_LO_BITS) >>> SYMBOL_SOURCE_LO_BITS_SHIFT; // bits 0-1
|
||||||
|
int sourceTypeHiBit = (flags & SYMBOL_SOURCE_HI_BIT) >>> (SYMBOL_SOURCE_HI_BIT_SHIFT - 2); // remaining HI-bit
|
||||||
|
int sourceTypeId = sourceTypeHiBit | sourceTypeLoBits;
|
||||||
|
return SourceType.getSourceType(sourceTypeId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiate a new basic symbol record. Caller is responsible for updating any related
|
* Instantiate a new basic symbol record. Caller is responsible for updating any related
|
||||||
* optional record fields and then adding to the table via the
|
* optional record fields and then adding to the table via the
|
||||||
|
|
|
@ -97,7 +97,7 @@ class SymbolDatabaseAdapterV4 extends SymbolDatabaseAdapter {
|
||||||
// if (nextID == 0) {
|
// if (nextID == 0) {
|
||||||
// nextID++;
|
// nextID++;
|
||||||
// }
|
// }
|
||||||
// return createSymbol(nextID, name, address, namespaceID, symbolType, (byte) source.ordinal(),
|
// return createSymbol(nextID, name, address, namespaceID, symbolType, (byte) source.getStorageId(),
|
||||||
// isPrimary);
|
// isPrimary);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ class SymbolDatabaseAdapterV4 extends SymbolDatabaseAdapter {
|
||||||
rec.setLongValue(SYMBOL_ADDR_COL, addressKey);
|
rec.setLongValue(SYMBOL_ADDR_COL, addressKey);
|
||||||
rec.setLongValue(SYMBOL_PARENT_ID_COL, namespaceID);
|
rec.setLongValue(SYMBOL_PARENT_ID_COL, namespaceID);
|
||||||
rec.setByteValue(SYMBOL_TYPE_COL, symbolType.getID());
|
rec.setByteValue(SYMBOL_TYPE_COL, symbolType.getID());
|
||||||
rec.setByteValue(SYMBOL_FLAGS_COL, (byte) source.ordinal());
|
rec.setByteValue(SYMBOL_FLAGS_COL, getSourceTypeFlagsBits(source)); // assume non-pinned
|
||||||
|
|
||||||
// Sparse columns - these columns don't apply to all symbols.
|
// Sparse columns - these columns don't apply to all symbols.
|
||||||
// they default to null unless specifically set. Null values don't consume space.
|
// they default to null unless specifically set. Null values don't consume space.
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
* 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.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -15,37 +15,98 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.program.model.symbol;
|
package ghidra.program.model.symbol;
|
||||||
|
|
||||||
public enum SourceType {
|
import java.util.NoSuchElementException;
|
||||||
// WARNING WARNING: do not change the order of these enums as they are stored in the
|
|
||||||
// database by their ordinal.
|
import ghidra.program.model.listing.Program;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link SourceType} provides a prioritized indication as to the general source of a specific
|
||||||
|
* markup made to a {@link Program}. The priority of each defined source type may be used to
|
||||||
|
* restrict impact or protect the related markup. Source types include: {@link #USER_DEFINED},
|
||||||
|
* which is higher priority than {@link #IMPORTED}, which is higher priority than {@link #ANALYSIS},
|
||||||
|
* which is higher priority than {@link #DEFAULT}. The {@link #AI} source type is primarliy
|
||||||
|
* intended to allow AI generated markup to be identified and currently has the same priority
|
||||||
|
* as {@link #ANALYSIS}.
|
||||||
|
*/
|
||||||
|
public enum SourceType {
|
||||||
|
// WARNING WARNING: the assigned storage IDs are used for persistent serialization.
|
||||||
|
// Any change or re-use must consider data upgrade concerns.
|
||||||
|
|
||||||
/** The object's source indicator for an auto analysis. */
|
|
||||||
ANALYSIS("Analysis", 2),
|
|
||||||
/** The object's source indicator for a user defined. */
|
|
||||||
USER_DEFINED("User Defined", 4),
|
|
||||||
/** The object's source indicator for a default. */
|
/** The object's source indicator for a default. */
|
||||||
DEFAULT("Default", 1),
|
DEFAULT("Default", 1, 2),
|
||||||
|
/** The object's source indicator for an auto analysis. */
|
||||||
|
ANALYSIS("Analysis", 2, 0),
|
||||||
|
/** The object's source indicator for something that was produced with AI assistance. */
|
||||||
|
AI("AI", 2, 4),
|
||||||
/** The object's source indicator for an imported. */
|
/** The object's source indicator for an imported. */
|
||||||
IMPORTED("Imported", 3);
|
IMPORTED("Imported", 3, 3),
|
||||||
|
/** The object's source indicator for a user defined. */
|
||||||
|
USER_DEFINED("User Defined", 4, 1);
|
||||||
|
|
||||||
|
// SourceType values indexed by storageID (use null for undefined IDs).
|
||||||
|
private static SourceType[] SOURCE_BY_STORAGE_ID =
|
||||||
|
new SourceType[] { ANALYSIS, USER_DEFINED, DEFAULT, IMPORTED, AI };
|
||||||
|
|
||||||
private final String displayString;
|
private final String displayString;
|
||||||
private final int priority; // bigger numbers are higher priorty
|
private final int storageId;
|
||||||
|
private final int priority; // bigger numbers are higher priority
|
||||||
|
|
||||||
private SourceType(String displayString, int priority) {
|
/**
|
||||||
|
* {@link SourceType} constructor
|
||||||
|
* @param displayString enum display name
|
||||||
|
* @param priority unique priority among other defined enum values
|
||||||
|
* @param storageId non-negative storage ID for persistent serialization. Once an ID is
|
||||||
|
* assigned it may never be removed without serious consideration to DB upgrade transformation.
|
||||||
|
*/
|
||||||
|
private SourceType(String displayString, int priority, int storageId) {
|
||||||
this.displayString = displayString;
|
this.displayString = displayString;
|
||||||
|
this.storageId = storageId;
|
||||||
this.priority = priority;
|
this.priority = priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a user-friendly string */
|
/**
|
||||||
|
* Get the SourceType which corresponds to the specified storage ID.
|
||||||
|
* @param storageId storage ID
|
||||||
|
* @return SourceType
|
||||||
|
* @throws NoSuchElementException if specified storage ID is not defined.
|
||||||
|
*/
|
||||||
|
public static SourceType getSourceType(int storageId) {
|
||||||
|
try {
|
||||||
|
SourceType source = SOURCE_BY_STORAGE_ID[storageId];
|
||||||
|
if (source != null) {
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ArrayIndexOutOfBoundsException e) {
|
||||||
|
// throw error below
|
||||||
|
}
|
||||||
|
throw new NoSuchElementException("SourceType storgae ID not defined: " + storageId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return numeric priority relative to other SourceType. Higher numbers are higher priority.}
|
||||||
|
*/
|
||||||
|
public int getPriority() {
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the storage ID which should be used for persistent serialization}
|
||||||
|
*/
|
||||||
|
public int getStorageId() {
|
||||||
|
return storageId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return a user-friendly string}
|
||||||
|
*/
|
||||||
public String getDisplayString() {
|
public String getDisplayString() {
|
||||||
return displayString;
|
return displayString;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if this source type is a higher priority than the one being
|
* Determine if this source type has a higher priority than the one being
|
||||||
* passed to this method as a parameter.
|
* passed to this method as a parameter.
|
||||||
* USER_DEFINED objects are higher priority than IMPORTED objects which are higher
|
|
||||||
* priority than ANALYSIS objects which are higher priority than DEFAULT objects.
|
|
||||||
* @param source the source type whose priority is to be compared with this one's.
|
* @param source the source type whose priority is to be compared with this one's.
|
||||||
* @return true if this source type is a higher priority.
|
* @return true if this source type is a higher priority.
|
||||||
* false if this source type is the same priority or lower priority.
|
* false if this source type is the same priority or lower priority.
|
||||||
|
@ -55,10 +116,19 @@ public enum SourceType {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if this source type is a lower priority than the one being
|
* Determine if this source type has the same or higher priority than the one being
|
||||||
|
* passed to this method as a parameter.
|
||||||
|
* @param source the source type whose priority is to be compared with this one's.
|
||||||
|
* @return true if this source type is a higher priority.
|
||||||
|
* false if this source type is the same priority or lower priority.
|
||||||
|
*/
|
||||||
|
public boolean isHigherOrEqualPriorityThan(SourceType source) {
|
||||||
|
return this.priority >= source.priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if this source type has a lower priority than the one being
|
||||||
* passed to this method as a parameter.
|
* passed to this method as a parameter.
|
||||||
* DEFAULT objects are lower priority than ANALYSIS objects which are lower
|
|
||||||
* priority than IMPORTED objects which are lower priority than USER_DEFINED objects.
|
|
||||||
* @param source the source type whose priority is to be compared with this one's.
|
* @param source the source type whose priority is to be compared with this one's.
|
||||||
* @return true if this source type is a lower priority.
|
* @return true if this source type is a lower priority.
|
||||||
* false if this source type is the same priority or higher priority.
|
* false if this source type is the same priority or higher priority.
|
||||||
|
@ -66,4 +136,15 @@ public enum SourceType {
|
||||||
public boolean isLowerPriorityThan(SourceType source) {
|
public boolean isLowerPriorityThan(SourceType source) {
|
||||||
return this.priority < source.priority;
|
return this.priority < source.priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if this source type has the same or lower priority than the one being
|
||||||
|
* passed to this method as a parameter.
|
||||||
|
* @param source the source type whose priority is to be compared with this one's.
|
||||||
|
* @return true if this source type is a lower priority.
|
||||||
|
* false if this source type is the same priority or higher priority.
|
||||||
|
*/
|
||||||
|
public boolean isLowerOrEqualPriorityThan(SourceType source) {
|
||||||
|
return this.priority <= source.priority;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ data/languages/AARCH64.slaspec||GHIDRA||||END|
|
||||||
data/languages/AARCH64BE.slaspec||GHIDRA||||END|
|
data/languages/AARCH64BE.slaspec||GHIDRA||||END|
|
||||||
data/languages/AARCH64_AMXext.sinc||GHIDRA||||END|
|
data/languages/AARCH64_AMXext.sinc||GHIDRA||||END|
|
||||||
data/languages/AARCH64_AppleSilicon.slaspec||GHIDRA||||END|
|
data/languages/AARCH64_AppleSilicon.slaspec||GHIDRA||||END|
|
||||||
|
data/languages/AARCH64_apple.cspec||GHIDRA||||END|
|
||||||
data/languages/AARCH64_base_PACoptions.sinc||GHIDRA||||END|
|
data/languages/AARCH64_base_PACoptions.sinc||GHIDRA||||END|
|
||||||
data/languages/AARCH64_golang.cspec||GHIDRA||||END|
|
data/languages/AARCH64_golang.cspec||GHIDRA||||END|
|
||||||
data/languages/AARCH64_golang.register.info||GHIDRA||||END|
|
data/languages/AARCH64_golang.register.info||GHIDRA||||END|
|
||||||
|
|
270
Ghidra/Processors/AARCH64/data/languages/AARCH64_apple.cspec
Normal file
270
Ghidra/Processors/AARCH64/data/languages/AARCH64_apple.cspec
Normal file
|
@ -0,0 +1,270 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<compiler_spec>
|
||||||
|
<data_organization>
|
||||||
|
<absolute_max_alignment value="0" />
|
||||||
|
<machine_alignment value="4" />
|
||||||
|
<default_alignment value="1" />
|
||||||
|
<default_pointer_alignment value="8" />
|
||||||
|
<pointer_size value="8" />
|
||||||
|
<wchar_size value="4" />
|
||||||
|
<short_size value="2" />
|
||||||
|
<integer_size value="4" />
|
||||||
|
<long_size value="8" />
|
||||||
|
<long_long_size value="8" />
|
||||||
|
<float_size value="4" />
|
||||||
|
<double_size value="8" />
|
||||||
|
<long_double_size value="8" />
|
||||||
|
<size_alignment_map>
|
||||||
|
<entry size="1" alignment="1" />
|
||||||
|
<entry size="2" alignment="2" />
|
||||||
|
<entry size="4" alignment="4" />
|
||||||
|
<entry size="8" alignment="8" />
|
||||||
|
<entry size="16" alignment="16"/>
|
||||||
|
</size_alignment_map>
|
||||||
|
</data_organization>
|
||||||
|
|
||||||
|
<global>
|
||||||
|
<range space="ram"/>
|
||||||
|
</global>
|
||||||
|
|
||||||
|
<stackpointer register="sp" space="ram"/>
|
||||||
|
<funcptr align="4"/> <!-- Function pointers are word aligned and leastsig bit may encode otherstuff -->
|
||||||
|
|
||||||
|
<prefersplit style="inhalf">
|
||||||
|
<register name="q0"/>
|
||||||
|
<register name="q1"/>
|
||||||
|
<register name="q2"/>
|
||||||
|
<register name="q3"/>
|
||||||
|
<register name="q4"/>
|
||||||
|
<register name="q5"/>
|
||||||
|
<register name="q6"/>
|
||||||
|
<register name="q7"/>
|
||||||
|
<register name="q8"/>
|
||||||
|
<register name="q9"/>
|
||||||
|
<register name="q10"/>
|
||||||
|
<register name="q11"/>
|
||||||
|
<register name="q12"/>
|
||||||
|
<register name="q13"/>
|
||||||
|
<register name="q14"/>
|
||||||
|
<register name="q15"/>
|
||||||
|
<register name="q16"/>
|
||||||
|
<register name="q17"/>
|
||||||
|
<register name="q18"/>
|
||||||
|
<register name="q19"/>
|
||||||
|
<register name="q20"/>
|
||||||
|
<register name="q21"/>
|
||||||
|
<register name="q22"/>
|
||||||
|
<register name="q23"/>
|
||||||
|
<register name="q24"/>
|
||||||
|
<register name="q25"/>
|
||||||
|
<register name="q26"/>
|
||||||
|
<register name="q27"/>
|
||||||
|
<register name="q28"/>
|
||||||
|
<register name="q29"/>
|
||||||
|
<register name="q30"/>
|
||||||
|
</prefersplit>
|
||||||
|
|
||||||
|
<default_proto>
|
||||||
|
<prototype name="__cdecl" extrapop="0" stackshift="0">
|
||||||
|
<input>
|
||||||
|
<pentry minsize="8" maxsize="8" storage="hiddenret">
|
||||||
|
<register name="x8"/>
|
||||||
|
</pentry>
|
||||||
|
<pentry minsize="1" maxsize="16" storage="float">
|
||||||
|
<register name="q0"/>
|
||||||
|
</pentry>
|
||||||
|
<pentry minsize="1" maxsize="16" storage="float">
|
||||||
|
<register name="q1"/>
|
||||||
|
</pentry>
|
||||||
|
<pentry minsize="1" maxsize="16" storage="float">
|
||||||
|
<register name="q2"/>
|
||||||
|
</pentry>
|
||||||
|
<pentry minsize="1" maxsize="16" storage="float">
|
||||||
|
<register name="q3"/>
|
||||||
|
</pentry>
|
||||||
|
<pentry minsize="1" maxsize="16" storage="float">
|
||||||
|
<register name="q4"/>
|
||||||
|
</pentry>
|
||||||
|
<pentry minsize="1" maxsize="16" storage="float">
|
||||||
|
<register name="q5"/>
|
||||||
|
</pentry>
|
||||||
|
<pentry minsize="1" maxsize="16" storage="float">
|
||||||
|
<register name="q6"/>
|
||||||
|
</pentry>
|
||||||
|
<pentry minsize="1" maxsize="16" storage="float">
|
||||||
|
<register name="q7"/>
|
||||||
|
</pentry>
|
||||||
|
<pentry minsize="1" maxsize="8" extension="zero">
|
||||||
|
<register name="x0"/>
|
||||||
|
</pentry>
|
||||||
|
<pentry minsize="1" maxsize="8" extension="zero">
|
||||||
|
<register name="x1"/>
|
||||||
|
</pentry>
|
||||||
|
<pentry minsize="1" maxsize="8" extension="zero">
|
||||||
|
<register name="x2"/>
|
||||||
|
</pentry>
|
||||||
|
<pentry minsize="1" maxsize="8" extension="zero">
|
||||||
|
<register name="x3"/>
|
||||||
|
</pentry>
|
||||||
|
<pentry minsize="1" maxsize="8" extension="zero">
|
||||||
|
<register name="x4"/>
|
||||||
|
</pentry>
|
||||||
|
<pentry minsize="1" maxsize="8" extension="zero">
|
||||||
|
<register name="x5"/>
|
||||||
|
</pentry>
|
||||||
|
<pentry minsize="1" maxsize="8" extension="zero">
|
||||||
|
<register name="x6"/>
|
||||||
|
</pentry>
|
||||||
|
<pentry minsize="1" maxsize="8" extension="zero">
|
||||||
|
<register name="x7"/>
|
||||||
|
</pentry>
|
||||||
|
<pentry minsize="1" maxsize="500" align="8">
|
||||||
|
<addr offset="0" space="stack"/>
|
||||||
|
</pentry>
|
||||||
|
<rule>
|
||||||
|
<datatype name="homogeneous-float-aggregate"/>
|
||||||
|
<join_per_primitive storage="float"/>
|
||||||
|
</rule>
|
||||||
|
<rule>
|
||||||
|
<datatype name="homogeneous-float-aggregate"/>
|
||||||
|
<goto_stack/> <!-- Don't consume general purpose registers -->
|
||||||
|
<consume_extra storage="float"/> <!-- Once the stack has been used, don't go back to registers -->
|
||||||
|
</rule>
|
||||||
|
<rule>
|
||||||
|
<datatype name="struct" minsize="17"/>
|
||||||
|
<convert_to_ptr/>
|
||||||
|
</rule>
|
||||||
|
<rule>
|
||||||
|
<datatype name="union" minsize="17"/>
|
||||||
|
<convert_to_ptr/>
|
||||||
|
</rule>
|
||||||
|
<!-- Variadic arguments are passed differently than in the AARCH64 standard -->
|
||||||
|
<!-- See "Writing ARM64 Code for Apple Platforms" -->
|
||||||
|
<rule>
|
||||||
|
<datatype name="any"/>
|
||||||
|
<varargs first="0"/>
|
||||||
|
<goto_stack/>
|
||||||
|
</rule>
|
||||||
|
<rule>
|
||||||
|
<datatype name="float"/>
|
||||||
|
<consume storage="float"/>
|
||||||
|
</rule>
|
||||||
|
<rule>
|
||||||
|
<datatype name="float"/>
|
||||||
|
<goto_stack/> <!-- Don't consume general purpose registers -->
|
||||||
|
</rule>
|
||||||
|
<rule>
|
||||||
|
<datatype name="any"/>
|
||||||
|
<join align="true"/> <!-- Chunk from general purpose registers -->
|
||||||
|
</rule>
|
||||||
|
</input>
|
||||||
|
<output>
|
||||||
|
<pentry minsize="1" maxsize="16" storage="float">
|
||||||
|
<register name="q0"/>
|
||||||
|
</pentry>
|
||||||
|
<pentry minsize="1" maxsize="16" storage="float">
|
||||||
|
<register name="q1"/>
|
||||||
|
</pentry>
|
||||||
|
<pentry minsize="1" maxsize="16" storage="float">
|
||||||
|
<register name="q2"/>
|
||||||
|
</pentry>
|
||||||
|
<pentry minsize="1" maxsize="16" storage="float">
|
||||||
|
<register name="q3"/>
|
||||||
|
</pentry>
|
||||||
|
<pentry minsize="1" maxsize="8" extension="zero">
|
||||||
|
<register name="x0"/>
|
||||||
|
</pentry>
|
||||||
|
<pentry minsize="1" maxsize="8" extension="zero">
|
||||||
|
<register name="x1"/>
|
||||||
|
</pentry>
|
||||||
|
<rule>
|
||||||
|
<datatype name="homogeneous-float-aggregate"/>
|
||||||
|
<join_per_primitive storage="float"/>
|
||||||
|
</rule>
|
||||||
|
<rule>
|
||||||
|
<datatype name="float"/>
|
||||||
|
<consume storage="float"/>
|
||||||
|
</rule>
|
||||||
|
<rule>
|
||||||
|
<datatype name="any" minsize="17"/>
|
||||||
|
<hidden_return voidlock="true"/>
|
||||||
|
</rule>
|
||||||
|
<rule>
|
||||||
|
<datatype name="any"/>
|
||||||
|
<join/>
|
||||||
|
</rule>
|
||||||
|
</output>
|
||||||
|
<unaffected>
|
||||||
|
<register name="x19"/>
|
||||||
|
<register name="x20"/>
|
||||||
|
<register name="x21"/>
|
||||||
|
<register name="x22"/>
|
||||||
|
<register name="x23"/>
|
||||||
|
<register name="x24"/>
|
||||||
|
<register name="x25"/>
|
||||||
|
<register name="x26"/>
|
||||||
|
<register name="x27"/>
|
||||||
|
<register name="x28"/>
|
||||||
|
<register name="x29"/>
|
||||||
|
<register name="x30"/>
|
||||||
|
<register name="sp"/>
|
||||||
|
<!-- vectors -->
|
||||||
|
<register name="d8"/>
|
||||||
|
<register name="d9"/>
|
||||||
|
<register name="d10"/>
|
||||||
|
<register name="d11"/>
|
||||||
|
<register name="d12"/>
|
||||||
|
<register name="d13"/>
|
||||||
|
<register name="d14"/>
|
||||||
|
<register name="d15"/>
|
||||||
|
</unaffected>
|
||||||
|
<killedbycall>
|
||||||
|
<register name="x0"/>
|
||||||
|
<register name="x1"/>
|
||||||
|
<register name="q0"/>
|
||||||
|
<!-- x8: indirect result location register, which is not
|
||||||
|
reflected in the pentry list -->
|
||||||
|
<register name="x8"/>
|
||||||
|
<register name="x9"/>
|
||||||
|
<register name="x10"/>
|
||||||
|
<register name="x11"/>
|
||||||
|
<register name="x12"/>
|
||||||
|
<register name="x13"/>
|
||||||
|
<register name="x14"/>
|
||||||
|
<register name="x15"/>
|
||||||
|
<register name="x16"/>
|
||||||
|
<register name="x17"/>
|
||||||
|
<register name="x18"/>
|
||||||
|
<!-- vectors -->
|
||||||
|
<register name="d16"/>
|
||||||
|
<register name="d17"/>
|
||||||
|
<register name="d18"/>
|
||||||
|
<register name="d19"/>
|
||||||
|
<register name="d20"/>
|
||||||
|
<register name="d21"/>
|
||||||
|
<register name="d22"/>
|
||||||
|
<register name="d23"/>
|
||||||
|
<register name="d24"/>
|
||||||
|
<register name="d25"/>
|
||||||
|
<register name="d26"/>
|
||||||
|
<register name="d27"/>
|
||||||
|
<register name="d28"/>
|
||||||
|
<register name="d29"/>
|
||||||
|
<register name="d30"/>
|
||||||
|
<register name="d31"/>
|
||||||
|
</killedbycall>
|
||||||
|
</prototype>
|
||||||
|
</default_proto>
|
||||||
|
|
||||||
|
|
||||||
|
<callfixup name="PlaceHolderCallFixup"> <!-- This is here just to force call fixup and NoReturn fixup. Will be fixed in Ghidra V6.0 -->
|
||||||
|
<target name="___NotARealFunctionName___"/>
|
||||||
|
<pcode>
|
||||||
|
<body><![CDATA[
|
||||||
|
tmpptr:4 = 0;
|
||||||
|
]]></body>
|
||||||
|
</pcode>
|
||||||
|
</callfixup>
|
||||||
|
|
||||||
|
</compiler_spec>
|
|
@ -10,7 +10,7 @@
|
||||||
manualindexfile="../manuals/AARCH64.idx"
|
manualindexfile="../manuals/AARCH64.idx"
|
||||||
id="AARCH64:LE:64:AppleSilicon">
|
id="AARCH64:LE:64:AppleSilicon">
|
||||||
<description>AppleSilicon ARM v8.5-A LE instructions, LE data, AMX extensions</description>
|
<description>AppleSilicon ARM v8.5-A LE instructions, LE data, AMX extensions</description>
|
||||||
<compiler name="default" spec="AARCH64.cspec" id="default"/>
|
<compiler name="default" spec="AARCH64_apple.cspec" id="default"/>
|
||||||
<compiler name="Swift" spec="AARCH64_swift.cspec" id="swift"/>
|
<compiler name="Swift" spec="AARCH64_swift.cspec" id="swift"/>
|
||||||
<compiler name="golang" spec="AARCH64_golang.cspec" id="golang"/>
|
<compiler name="golang" spec="AARCH64_golang.cspec" id="golang"/>
|
||||||
<external_name tool="gnu" name="aarch64"/>
|
<external_name tool="gnu" name="aarch64"/>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue