mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-09 20:18:01 +08:00
Merge branch 'GP-2308_1633_ghidra1_FunctionDefinitionCallingConventions'
(Closes #4537, Closes #4898, Closes #3723, Closes #3267)
This commit is contained in:
+3
-3
@@ -264,9 +264,9 @@ class SymPcodeExecutor extends PcodeExecutor<Sym> {
|
||||
// TODO: Does the decompiler communicate the inferred calling convention?
|
||||
try {
|
||||
PrototypeModel convention = program.getCompilerSpec().findBestCallingConvention(params);
|
||||
sig.setGenericCallingConvention(convention.getGenericCallingConvention());
|
||||
sig.setCallingConvention(convention.getName());
|
||||
}
|
||||
catch (SleighException e) {
|
||||
catch (SleighException | InvalidInputException e) {
|
||||
// Whatever, just leave sig at "unknown"
|
||||
}
|
||||
return sig;
|
||||
@@ -352,7 +352,7 @@ class SymPcodeExecutor extends PcodeExecutor<Sym> {
|
||||
throw new PcodeExecutionException("Cannot get stack change for indirect call: " + op);
|
||||
}
|
||||
PrototypeModel convention =
|
||||
program.getCompilerSpec().matchConvention(sig.getGenericCallingConvention());
|
||||
program.getCompilerSpec().matchConvention(sig.getCallingConventionName());
|
||||
if (convention == null) {
|
||||
warnings.add(new UnspecifiedConventionStackUnwindWarning(null));
|
||||
convention = program.getCompilerSpec().getDefaultCallingConvention();
|
||||
|
||||
+25
-10
@@ -24,7 +24,9 @@ import db.DBHandle;
|
||||
import ghidra.framework.model.DomainFile;
|
||||
import ghidra.program.database.data.ProgramBasedDataTypeManagerDB;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressFactory;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.lang.*;
|
||||
import ghidra.trace.database.DBTrace;
|
||||
import ghidra.trace.database.DBTraceManager;
|
||||
import ghidra.trace.model.data.TraceBasedDataTypeManager;
|
||||
@@ -38,15 +40,36 @@ import ghidra.util.task.TaskMonitor;
|
||||
public class DBTraceDataTypeManager extends ProgramBasedDataTypeManagerDB
|
||||
implements TraceBasedDataTypeManager, DBTraceManager {
|
||||
|
||||
protected final ReadWriteLock lock;
|
||||
protected final ReadWriteLock lock; // TODO: This lock object is not used
|
||||
protected final DBTrace trace;
|
||||
|
||||
private static final String INSTANCE_TABLE_PREFIX = null; // placeholder only
|
||||
|
||||
public DBTraceDataTypeManager(DBHandle dbh, DBOpenMode openMode, ReadWriteLock lock,
|
||||
TaskMonitor monitor, DBTrace trace)
|
||||
throws CancelledException, VersionException, IOException {
|
||||
super(dbh, null, openMode.toInteger(), trace, trace.getLock(), monitor);
|
||||
super(dbh, null, openMode.toInteger(), INSTANCE_TABLE_PREFIX, trace, trace.getLock(),
|
||||
monitor);
|
||||
this.lock = lock; // TODO: nothing uses this local lock - not sure what its purpose is
|
||||
this.trace = trace;
|
||||
|
||||
setProgramArchitecture(new ProgramArchitecture() {
|
||||
|
||||
@Override
|
||||
public Language getLanguage() {
|
||||
return trace.getBaseLanguage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompilerSpec getCompilerSpec() {
|
||||
return trace.getBaseCompilerSpec();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AddressFactory getAddressFactory() {
|
||||
return trace.getBaseAddressFactory();
|
||||
}
|
||||
}, null, false, monitor);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -233,12 +256,4 @@ public class DBTraceDataTypeManager extends ProgramBasedDataTypeManagerDB
|
||||
*/
|
||||
return ArchiveType.PROGRAM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataOrganization getDataOrganization() {
|
||||
if (dataOrganization == null) {
|
||||
dataOrganization = trace.getBaseCompilerSpec().getDataOrganization();
|
||||
}
|
||||
return dataOrganization;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-8
@@ -15,11 +15,11 @@
|
||||
*/
|
||||
package ghidra.trace.database.program;
|
||||
|
||||
import static ghidra.lifecycle.Unfinished.TODO;
|
||||
import static ghidra.lifecycle.Unfinished.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import generic.NestedIterator;
|
||||
import ghidra.program.database.ProgramDB;
|
||||
@@ -64,7 +64,7 @@ public class DBTraceProgramViewFunctionManager implements FunctionManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getCallingConventionNames() {
|
||||
public Collection<String> getCallingConventionNames() {
|
||||
return functions.getCallingConventionNames();
|
||||
}
|
||||
|
||||
@@ -78,11 +78,6 @@ public class DBTraceProgramViewFunctionManager implements FunctionManager {
|
||||
return functions.getCallingConvention(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrototypeModel[] getCallingConventions() {
|
||||
return functions.getCallingConventions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TraceFunctionSymbol createFunction(String name, Address entryPoint, AddressSetView body,
|
||||
SourceType source) throws InvalidInputException, OverlappingFunctionException {
|
||||
|
||||
+22
-34
@@ -22,6 +22,7 @@ import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import db.DBRecord;
|
||||
import ghidra.program.database.data.DataTypeManagerDB;
|
||||
import ghidra.program.database.function.OverlappingFunctionException;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.data.*;
|
||||
@@ -33,6 +34,7 @@ import ghidra.program.model.symbol.*;
|
||||
import ghidra.trace.database.address.DBTraceOverlaySpaceAdapter.AddressDBFieldCodec;
|
||||
import ghidra.trace.database.address.DBTraceOverlaySpaceAdapter.DecodesAddresses;
|
||||
import ghidra.trace.database.bookmark.DBTraceBookmarkType;
|
||||
import ghidra.trace.database.data.DBTraceDataTypeManager;
|
||||
import ghidra.trace.database.listing.DBTraceCommentAdapter;
|
||||
import ghidra.trace.database.listing.DBTraceData;
|
||||
import ghidra.trace.database.program.DBTraceProgramView;
|
||||
@@ -122,7 +124,7 @@ public class DBTraceFunctionSymbol extends DBTraceNamespaceSymbol
|
||||
@DBAnnotatedField(column = FIXUP_COLUMN_NAME)
|
||||
protected String callFixup;
|
||||
@DBAnnotatedField(column = CALLING_CONVENTION_COLUMN_NAME)
|
||||
protected byte callingConventionID = DBTraceSymbolManager.DEFAULT_CALLING_CONVENTION_ID;
|
||||
protected byte callingConventionID = DataTypeManagerDB.UNKNOWN_CALLING_CONVENTION_ID;
|
||||
// TODO: Pack into flags if more bits needed
|
||||
@DBAnnotatedField(column = SIGNATURE_SOURCE_COLUMN_NAME)
|
||||
protected SourceType signatureSource = SourceType.ANALYSIS; // Assumed default, 0-ordinal
|
||||
@@ -484,7 +486,8 @@ public class DBTraceFunctionSymbol extends DBTraceNamespaceSymbol
|
||||
}
|
||||
|
||||
protected boolean hasExplicitCallingConvention() {
|
||||
return callingConventionID != -1 && callingConventionID != -2;
|
||||
return callingConventionID != DataTypeManagerDB.DEFAULT_CALLING_CONVENTION_ID &&
|
||||
callingConventionID != DataTypeManagerDB.UNKNOWN_CALLING_CONVENTION_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1734,16 +1737,14 @@ public class DBTraceFunctionSymbol extends DBTraceNamespaceSymbol
|
||||
if (cs == null) {
|
||||
return null;
|
||||
}
|
||||
if (DBTraceSymbolManager.UNKNOWN_CALLING_CONVENTION_ID == callingConventionID) {
|
||||
DBTraceDataTypeManager dtm = manager.dataTypeManager;
|
||||
if (callingConventionID == DataTypeManagerDB.UNKNOWN_CALLING_CONVENTION_ID) {
|
||||
return null;
|
||||
}
|
||||
if (DBTraceSymbolManager.DEFAULT_CALLING_CONVENTION_ID == callingConventionID) {
|
||||
if (callingConventionID == DataTypeManagerDB.DEFAULT_CALLING_CONVENTION_ID) {
|
||||
return cs.getDefaultCallingConvention();
|
||||
}
|
||||
String ccName = manager.callingConventionMap.getKey(callingConventionID);
|
||||
if (ccName == null) {
|
||||
return null;
|
||||
}
|
||||
String ccName = dtm.getCallingConventionName(callingConventionID);
|
||||
return cs.getCallingConvention(ccName);
|
||||
}
|
||||
}
|
||||
@@ -1751,28 +1752,8 @@ public class DBTraceFunctionSymbol extends DBTraceNamespaceSymbol
|
||||
@Override
|
||||
public String getCallingConventionName() {
|
||||
try (LockHold hold = LockHold.lock(manager.lock.readLock())) {
|
||||
if (DBTraceSymbolManager.UNKNOWN_CALLING_CONVENTION_ID == callingConventionID) {
|
||||
return null;
|
||||
}
|
||||
if (DBTraceSymbolManager.DEFAULT_CALLING_CONVENTION_ID == callingConventionID) {
|
||||
return DBTraceSymbolManager.DEFAULT_CALLING_CONVENTION_NAME;
|
||||
}
|
||||
return manager.callingConventionMap.getKey(callingConventionID);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefaultCallingConventionName() {
|
||||
try (LockHold hold = LockHold.lock(manager.lock.readLock())) {
|
||||
PrototypeModel cc = manager.functions.getDefaultCallingConvention();
|
||||
if (cc == null) {
|
||||
return DBTraceSymbolManager.DEFAULT_CALLING_CONVENTION_NAME;
|
||||
}
|
||||
String ccName = cc.getName();
|
||||
if (ccName == null) { // Really?
|
||||
return DBTraceSymbolManager.DEFAULT_CALLING_CONVENTION_NAME;
|
||||
}
|
||||
return ccName;
|
||||
DBTraceDataTypeManager dtm = manager.dataTypeManager;
|
||||
return dtm.getCallingConventionName(callingConventionID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1783,12 +1764,16 @@ public class DBTraceFunctionSymbol extends DBTraceNamespaceSymbol
|
||||
thunked.setCallingConvention(name);
|
||||
return;
|
||||
}
|
||||
if (Objects.equals(getCallingConventionName(), name)) {
|
||||
return;
|
||||
|
||||
DBTraceDataTypeManager dtm = manager.dataTypeManager;
|
||||
byte id = dtm.getCallingConventionID(name, true);
|
||||
if (id == callingConventionID) {
|
||||
return; // no change
|
||||
}
|
||||
|
||||
doLoadVariables();
|
||||
|
||||
this.callingConventionID = manager.findOrRecordCallingConvention(name);
|
||||
callingConventionID = id;
|
||||
update(CALLING_CONVENTION_COLUMN);
|
||||
|
||||
boolean hasCustomStorage = hasCustomVariableStorage();
|
||||
@@ -1813,11 +1798,14 @@ public class DBTraceFunctionSymbol extends DBTraceNamespaceSymbol
|
||||
new TraceChangeRecord<>(TraceFunctionChangeType.CHANGED, getSpace(), this));
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
manager.dbError(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void createClassStructIfNeeded() {
|
||||
PrototypeModel cc = getCallingConvention();
|
||||
if (cc == null || cc.getGenericCallingConvention() != GenericCallingConvention.thiscall) {
|
||||
if (cc == null || !CompilerSpec.CALLING_CONVENTION_thiscall.equals(cc.getName())) {
|
||||
return;
|
||||
}
|
||||
Namespace parentNS = getParentNamespace();
|
||||
|
||||
+5
-41
@@ -15,8 +15,7 @@
|
||||
*/
|
||||
package ghidra.trace.database.symbol;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
import ghidra.program.database.function.OverlappingFunctionException;
|
||||
import ghidra.program.database.symbol.OverlappingNamespaceException;
|
||||
@@ -165,54 +164,19 @@ public class DBTraceFunctionSymbolView
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String> getCallingConventionNames(CompilerSpec cs) {
|
||||
PrototypeModel[] namedCCs = cs.getCallingConventions();
|
||||
List<String> names = new ArrayList<>(2 + namedCCs.length);
|
||||
names.add(Function.UNKNOWN_CALLING_CONVENTION_STRING);
|
||||
names.add(Function.DEFAULT_CALLING_CONVENTION_STRING);
|
||||
for (PrototypeModel model : namedCCs) {
|
||||
names.add(model.getName());
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getCallingConventionNames() {
|
||||
// TODO: Allow for user-selected compiler spec(s)
|
||||
return getCallingConventionNames(manager.trace.getBaseCompilerSpec());
|
||||
public Collection<String> getCallingConventionNames() {
|
||||
return manager.dataTypeManager.getDefinedCallingConventionNames();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrototypeModel getDefaultCallingConvention() {
|
||||
CompilerSpec cs = manager.trace.getBaseCompilerSpec();
|
||||
if (cs == null) {
|
||||
return null;
|
||||
}
|
||||
return cs.getDefaultCallingConvention();
|
||||
return manager.dataTypeManager.getDefaultCallingConvention();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrototypeModel getCallingConvention(String name) {
|
||||
CompilerSpec cs = manager.trace.getBaseCompilerSpec();
|
||||
if (cs == null) {
|
||||
return null;
|
||||
}
|
||||
if (Function.UNKNOWN_CALLING_CONVENTION_STRING.equals(name)) {
|
||||
return null;
|
||||
}
|
||||
if (Function.DEFAULT_CALLING_CONVENTION_STRING.equals(name)) {
|
||||
return cs.getDefaultCallingConvention();
|
||||
}
|
||||
return cs.getCallingConvention(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrototypeModel[] getCallingConventions() {
|
||||
CompilerSpec cs = manager.trace.getBaseCompilerSpec();
|
||||
if (cs == null) {
|
||||
return EMPTY_MODEL_LIST;
|
||||
}
|
||||
return cs.getCallingConventions();
|
||||
return manager.dataTypeManager.getCallingConvention(name);
|
||||
}
|
||||
|
||||
// TODO: Move this into a FunctionUtilities class?
|
||||
|
||||
+1
-67
@@ -20,9 +20,6 @@ import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
|
||||
import org.apache.commons.collections4.BidiMap;
|
||||
import org.apache.commons.collections4.bidimap.DualHashBidiMap;
|
||||
|
||||
import db.*;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.data.DataType;
|
||||
@@ -60,11 +57,6 @@ import ghidra.util.task.TaskMonitor;
|
||||
* TODO: See if CALL-type references produce dynamic labels or functions.
|
||||
*/
|
||||
public class DBTraceSymbolManager implements TraceSymbolManager, DBTraceManager {
|
||||
protected static final byte DEFAULT_CALLING_CONVENTION_ID = -1;
|
||||
protected static final byte UNKNOWN_CALLING_CONVENTION_ID = -2;
|
||||
|
||||
protected static final String DEFAULT_CALLING_CONVENTION_NAME = "default";
|
||||
protected static final String UNKNOWN_CALLING_CONVENTION_NAME = "unknown";
|
||||
|
||||
private static final long TYPE_MASK = 0xFF;
|
||||
private static final int TYPE_SHIFT = 64 - 8;
|
||||
@@ -101,32 +93,6 @@ public class DBTraceSymbolManager implements TraceSymbolManager, DBTraceManager
|
||||
}
|
||||
}
|
||||
|
||||
@DBAnnotatedObjectInfo(version = 0)
|
||||
public static class DBTraceCallingConventionEntry extends DBAnnotatedObject {
|
||||
static final String TABLE_NAME = "CallingConventions";
|
||||
|
||||
static final String NAME_COLUMN_NAME = "Name";
|
||||
|
||||
@DBAnnotatedColumn(NAME_COLUMN_NAME)
|
||||
static DBObjectColumn NAME_COLUMN;
|
||||
|
||||
@DBAnnotatedField(column = NAME_COLUMN_NAME)
|
||||
String name;
|
||||
|
||||
public DBTraceCallingConventionEntry(DBCachedObjectStore<?> store, DBRecord record) {
|
||||
super(store, record);
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
update(NAME_COLUMN);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
@DBAnnotatedObjectInfo(version = 0)
|
||||
public static class DBTraceFunctionTag extends DBAnnotatedObject implements FunctionTag {
|
||||
|
||||
@@ -435,9 +401,6 @@ public class DBTraceSymbolManager implements TraceSymbolManager, DBTraceManager
|
||||
|
||||
protected final DBTraceAddressSnapRangePropertyMap<Long, DBTraceSymbolIDEntry> idMap;
|
||||
|
||||
protected final DBCachedObjectStore<DBTraceCallingConventionEntry> callingConventionStore;
|
||||
protected final BidiMap<String, Byte> callingConventionMap = new DualHashBidiMap<>();
|
||||
|
||||
protected final DBCachedObjectStore<DBTraceFunctionTag> tagStore;
|
||||
protected final DBCachedObjectIndex<String, DBTraceFunctionTag> tagsByName;
|
||||
|
||||
@@ -494,11 +457,6 @@ public class DBTraceSymbolManager implements TraceSymbolManager, DBTraceManager
|
||||
baseLanguage, trace, threadManager, DBTraceSymbolIDEntry.class,
|
||||
DBTraceSymbolIDEntry::new);
|
||||
|
||||
callingConventionStore =
|
||||
factory.getOrCreateCachedStore(DBTraceCallingConventionEntry.TABLE_NAME,
|
||||
DBTraceCallingConventionEntry.class, DBTraceCallingConventionEntry::new, true);
|
||||
loadCallingConventions();
|
||||
|
||||
tagStore = factory.getOrCreateCachedStore(DBTraceFunctionTag.TABLE_NAME,
|
||||
DBTraceFunctionTag.class, (s, r) -> new DBTraceFunctionTag(this, s, r), true);
|
||||
tagsByName = tagStore.getIndex(String.class, DBTraceFunctionTag.NAME_COLUMN);
|
||||
@@ -570,9 +528,7 @@ public class DBTraceSymbolManager implements TraceSymbolManager, DBTraceManager
|
||||
if (ptrSize != dataTypeManager.getDataOrganization().getPointerSize()) {
|
||||
return dataTypeManager.getPointer(formal, ptrSize);
|
||||
}
|
||||
else {
|
||||
return dataTypeManager.getPointer(formal);
|
||||
}
|
||||
return dataTypeManager.getPointer(formal);
|
||||
}
|
||||
|
||||
protected <T extends AbstractDBTraceSymbolSingleTypeView<?>> T putInMap(T view) {
|
||||
@@ -608,25 +564,6 @@ public class DBTraceSymbolManager implements TraceSymbolManager, DBTraceManager
|
||||
return (symbolID >> KEY_SHIFT) & KEY_MASK;
|
||||
}
|
||||
|
||||
protected void loadCallingConventions() {
|
||||
// NOTE: Should already own write lock
|
||||
for (DBTraceCallingConventionEntry ent : callingConventionStore.asMap().values()) {
|
||||
// NOTE: No need to check. Only called on new or invalidate.
|
||||
callingConventionMap.put(ent.name, (byte) ent.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
protected byte doRecordCallingConvention(String name) {
|
||||
DBTraceCallingConventionEntry ent = callingConventionStore.create();
|
||||
ent.setName(name);
|
||||
return (byte) ent.getKey();
|
||||
}
|
||||
|
||||
protected byte findOrRecordCallingConvention(String name) {
|
||||
// NOTE: Must already have write lock
|
||||
return callingConventionMap.computeIfAbsent(name, this::doRecordCallingConvention);
|
||||
}
|
||||
|
||||
protected int findOrRecordVariableStorage(VariableStorage storage) {
|
||||
DBTraceVariableStorageEntry entry = storageByStorage.getOne(storage);
|
||||
if (entry == null) {
|
||||
@@ -645,9 +582,6 @@ public class DBTraceSymbolManager implements TraceSymbolManager, DBTraceManager
|
||||
public void invalidateCache(boolean all) {
|
||||
try (LockHold hold = LockHold.lock(lock.writeLock())) {
|
||||
idMap.invalidateCache(all);
|
||||
callingConventionStore.invalidateCache();
|
||||
callingConventionMap.clear();
|
||||
loadCallingConventions();
|
||||
|
||||
for (AbstractDBTraceSymbolSingleTypeView<?> view : symbolViews.values()) {
|
||||
view.invalidateCache();
|
||||
|
||||
+23
-4
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package ghidra.trace.model.symbol;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Collection;
|
||||
|
||||
import ghidra.program.database.function.OverlappingFunctionException;
|
||||
import ghidra.program.model.address.Address;
|
||||
@@ -37,11 +37,30 @@ public interface TraceFunctionSymbolView extends TraceSymbolWithLocationView<Tra
|
||||
return add(Lifespan.nowOn(snap), entryPoint, body, name, thunked, parent, source);
|
||||
}
|
||||
|
||||
PrototypeModel[] getCallingConventions();
|
||||
|
||||
List<String> getCallingConventionNames();
|
||||
/**
|
||||
* Get the ordered unmodifiable set of defined calling convention names. The reserved names
|
||||
* "unknown" and "default" are not included. The returned collection may not include all names
|
||||
* referenced by various functions and function-definitions. This set is limited to
|
||||
* those defined by the associated compiler specification.
|
||||
*
|
||||
* @return the set of defined calling convention names.
|
||||
*/
|
||||
Collection<String> getCallingConventionNames();
|
||||
|
||||
/**
|
||||
* Get the default calling convention's prototype model.
|
||||
*
|
||||
* @return the default calling convention prototype model.
|
||||
*/
|
||||
PrototypeModel getDefaultCallingConvention();
|
||||
|
||||
/**
|
||||
* Get the prototype model of the calling convention with the specified name from the
|
||||
* associated compiler specification. If {@link Function#DEFAULT_CALLING_CONVENTION_STRING}
|
||||
* is specified {@link #getDefaultCallingConvention()} will be returned.
|
||||
*
|
||||
* @param name the calling convention name
|
||||
* @return the named function calling convention prototype model or null if not defined.
|
||||
*/
|
||||
PrototypeModel getCallingConvention(String name);
|
||||
}
|
||||
|
||||
+3
-16
@@ -19,8 +19,8 @@ import static ghidra.lifecycle.Unfinished.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
@@ -423,25 +423,12 @@ public class DBTraceProgramViewFunctionManagerTest extends AbstractGhidraHeadles
|
||||
assertEquals(defaultModel, protoModel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCallingConventions() throws Exception {
|
||||
PrototypeModel[] protoModels = functionManager.getCallingConventions();
|
||||
assertTrue(protoModels.length >= 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCallingConventionNames() throws Exception {
|
||||
|
||||
List<String> names = functionManager.getCallingConventionNames();
|
||||
Collection<String> names = functionManager.getCallingConventionNames();
|
||||
assertTrue(names.size() >= 1);
|
||||
|
||||
for (String name : names) {
|
||||
if (Function.UNKNOWN_CALLING_CONVENTION_STRING.equals(name)) {
|
||||
assertNull(functionManager.getCallingConvention(name));
|
||||
}
|
||||
else {
|
||||
assertNotNull(functionManager.getCallingConvention(name));
|
||||
}
|
||||
assertNotNull(functionManager.getCallingConvention(name));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,8 +30,9 @@ data/parserprofiles/MacOSX_10.9.prf||GHIDRA||||END|
|
||||
data/parserprofiles/MacOSX_Cocoa.prf||GHIDRA||||END|
|
||||
data/parserprofiles/VisualStudio12_32.prf||GHIDRA||||END|
|
||||
data/parserprofiles/VisualStudio12_64.prf||GHIDRA||||END|
|
||||
data/parserprofiles/VisualStudio9.prf||GHIDRA||reviewed||END|
|
||||
data/parserprofiles/clib.prf||GHIDRA||reviewed||END|
|
||||
data/parserprofiles/VisualStudio22_64.prf||GHIDRA||||END|
|
||||
data/parserprofiles/VisualStudio9.prf||GHIDRA||||END|
|
||||
data/parserprofiles/clib.prf||GHIDRA||||END|
|
||||
data/parserprofiles/generic_clib_32.prf||GHIDRA||||END|
|
||||
data/parserprofiles/generic_clib_64.prf||GHIDRA||||END|
|
||||
data/parserprofiles/linux_32.prf||GHIDRA||||END|
|
||||
|
||||
@@ -207,7 +207,6 @@ zlib.h
|
||||
-DTARGET_API_MAC_OSX
|
||||
-DTARGET_COCOA
|
||||
-DHANDLE="unsigned long"
|
||||
-D_WCHAR_T
|
||||
-D_Complex
|
||||
-Drestrict
|
||||
-D__restrict
|
||||
|
||||
@@ -323,7 +323,6 @@ zlib.h
|
||||
-D_MAC_
|
||||
-DTARGET_API_MAC_OSX
|
||||
-DHANDLE="unsigned long"
|
||||
-D_WCHAR_T
|
||||
-D_Complex
|
||||
-Drestrict
|
||||
-D__restrict
|
||||
|
||||
@@ -28,7 +28,6 @@ Cocoa\Cocoa.h
|
||||
-D_MAC_
|
||||
-DTARGET_API_MAC_OSX=1
|
||||
-DHANDLE="unsigned long"
|
||||
-D_WCHAR_T
|
||||
-D_Complex
|
||||
-Drestrict
|
||||
-D__restrict
|
||||
|
||||
@@ -172,12 +172,8 @@ wpcapi.h
|
||||
wscapi.h
|
||||
wsdapi.h
|
||||
wspiapi.h
|
||||
|
||||
rpcproxy.h
|
||||
|
||||
-I/VC/VS12/src
|
||||
-I/VC/VS12/include
|
||||
-I/VC/SDK/v7.1A/Include
|
||||
-D_M_IX86=300
|
||||
-D_MSC_VER=1200
|
||||
-D_INTEGRAL_MAX_BITS=32
|
||||
@@ -191,7 +187,6 @@ rpcproxy.h
|
||||
-DSTRSAFE_LIB
|
||||
-DSTRSAFE_LIB_IMPL
|
||||
-DLPSKBINFO=LPARAM
|
||||
-D_WCHAR_T_DEFINED
|
||||
-DCONST=const
|
||||
-D_CRT_SECURE_NO_WARNINGS
|
||||
-D_CRT_NONSTDC_NO_DEPRECATE
|
||||
@@ -205,3 +200,14 @@ rpcproxy.h
|
||||
-D_ThrowInfo=ThrowInfo
|
||||
-v0
|
||||
-D__inner_checkReturn=""
|
||||
|
||||
/data/HeaderFiles/VC/VS12/src
|
||||
/data/HeaderFiles/VC/VS12/include
|
||||
/data/HeaderFiles/VC/SDK/v7.1A/Include
|
||||
|
||||
x86:LE:32:default
|
||||
|
||||
windows
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -172,12 +172,8 @@ wpcapi.h
|
||||
wscapi.h
|
||||
wsdapi.h
|
||||
wspiapi.h
|
||||
|
||||
rpcproxy.h
|
||||
|
||||
-I/VC/VS12/src
|
||||
-I/VC/VS12/include
|
||||
-I/VC/SDK/v7.1A/Include
|
||||
-D_M_IX86=300
|
||||
-D_MSC_VER=1200
|
||||
-D_INTEGRAL_MAX_BITS=64
|
||||
@@ -193,7 +189,6 @@ rpcproxy.h
|
||||
-DSTRSAFE_LIB
|
||||
-DSTRSAFE_LIB_IMPL
|
||||
-DLPSKBINFO=LPARAM
|
||||
-D_WCHAR_T_DEFINED
|
||||
-DCONST=const
|
||||
-D_CRT_SECURE_NO_WARNINGS
|
||||
-D_CRT_NONSTDC_NO_DEPRECATE
|
||||
@@ -208,3 +203,11 @@ rpcproxy.h
|
||||
-D__unaligned=""
|
||||
-v0
|
||||
-D__inner_checkReturn=""
|
||||
|
||||
/data/HeaderFiles/VC/VS12/include
|
||||
/data/HeaderFiles/VC/VS12/src
|
||||
/data/HeaderFiles/VC/SDK/v7.1A/Include
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,341 @@
|
||||
# Core necessary files
|
||||
winapifamily.h
|
||||
winpackagefamily.h
|
||||
sdkddkver.h
|
||||
sal.h
|
||||
no_sal2.h
|
||||
corecrt.h
|
||||
wtypes.h
|
||||
winnt.h
|
||||
winternl.h
|
||||
#ntdef.h
|
||||
# Common headers
|
||||
dos.h
|
||||
errno.h
|
||||
malloc.h
|
||||
signal.h
|
||||
stdalign.h
|
||||
stddef.h
|
||||
stdio.h
|
||||
stdlib.h
|
||||
assert.h
|
||||
crtdbg.h
|
||||
ctype.h
|
||||
conio.h
|
||||
direct.h
|
||||
fcntl.h
|
||||
float.h
|
||||
fpieee.h
|
||||
inttypes.h
|
||||
io.h
|
||||
locale.h
|
||||
complex.h
|
||||
math.h
|
||||
mbctype.h
|
||||
mbstring.h
|
||||
memory.h
|
||||
minmax.h
|
||||
new.h
|
||||
process.h
|
||||
search.h
|
||||
share.h
|
||||
winbase.h
|
||||
winuser.h
|
||||
Windows.h
|
||||
# Security and identity (https://docs.microsoft.com/en-us/windows/win32/api/_security/)
|
||||
accctrl.h
|
||||
aclapi.h
|
||||
aclui.h
|
||||
advapi32.h
|
||||
adtgen.h
|
||||
authz.h
|
||||
azroles.h
|
||||
bcrypt.h
|
||||
casetup.h
|
||||
ccgplugins.h
|
||||
celib.h
|
||||
ntlsa.h
|
||||
sspi.h
|
||||
ntsecapi.h
|
||||
ntsecpkg.h
|
||||
schannel.h
|
||||
certadm.h
|
||||
certbcli.h
|
||||
certcli.h
|
||||
certenroll.h
|
||||
certexit.h
|
||||
certif.h
|
||||
certmod.h
|
||||
certpol.h
|
||||
certpoleng.h
|
||||
certsrv.h
|
||||
certview.h
|
||||
credssp.h
|
||||
cryptdlg.h
|
||||
cryptuiapi.h
|
||||
cryptxml.h
|
||||
diagnosticdataquery.h
|
||||
diagnosticdataquerytypes.h
|
||||
dpapi.h
|
||||
dssec.h
|
||||
iads.h
|
||||
identitycommon.h
|
||||
identityprovider.h
|
||||
identitystore.h
|
||||
keycredmgr.h
|
||||
lmaccess.h
|
||||
lsalookup.h
|
||||
mmcobj.h
|
||||
mscat.h
|
||||
mssip.h
|
||||
namedpipeapi.h
|
||||
ncrypt.h
|
||||
ncryptprotect.h
|
||||
npapi.h
|
||||
processthreadsapi.h
|
||||
sas.h
|
||||
scesvc.h
|
||||
sddl.h
|
||||
securityappcontainer.h
|
||||
securitybaseapi.h
|
||||
slpublic.h
|
||||
subauth.h
|
||||
tokenbinding.h
|
||||
tpmvscmgr.h
|
||||
wincred.h
|
||||
wincrypt.h
|
||||
winnetwk.h
|
||||
winreg.h
|
||||
winsafer.h
|
||||
winscard.h
|
||||
winsvc.h
|
||||
wintrust.h
|
||||
winwlx.h
|
||||
xenroll.h
|
||||
# Windows sockets
|
||||
af_irda.h
|
||||
in6addr.h
|
||||
mstcpip.h
|
||||
ws2def.h
|
||||
winsock.h
|
||||
winsock2.h
|
||||
nsemail.h
|
||||
nspapi.h
|
||||
socketapi.h
|
||||
# Nothing includes this; is it necessary?
|
||||
#sporder.h
|
||||
transportsettingcommon.h
|
||||
ws2atm.h
|
||||
ws2spi.h
|
||||
mswsock.h
|
||||
ws2tcpip.h
|
||||
wsipv6ok.h
|
||||
wsnwlink.h
|
||||
wsrm.h
|
||||
mswsockdef.h
|
||||
# Remote Procedure Call (RPC)
|
||||
midles.h
|
||||
midlbase.h
|
||||
rpc.h
|
||||
rpcndr.h
|
||||
rpcasync.h
|
||||
rpcdcep.h
|
||||
rpcnsi.h
|
||||
rpcproxy.h
|
||||
rpcssl.h
|
||||
# COM
|
||||
accctrl.h
|
||||
callobj.h
|
||||
combaseapi.h
|
||||
comcat.h
|
||||
ctxtcall.h
|
||||
dmerror.h
|
||||
docobj.h
|
||||
eventsys.h
|
||||
guiddef.h
|
||||
iaccess.h
|
||||
hstring.h
|
||||
imessagedispatcher.h
|
||||
messagedispatcherapi.h
|
||||
objbase.h
|
||||
objidlbase.h
|
||||
objidl.h
|
||||
ocidl.h
|
||||
ole.h
|
||||
ole2.h
|
||||
oledlg.h
|
||||
oleidl.h
|
||||
roapi.h
|
||||
rpcdce.h
|
||||
servprov.h
|
||||
shobjidl.h
|
||||
txlogpub.h
|
||||
unknwnbase.h
|
||||
unknwn.h
|
||||
urlmon.h
|
||||
vbinterf.h
|
||||
winddi.h
|
||||
winerror.h
|
||||
wtypesbase.h
|
||||
# COM+
|
||||
comadmin.h
|
||||
mtxdm.h
|
||||
# More
|
||||
inspectable.h
|
||||
# Windows Internet
|
||||
proofofpossessioncookieinfo.h
|
||||
wininet.h
|
||||
winineti.h
|
||||
# Windows HTTP Services
|
||||
winhttp.h
|
||||
# Compression
|
||||
compressapi.h
|
||||
# TraceLogging
|
||||
#traceloggingactivity.h
|
||||
#traceloggingprovider.h
|
||||
# Windows Error Reporting
|
||||
errorrep.h
|
||||
werapi.h
|
||||
# Windows and MEssages
|
||||
olectl.h
|
||||
windef.h
|
||||
windowsx.h
|
||||
# Shell
|
||||
appmgmt.h
|
||||
appnotify.h
|
||||
cpl.h
|
||||
credentialprovider.h
|
||||
dimm.h
|
||||
imagetranscode.h
|
||||
inputpanelconfiguration.h
|
||||
intsafe.h
|
||||
intshcut.h
|
||||
mobsync.h
|
||||
objectarray.h
|
||||
pathcch.h
|
||||
profinfo.h
|
||||
propkeydef.h
|
||||
scrnsave.h
|
||||
shappmgr.h
|
||||
shdeprecated.h
|
||||
shidfact.h
|
||||
shimgdata.h
|
||||
shlwapi.h
|
||||
shtypes.h
|
||||
storageprovider.h
|
||||
syncmgr.h
|
||||
thumbcache.h
|
||||
thumbnailstreamcache.h
|
||||
tlogstg.h
|
||||
userenv.h
|
||||
# Windows Controls
|
||||
commctrl.h
|
||||
commoncontrols.h
|
||||
dpa_dsa.h
|
||||
prsht.h
|
||||
richedit.h
|
||||
richole.h
|
||||
shlobj_core.h
|
||||
shlobj.h
|
||||
#textserv.h // C++
|
||||
tom.h
|
||||
uxtheme.h
|
||||
# Menus and other resources
|
||||
resourceindexer.h
|
||||
strsafe.h
|
||||
verrsrc.h
|
||||
winver.h
|
||||
# Windows Accessibility Features
|
||||
oleacc.h
|
||||
uiautomationcore.h
|
||||
uiautomationclient.h
|
||||
uiautomationcoreapi.h
|
||||
# Internationalization
|
||||
datetimeapi.h
|
||||
elscore.h
|
||||
gb18030.h
|
||||
imepad.h
|
||||
imm.h
|
||||
immdev.h
|
||||
msime.h
|
||||
msimeapi.h
|
||||
muiload.h
|
||||
spellcheck.h
|
||||
spellcheckprovider.h
|
||||
stringapiset.h
|
||||
usp10.h
|
||||
winnls.h
|
||||
# HTTP Server API
|
||||
#http.h // included by something else
|
||||
# IP Helper
|
||||
ifdef.h
|
||||
inaddr.h
|
||||
ip2string.h
|
||||
ipexport.h
|
||||
iphlpapi.h
|
||||
icmpapi.h
|
||||
iprtrmib.h
|
||||
iptypes.h
|
||||
netioapi.h
|
||||
nldef.h
|
||||
tcpestats.h
|
||||
ws2ipdef.h
|
||||
# Network Management
|
||||
atacct.h
|
||||
lmalert.h
|
||||
lmapibuf.h
|
||||
lmat.h
|
||||
lmaudit.h
|
||||
lmconfig.h
|
||||
lmerrlog.h
|
||||
lmjoin.h
|
||||
lmmsg.h
|
||||
lmremutl.h
|
||||
lmserver.h
|
||||
lmsvc.h
|
||||
lmuse.h
|
||||
lmwksta.h
|
||||
|
||||
-D_MSC_VER=1924
|
||||
-D_INTEGRAL_MAX_BITS=64
|
||||
-DWINVER=0x0a00
|
||||
-D_WIN32_WINNT=0x0a00
|
||||
-D_AMD64_
|
||||
-D_M_AMD64
|
||||
-D_M_X64
|
||||
-D_WIN64
|
||||
-D_WIN32
|
||||
-D_USE_ATTRIBUTES_FOR_SAL
|
||||
-D_CRTBLD
|
||||
-D_OPENMP_NOFORCE_MANIFEST
|
||||
-DSTRSAFE_LIB
|
||||
-DSTRSAFE_LIB_IMPL
|
||||
-DLPSKBINFO=LPARAM
|
||||
-DCONST=const
|
||||
-D_CRT_SECURE_NO_WARNINGS
|
||||
-D_CRT_NONSTDC_NO_DEPRECATE
|
||||
-D_CRT_NONSTDC_NO_WARNINGS
|
||||
-D_CRT_OBSOLETE_NO_DEPRECATE
|
||||
-D_ALLOW_KEYWORD_MACROS
|
||||
-D_ASSERT_OK
|
||||
-DSTRSAFE_NO_DEPRECATE
|
||||
-D__possibly_notnullterminated
|
||||
"-Dtype_info=\"void *\"",
|
||||
-D_ThrowInfo=ThrowInfo
|
||||
-D__unaligned=
|
||||
-v0
|
||||
-D__inner_checkReturn=
|
||||
-DWINAPI_PARTITION_APP=1
|
||||
-DWINAPI_PARTITION_SYSTEM=1
|
||||
-DWINAPI_PARTITION_GAMES=1
|
||||
-DSECURITY_WIN32
|
||||
|
||||
/data/HeaderFiles/VC/VS22/Community/VC/Tools/MSVC/14.29.30133/include
|
||||
/data/HeaderFiles/VC/VS22/10.0.19041.0/shared
|
||||
/data/HeaderFiles/VC/VS22/10.0.19041.0/ucrt
|
||||
/data/HeaderFiles/VC/VS22/10.0.19041.0/um
|
||||
/data/HeaderFiles/VC/VS22/10.0.19041.0/winrt
|
||||
|
||||
x86:LE:64:default
|
||||
|
||||
windows
|
||||
@@ -58,13 +58,10 @@ yvals.h
|
||||
CommDlg.h
|
||||
WinUser.h
|
||||
WinNls.h
|
||||
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\crt\src\internal.h
|
||||
internal.h
|
||||
strsafe.h
|
||||
penwin.h
|
||||
|
||||
-IC:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\Include
|
||||
-IC:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include
|
||||
-IC:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\crt\src
|
||||
-D_M_IX86=500
|
||||
-D_MSC_VER=9090
|
||||
-D_MSC_EXTENSIONS
|
||||
@@ -85,5 +82,11 @@ penwin.h
|
||||
-DSTRSAFE_LIB_IMPL
|
||||
-DLPSKBINFO=LPARAM
|
||||
-D_PHNDLR=void *
|
||||
-D_WCHAR_T_DEFINED
|
||||
-DCONST=const
|
||||
|
||||
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\Include
|
||||
C:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include
|
||||
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\crt\src
|
||||
|
||||
x86:LE:64:default
|
||||
|
||||
|
||||
@@ -78,13 +78,17 @@ wchar.h
|
||||
wctype.h
|
||||
wordexp.h
|
||||
|
||||
-IU:\linux_include\include
|
||||
-IU:\linux_include\include\sys
|
||||
-IU:\linux_include\i386-redhat-linux\4.1.2\include
|
||||
-D_X86_
|
||||
-D__STDC__
|
||||
-D__WORDSIZE=32
|
||||
-D__builtin_va_list=void *
|
||||
-D__DO_NOT_DEFINE_COMPILE
|
||||
-D_Complex
|
||||
-D_WCHAR_T
|
||||
|
||||
U:\linux_include\include
|
||||
U:\linux_include\include\sys
|
||||
U:\linux_include\i386-redhat-linux\4.1.2\include
|
||||
|
||||
x86:LE:32:default
|
||||
|
||||
gcc
|
||||
|
||||
@@ -219,11 +219,6 @@ arpa/nameser_compat.h
|
||||
arpa/telnet.h
|
||||
arpa/tftp.h
|
||||
|
||||
-I/linux/include
|
||||
-I/linux/include/sys
|
||||
-I/linux/gcc/include
|
||||
-I/linux/x86_64-redhat-linux5E/include
|
||||
-I/linux/x86_64-redhat-linux5E/include/sys
|
||||
-D_X86_
|
||||
-D__STDC__
|
||||
-D_GNU_SOURCE
|
||||
@@ -231,10 +226,19 @@ arpa/tftp.h
|
||||
-D__builtin_va_list=void *
|
||||
-D__DO_NOT_DEFINE_COMPILE
|
||||
-D_Complex
|
||||
-D_WCHAR_T
|
||||
-D__NO_STRING_INLINES
|
||||
-D__NO_LONG_DOUBLE_MATH
|
||||
-D__signed__
|
||||
-D__extension__=""
|
||||
-D__GLIBC_HAVE_LONG_LONG=1
|
||||
-Daligned_u64=uint64_t
|
||||
|
||||
/data/HeaderFiles/linux/include
|
||||
/data/HeaderFiles/linux/include/sys
|
||||
/data/HeaderFiles/linux/gcc/include
|
||||
/data/HeaderFiles/linux/x86_64-redhat-linux5E/include
|
||||
/data/HeaderFiles/linux/x86_64-redhat-linux5E/include/sys
|
||||
|
||||
x86:LE:32:default
|
||||
|
||||
gcc
|
||||
|
||||
@@ -219,11 +219,6 @@ arpa/nameser_compat.h
|
||||
arpa/telnet.h
|
||||
arpa/tftp.h
|
||||
|
||||
-I/linux/include
|
||||
-I/linux/include/sys
|
||||
-I/linux/gcc/include
|
||||
-I/linux/x86_64-redhat-linux5E/include
|
||||
-I/linux/x86_64-redhat-linux5E/include/sys
|
||||
-D_X86_
|
||||
-D__STDC__
|
||||
-D_GNU_SOURCE
|
||||
@@ -231,10 +226,19 @@ arpa/tftp.h
|
||||
-D__builtin_va_list=void *
|
||||
-D__DO_NOT_DEFINE_COMPILE
|
||||
-D_Complex
|
||||
-D_WCHAR_T
|
||||
-D__NO_STRING_INLINES
|
||||
-D__signed__
|
||||
-D__extension__=""
|
||||
-D__GLIBC_HAVE_LONG_LONG=1
|
||||
-D__need_sigset_t
|
||||
-Daligned_u64=uint64_t
|
||||
|
||||
/data/HeaderFiles/linux/include
|
||||
/data/HeaderFiles/linux/include/sys
|
||||
/data/HeaderFiles/linux/gcc/include
|
||||
/data/HeaderFiles/linux/x86_64-redhat-linux5E/include
|
||||
/data/HeaderFiles/linux/x86_64-redhat-linux5E/include/sys
|
||||
|
||||
x86:LE:64:default
|
||||
|
||||
gcc
|
||||
|
||||
@@ -515,11 +515,6 @@ mechglue.h
|
||||
auth_gss.h
|
||||
auth_gssapi.h
|
||||
|
||||
-I/linux/include
|
||||
-I/linux/include/sys
|
||||
-I/linux/gcc/include
|
||||
-I/linux/x86_64-redhat-linux5E/include
|
||||
-I/linux/x86_64-redhat-linux5E/include/sys
|
||||
-D_X86_
|
||||
-D__STDC__
|
||||
-D_POSIX_C_SOURCE
|
||||
@@ -528,10 +523,19 @@ auth_gssapi.h
|
||||
-D__builtin_va_list=void *
|
||||
-D__DO_NOT_DEFINE_COMPILE
|
||||
-D_Complex
|
||||
-D_WCHAR_T
|
||||
-D__NO_STRING_INLINES
|
||||
-D__NO_LONG_DOUBLE_MATH
|
||||
-D__signed__
|
||||
-D__extension__=""
|
||||
-D__GLIBC_HAVE_LONG_LONG=1
|
||||
-Daligned_u64=uint64_t
|
||||
|
||||
/data/HeaderFiles/linux/include
|
||||
/data/HeaderFiles/linux/include/sys
|
||||
/data/HeaderFiles/linux/gcc/include
|
||||
/data/HeaderFiles/linux/x86_64-redhat-linux5E/include
|
||||
/data/HeaderFiles/linux/x86_64-redhat-linux5E/include/sys
|
||||
|
||||
x86:LE:32:default
|
||||
|
||||
gcc
|
||||
|
||||
@@ -515,11 +515,6 @@ mechglue.h
|
||||
auth_gss.h
|
||||
auth_gssapi.h
|
||||
|
||||
-I/linux/include
|
||||
-I/linux/include/sys
|
||||
-I/linux/gcc/include
|
||||
-I/linux/x86_64-redhat-linux5E/include
|
||||
-I/linux/x86_64-redhat-linux5E/include/sys
|
||||
-D_X86_
|
||||
-D__STDC__
|
||||
-D_POSIX_C_SOURCE
|
||||
@@ -528,9 +523,18 @@ auth_gssapi.h
|
||||
-D__builtin_va_list=void *
|
||||
-D__DO_NOT_DEFINE_COMPILE
|
||||
-D_Complex
|
||||
-D_WCHAR_T
|
||||
-D__NO_STRING_INLINES
|
||||
-D__signed__
|
||||
-D__extension__=""
|
||||
-D__GLIBC_HAVE_LONG_LONG=1
|
||||
-Daligned_u64=uint64_t
|
||||
|
||||
/data/HeaderFiles/linux/include
|
||||
/data/HeaderFiles/linux/include/sys
|
||||
/data/HeaderFiles/linux/gcc/include
|
||||
/data/HeaderFiles/linux/x86_64-redhat-linux5E/include
|
||||
/data/HeaderFiles/linux/x86_64-redhat-linux5E/include/sys
|
||||
|
||||
x86:LE:64:default
|
||||
|
||||
gcc
|
||||
|
||||
@@ -222,9 +222,6 @@ wscapi.h
|
||||
wsdapi.h
|
||||
wspiapi.h
|
||||
|
||||
-I/VisualStudio/VS12/include
|
||||
-I/VisualStudio/Windows/v7.0a/Include
|
||||
-I/VisualStudio/VS12/src
|
||||
-D_M_IX86
|
||||
-D_MSC_VER=9090
|
||||
-D_INTEGRAL_MAX_BITS=32
|
||||
@@ -239,7 +236,6 @@ wspiapi.h
|
||||
-DSTRSAFE_LIB
|
||||
-DSTRSAFE_LIB_IMPL
|
||||
-DLPSKBINFO=LPARAM
|
||||
-D_WCHAR_T_DEFINED
|
||||
-DCONST=const
|
||||
-D_CRT_SECURE_NO_WARNINGS
|
||||
-D_CRT_NONSTDC_NO_DEPRECATE
|
||||
@@ -250,3 +246,12 @@ wspiapi.h
|
||||
-D__possibly_notnullterminated
|
||||
-Dtype_info="void *"
|
||||
-v0
|
||||
|
||||
/data/HeaderFiles/VC/VS12/include
|
||||
/data/HeaderFiles/VC/Windows/v7.0a/Include
|
||||
/data/HeaderFiles/VC/VS12/src
|
||||
|
||||
x86:LE:32:default
|
||||
|
||||
windows
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -26,6 +26,7 @@ import java.util.Iterator;
|
||||
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.data.StandAloneDataTypeManager.ArchiveWarning;
|
||||
import ghidra.util.UniversalID;
|
||||
|
||||
public class CompareGDTs extends GhidraScript {
|
||||
@@ -54,13 +55,28 @@ public class CompareGDTs extends GhidraScript {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
firstArchive = openDataTypeArchive(firstFile, false);
|
||||
if (firstArchive.getWarning() != ArchiveWarning.NONE) {
|
||||
popup(
|
||||
"An architecture language error occured while opening archive (see log for details)\n" +
|
||||
firstFile.getPath());
|
||||
return;
|
||||
}
|
||||
|
||||
secondArchive = openDataTypeArchive(secondFile, false);
|
||||
if (secondArchive.getWarning() != ArchiveWarning.NONE) {
|
||||
popup(
|
||||
"An architecture language error occured while opening archive (see log for details)\n" +
|
||||
secondFile.getPath());
|
||||
return;
|
||||
}
|
||||
|
||||
matchByName = askYesNo("Match Data Types By Path Name?",
|
||||
"Do you want to match data types by their path names (rather than by Universal ID)?");
|
||||
checkPointers = askYesNo("Check Pointers?", "Do you want to check Pointers?");
|
||||
checkArrays = askYesNo("Check Arrays?", "Do you want to check Arrays?");
|
||||
|
||||
firstArchive = FileDataTypeManager.openFileArchive(firstFile, false);
|
||||
secondArchive = FileDataTypeManager.openFileArchive(secondFile, false);
|
||||
printWriter = new PrintWriter(outputFile);
|
||||
try {
|
||||
compareDataTypes();
|
||||
|
||||
@@ -31,6 +31,7 @@ import java.io.IOException;
|
||||
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.app.util.cparser.C.CParserUtils;
|
||||
import ghidra.app.util.cparser.C.CParserUtils.CParseResults;
|
||||
import ghidra.app.util.cparser.C.ParseException;
|
||||
import ghidra.program.model.data.DataTypeManager;
|
||||
import ghidra.program.model.data.FileDataTypeManager;
|
||||
@@ -55,14 +56,16 @@ public class CreateDefaultGDTArchivesScript extends GhidraScript {
|
||||
|
||||
}
|
||||
|
||||
private void parseHeaderFilesToGDT(File outputDir, String gdtName, String languageID, String compiler, String[] filenames, String[] args)
|
||||
private void parseHeaderFilesToGDT(File outputDir, String gdtName, String languageID, String compiler,
|
||||
String[] filenames, String includePaths[], String[] args)
|
||||
throws ParseException, ghidra.app.util.cparser.CPP.ParseException, IOException {
|
||||
DataTypeManager openTypes[] = null;
|
||||
|
||||
parseHeaderFilesToGDT(openTypes, outputDir, gdtName, languageID, compiler, filenames, args);
|
||||
parseHeaderFilesToGDT(openTypes, outputDir, gdtName, languageID, compiler, filenames, includePaths, args);
|
||||
}
|
||||
|
||||
private void parseHeaderFilesToGDT(DataTypeManager openTypes[], File outputDir, String gdtName, String languageID, String compiler, String[] filenames, String[] args)
|
||||
private void parseHeaderFilesToGDT(DataTypeManager openTypes[], File outputDir, String gdtName, String languageID, String compiler,
|
||||
String[] filenames, String[] includePaths, String[] args)
|
||||
throws ParseException, ghidra.app.util.cparser.CPP.ParseException, IOException {
|
||||
|
||||
String dataTypeFile = outputDir + File.separator + gdtName + ".gdt";
|
||||
@@ -71,9 +74,9 @@ public class CreateDefaultGDTArchivesScript extends GhidraScript {
|
||||
|
||||
FileDataTypeManager dtMgr = FileDataTypeManager.createFileArchive(f);
|
||||
|
||||
String messages = CParserUtils.parseHeaderFiles(openTypes, filenames, args, dtMgr, languageID, compiler, null, monitor);
|
||||
CParseResults results = CParserUtils.parseHeaderFiles(openTypes, filenames, includePaths, args, dtMgr, languageID, compiler, monitor);
|
||||
|
||||
Msg.info(this, messages);
|
||||
Msg.info(this, results.getFormattedParseMessage(null));
|
||||
|
||||
dtMgr.save();
|
||||
dtMgr.close();
|
||||
@@ -276,14 +279,16 @@ public class CreateDefaultGDTArchivesScript extends GhidraScript {
|
||||
"wscapi.h",
|
||||
"wsdapi.h",
|
||||
"wspiapi.h",
|
||||
|
||||
"rpcproxy.h",
|
||||
};
|
||||
|
||||
String includePaths[] = {
|
||||
headerFilePath+"/VC/VS12/src",
|
||||
headerFilePath+"/VC/VS12/include",
|
||||
headerFilePath+"/VC/SDK/v7.1A/Include",
|
||||
};
|
||||
|
||||
String args[] = {
|
||||
"-I"+headerFilePath+"/VC/VS12/src",
|
||||
"-I"+headerFilePath+"/VC/VS12/include",
|
||||
"-I"+headerFilePath+"/VC/SDK/v7.1A/Include",
|
||||
"-D_M_IX86=300",
|
||||
"-D_MSC_VER=1200",
|
||||
"-D_INTEGRAL_MAX_BITS=32",
|
||||
@@ -294,8 +299,6 @@ public class CreateDefaultGDTArchivesScript extends GhidraScript {
|
||||
"-D_USE_ATTRIBUTES_FOR_SAL",
|
||||
"-D_CRTBLD",
|
||||
"-D_OPENMP_NOFORCE_MANIFEST",
|
||||
"-DSTRSAFE_LIB",
|
||||
"-DSTRSAFE_LIB_IMPL",
|
||||
"-DLPSKBINFO=LPARAM",
|
||||
"-DCONST=const",
|
||||
"-D_CRT_SECURE_NO_WARNINGS",
|
||||
@@ -312,7 +315,7 @@ public class CreateDefaultGDTArchivesScript extends GhidraScript {
|
||||
"-D__inner_checkReturn=",
|
||||
};
|
||||
|
||||
parseHeaderFilesToGDT(outputDirectory, "windows_vs12_32_new", "x86:LE:32:default", "windows", filenames, args);
|
||||
parseHeaderFilesToGDT(outputDirectory, "windows_vs12_32_new", "x86:LE:32:default", "windows", filenames, includePaths, args);
|
||||
}
|
||||
|
||||
|
||||
@@ -494,14 +497,16 @@ public class CreateDefaultGDTArchivesScript extends GhidraScript {
|
||||
"wscapi.h",
|
||||
"wsdapi.h",
|
||||
"wspiapi.h",
|
||||
|
||||
"rpcproxy.h",
|
||||
};
|
||||
|
||||
String includePaths[] = {
|
||||
headerFilePath+"/VC/VS12/src",
|
||||
headerFilePath+"/VC/VS12/include",
|
||||
headerFilePath+"/VC/SDK/v7.1A/Include",
|
||||
};
|
||||
|
||||
String args[] = {
|
||||
"-I"+headerFilePath+"/VC/VS12/src",
|
||||
"-I"+headerFilePath+"/VC/VS12/include",
|
||||
"-I"+headerFilePath+"/VC/SDK/v7.1A/Include",
|
||||
"-D_MSC_VER=1200",
|
||||
"-D_INTEGRAL_MAX_BITS=64",
|
||||
"-DWINVER=0x0900",
|
||||
@@ -513,8 +518,6 @@ public class CreateDefaultGDTArchivesScript extends GhidraScript {
|
||||
"-D_USE_ATTRIBUTES_FOR_SAL",
|
||||
"-D_CRTBLD",
|
||||
"-D_OPENMP_NOFORCE_MANIFEST",
|
||||
"-DSTRSAFE_LIB",
|
||||
"-DSTRSAFE_LIB_IMPL",
|
||||
"-DLPSKBINFO=LPARAM",
|
||||
"-DCONST=const",
|
||||
"-D_CRT_SECURE_NO_WARNINGS",
|
||||
@@ -532,7 +535,7 @@ public class CreateDefaultGDTArchivesScript extends GhidraScript {
|
||||
"-D__inner_checkReturn=",
|
||||
};
|
||||
|
||||
parseHeaderFilesToGDT(outputDirectory, "windows_vs12_64_new", "x86:LE:64:default", "windows", filenames, args);
|
||||
parseHeaderFilesToGDT(outputDirectory, "windows_vs12_64_new", "x86:LE:64:default", "windows", filenames, includePaths, args);
|
||||
}
|
||||
|
||||
|
||||
@@ -761,12 +764,15 @@ public class CreateDefaultGDTArchivesScript extends GhidraScript {
|
||||
"arpa/tftp.h",
|
||||
};
|
||||
|
||||
String includePaths[] = {
|
||||
headerFilePath+"/linux/include",
|
||||
headerFilePath+"/linux/include/sys",
|
||||
headerFilePath+"/linux/gcc/include",
|
||||
headerFilePath+"/linux/x86_64-redhat-linux5E/include",
|
||||
headerFilePath+"/linux/x86_64-redhat-linux5E/include/sys",
|
||||
};
|
||||
|
||||
String args[] = {
|
||||
"-I"+headerFilePath+"/linux/include",
|
||||
"-I"+headerFilePath+"/linux/include/sys",
|
||||
"-I"+headerFilePath+"/linux/gcc/include",
|
||||
"-I"+headerFilePath+"/linux/x86_64-redhat-linux5E/include",
|
||||
"-I"+headerFilePath+"/linux/x86_64-redhat-linux5E/include/sys",
|
||||
"-D_X86_",
|
||||
"-D__STDC__",
|
||||
"-D_GNU_SOURCE",
|
||||
@@ -782,7 +788,7 @@ public class CreateDefaultGDTArchivesScript extends GhidraScript {
|
||||
"-Daligned_u64=uint64_t",
|
||||
};
|
||||
|
||||
parseHeaderFilesToGDT(outputDirectory, "generic_clib_64_new", "x86:LE:64:default", "gcc", filenames, args);
|
||||
parseHeaderFilesToGDT(outputDirectory, "generic_clib_64_new", "x86:LE:64:default", "gcc", filenames, includePaths, args);
|
||||
}
|
||||
|
||||
|
||||
@@ -1011,12 +1017,15 @@ public class CreateDefaultGDTArchivesScript extends GhidraScript {
|
||||
"arpa/tftp.h",
|
||||
};
|
||||
|
||||
String includePaths[] = {
|
||||
headerFilePath+"/linux/include",
|
||||
headerFilePath+"/linux/include/sys",
|
||||
headerFilePath+"/linux/gcc/include",
|
||||
headerFilePath+"/linux/x86_64-redhat-linux5E/include",
|
||||
headerFilePath+"/linux/x86_64-redhat-linux5E/include/sys",
|
||||
};
|
||||
|
||||
String args[] = {
|
||||
"-I"+headerFilePath+"/linux/include",
|
||||
"-I"+headerFilePath+"/linux/include/sys",
|
||||
"-I"+headerFilePath+"/linux/gcc/include",
|
||||
"-I"+headerFilePath+"/linux/x86_64-redhat-linux5E/include",
|
||||
"-I"+headerFilePath+"/linux/x86_64-redhat-linux5E/include/sys",
|
||||
"-D_X86_",
|
||||
"-D__STDC__",
|
||||
"-D_GNU_SOURCE",
|
||||
@@ -1032,6 +1041,6 @@ public class CreateDefaultGDTArchivesScript extends GhidraScript {
|
||||
"-Daligned_u64=uint64_t",
|
||||
};
|
||||
|
||||
parseHeaderFilesToGDT(outputDirectory, "generic_clib_new", "x86:LE:32:default", "gcc", filenames, args);
|
||||
parseHeaderFilesToGDT(outputDirectory, "generic_clib_new", "x86:LE:32:default", "gcc", filenames, includePaths, args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import java.io.IOException;
|
||||
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.app.util.cparser.C.CParserUtils;
|
||||
import ghidra.app.util.cparser.C.CParserUtils.CParseResults;
|
||||
import ghidra.app.util.cparser.C.ParseException;
|
||||
import ghidra.program.model.data.DataTypeManager;
|
||||
import ghidra.program.model.data.FileDataTypeManager;
|
||||
@@ -52,14 +53,16 @@ public class CreateExampleGDTArchiveScript extends GhidraScript {
|
||||
parseGDT_WinVS22();
|
||||
}
|
||||
|
||||
private void parseHeaderFilesToGDT(File outputDir, String gdtName, String languageID, String compiler, String[] filenames, String[] args)
|
||||
private void parseHeaderFilesToGDT(File outputDir, String gdtName, String languageID, String compiler,
|
||||
String[] filenames, String includePaths[], String[] args)
|
||||
throws ParseException, ghidra.app.util.cparser.CPP.ParseException, IOException {
|
||||
DataTypeManager openTypes[] = null;
|
||||
|
||||
parseHeaderFilesToGDT(openTypes, outputDir, gdtName, languageID, compiler, filenames, args);
|
||||
parseHeaderFilesToGDT(openTypes, outputDir, gdtName, languageID, compiler, filenames, includePaths, args);
|
||||
}
|
||||
|
||||
private void parseHeaderFilesToGDT(DataTypeManager openTypes[], File outputDir, String gdtName, String languageID, String compiler, String[] filenames, String[] args)
|
||||
private void parseHeaderFilesToGDT(DataTypeManager openTypes[], File outputDir, String gdtName, String languageID, String compiler,
|
||||
String[] filenames, String[] includePaths, String[] args)
|
||||
throws ParseException, ghidra.app.util.cparser.CPP.ParseException, IOException {
|
||||
|
||||
String dataTypeFile = outputDir + File.separator + gdtName + ".gdt";
|
||||
@@ -68,9 +71,9 @@ public class CreateExampleGDTArchiveScript extends GhidraScript {
|
||||
|
||||
FileDataTypeManager dtMgr = FileDataTypeManager.createFileArchive(f);
|
||||
|
||||
String messages = CParserUtils.parseHeaderFiles(openTypes, filenames, args, dtMgr, languageID, compiler, null, monitor);
|
||||
CParseResults results = CParserUtils.parseHeaderFiles(openTypes, filenames, includePaths, args, dtMgr, languageID, compiler, monitor);
|
||||
|
||||
Msg.info(this, messages);
|
||||
Msg.info(this, results.getFormattedParseMessage(null));
|
||||
|
||||
dtMgr.save();
|
||||
dtMgr.close();
|
||||
@@ -79,7 +82,7 @@ public class CreateExampleGDTArchiveScript extends GhidraScript {
|
||||
/**
|
||||
* Turn string into a file, delete old archive if it exists
|
||||
*
|
||||
* @param dataTypeFile
|
||||
* @param dataTypeFile name of archive file
|
||||
*
|
||||
* @return file
|
||||
*/
|
||||
@@ -112,12 +115,15 @@ public class CreateExampleGDTArchiveScript extends GhidraScript {
|
||||
"dsound.h",
|
||||
};
|
||||
|
||||
String includeFiles[] = {
|
||||
headerFilePath+"/VC/VS22/10.0.190141.0",
|
||||
headerFilePath+"/VC/VS22/10.0.19041.0/um",
|
||||
headerFilePath+"/VC/VS22/10.0.19041.0/shared",
|
||||
headerFilePath+"/VC/VS22/10.0.19041.0/ucrt",
|
||||
headerFilePath+"/VC/VS22/Community/VC/Tools/MSVC/14.30.30705/include",
|
||||
};
|
||||
|
||||
String args[] = {
|
||||
"-I"+headerFilePath+"/VC/VS22/10.0.190141.0",
|
||||
"-I"+headerFilePath+"/VC/VS22/10.0.19041.0/um",
|
||||
"-I"+headerFilePath+"/VC/VS22/10.0.19041.0/shared",
|
||||
"-I"+headerFilePath+"/VC/VS22/10.0.19041.0/ucrt",
|
||||
"-I"+headerFilePath+"/VC/VS22/Community/VC/Tools/MSVC/14.30.30705/include",
|
||||
"-D_AMD64_",
|
||||
"-D_M_AMD64",
|
||||
"-D_M_X64",
|
||||
@@ -126,7 +132,7 @@ public class CreateExampleGDTArchiveScript extends GhidraScript {
|
||||
"-v0",
|
||||
};
|
||||
|
||||
parseHeaderFilesToGDT(outputDirectory, "directX64", "x86:LE:64:default", "windows", filenames, args);
|
||||
parseHeaderFilesToGDT(outputDirectory, "directX64", "x86:LE:64:default", "windows", filenames, includeFiles, args);
|
||||
}
|
||||
|
||||
public void parseGDT_WinVS22() throws Exception {
|
||||
@@ -167,7 +173,7 @@ public class CreateExampleGDTArchiveScript extends GhidraScript {
|
||||
"complex.h",
|
||||
"math.h",
|
||||
"mbctype.h",
|
||||
"mbstring.hs",
|
||||
"mbstring.h",
|
||||
"memory.h",
|
||||
"minmax.h",
|
||||
"new.h",
|
||||
@@ -216,7 +222,7 @@ public class CreateExampleGDTArchiveScript extends GhidraScript {
|
||||
"dssec.h",
|
||||
"iads.h",
|
||||
"identitycommon.h",
|
||||
"identityproviders.h",
|
||||
"identityprovider.h",
|
||||
"identitystore.h",
|
||||
"keycredmgr.h",
|
||||
"lmaccess.h",
|
||||
@@ -237,7 +243,7 @@ public class CreateExampleGDTArchiveScript extends GhidraScript {
|
||||
"slpublic.h",
|
||||
"subauth.h",
|
||||
"tokenbinding.h",
|
||||
"tpmsvcmgr.h",
|
||||
"tpmvscmgr.h",
|
||||
"wincred.h",
|
||||
"wincrypt.h",
|
||||
"winnetwk.h",
|
||||
@@ -267,7 +273,7 @@ public class CreateExampleGDTArchiveScript extends GhidraScript {
|
||||
"mswsock.h",
|
||||
"ws2tcpip.h",
|
||||
"wsipv6ok.h",
|
||||
"wslwlink.h",
|
||||
"wsnwlink.h",
|
||||
"wsrm.h",
|
||||
"mswsockdef.h",
|
||||
|
||||
@@ -375,7 +381,7 @@ public class CreateExampleGDTArchiveScript extends GhidraScript {
|
||||
"thumbcache.h",
|
||||
"thumbnailstreamcache.h",
|
||||
"tlogstg.h",
|
||||
"usereng.h",
|
||||
"userenv.h",
|
||||
|
||||
"# Windows Controls",
|
||||
"commctrl.h",
|
||||
@@ -452,12 +458,15 @@ public class CreateExampleGDTArchiveScript extends GhidraScript {
|
||||
"lmwksta.h"
|
||||
};
|
||||
|
||||
String includeFiles[] = {
|
||||
headerFilePath+"/VC/VS22/Community/VC/Tools/MSVC/14.29.30133/include",
|
||||
headerFilePath+"/VC/VS22/10.0.19041.0/shared",
|
||||
headerFilePath+"/VC/VS22/10.0.19041.0/ucrt",
|
||||
headerFilePath+"/VC/VS22/10.0.19041.0/um",
|
||||
headerFilePath+"/VC/VS22/10.0.19041.0/winrt",
|
||||
};
|
||||
|
||||
String args[] = {
|
||||
"-I"+headerFilePath+"/VC/VS22/Community/VC/Tools/MSVC/14.29.30133/include",
|
||||
"-I"+headerFilePath+"/VC/VS22/10.0.19041.0/shared",
|
||||
"-I"+headerFilePath+"/VC/VS22/10.0.19041.0/ucrt",
|
||||
"-I"+headerFilePath+"/VC/VS22/10.0.19041.0/um",
|
||||
"-I"+headerFilePath+"/VC/VS22/10.0.19041.0/winrt",
|
||||
"-D_MSC_VER=1924",
|
||||
"-D_INTEGRAL_MAX_BITS=64",
|
||||
"-DWINVER=0x0a00",
|
||||
@@ -473,7 +482,6 @@ public class CreateExampleGDTArchiveScript extends GhidraScript {
|
||||
"-DSTRSAFE_LIB",
|
||||
"-DSTRSAFE_LIB_IMPL",
|
||||
"-DLPSKBINFO=LPARAM",
|
||||
"-D_WCHAR_T_DEFINED",
|
||||
"-DCONST=const",
|
||||
"-D_CRT_SECURE_NO_WARNINGS",
|
||||
"-D_CRT_NONSTDC_NO_DEPRECATE",
|
||||
@@ -494,6 +502,6 @@ public class CreateExampleGDTArchiveScript extends GhidraScript {
|
||||
"-DSECURITY_WIN32",
|
||||
};
|
||||
|
||||
parseHeaderFilesToGDT(outputDirectory, "windows_vs22_64_new", "x86:LE:64:default", "windows", filenames, args);
|
||||
parseHeaderFilesToGDT(outputDirectory, "windows_vs22_64_new", "x86:LE:64:default", "windows", filenames, includeFiles, args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import ghidra.app.script.GhidraScript;
|
||||
import ghidra.app.services.DataTypeManagerService;
|
||||
import ghidra.framework.model.DomainFile;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.program.database.ProjectDataTypeManager;
|
||||
import ghidra.program.database.data.*;
|
||||
import ghidra.program.model.data.BuiltInDataTypeManager;
|
||||
import ghidra.program.model.data.DataTypeManager;
|
||||
|
||||
@@ -24,43 +24,59 @@ import java.io.File;
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.program.model.data.Category;
|
||||
import ghidra.program.model.data.FileDataTypeManager;
|
||||
import ghidra.program.model.data.StandAloneDataTypeManager.ArchiveWarning;
|
||||
import ghidra.util.InvalidNameException;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
public class SynchronizeGDTCategoryPaths extends GhidraScript {
|
||||
|
||||
private File firstFile;
|
||||
private File secondFile;
|
||||
private FileDataTypeManager firstArchive;
|
||||
private FileDataTypeManager secondArchive;
|
||||
|
||||
@Override
|
||||
protected void run() throws Exception {
|
||||
firstFile = askFile("Select First GDT File", "Select 1st");
|
||||
secondFile = askFile("Select Second GDT File", "Select 2nd");
|
||||
|
||||
try {
|
||||
firstArchive = FileDataTypeManager.openFileArchive(firstFile, false);
|
||||
secondArchive = FileDataTypeManager.openFileArchive(secondFile, true);
|
||||
|
||||
int transactionID = secondArchive.startTransaction("Synchronize Category Path Names");
|
||||
Category firstCategory = firstArchive.getRootCategory();
|
||||
Category secondCategory = secondArchive.getRootCategory();
|
||||
|
||||
synchronizeCategory(firstCategory, secondCategory);
|
||||
secondArchive.endTransaction(transactionID, true);
|
||||
}
|
||||
finally {
|
||||
if (firstArchive != null) {
|
||||
firstArchive.close();
|
||||
File firstFile = askFile("Select First GDT File", "Select 1st");
|
||||
try (FileDataTypeManager firstArchive =
|
||||
FileDataTypeManager.openFileArchive(firstFile, false)) {
|
||||
if (hasWarning(firstArchive, firstFile)) {
|
||||
return;
|
||||
}
|
||||
secondArchive.save();
|
||||
if (secondArchive != null) {
|
||||
secondArchive.close();
|
||||
|
||||
File secondFile = askFile("Select Second GDT File", "Select 2nd");
|
||||
try (FileDataTypeManager secondArchive =
|
||||
FileDataTypeManager.openFileArchive(secondFile, true)) {
|
||||
if (hasWarning(secondArchive, secondFile)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int transactionID =
|
||||
secondArchive.startTransaction("Synchronize Category Path Names");
|
||||
try {
|
||||
Category firstCategory = firstArchive.getRootCategory();
|
||||
Category secondCategory = secondArchive.getRootCategory();
|
||||
synchronizeCategory(firstCategory, secondCategory);
|
||||
}
|
||||
finally {
|
||||
secondArchive.endTransaction(transactionID, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasWarning(FileDataTypeManager archive, File file) {
|
||||
ArchiveWarning warning = archive.getWarning();
|
||||
if (warning == ArchiveWarning.NONE) {
|
||||
return false;
|
||||
}
|
||||
if (warning == ArchiveWarning.UPGRADED_LANGUAGE_VERSION) {
|
||||
return !askYesNo("Archive Upgrade Confirmation",
|
||||
"A language upgrade has been performed on archive " + file.getName() +
|
||||
"\nIs it OK to proceed?");
|
||||
}
|
||||
popup(
|
||||
"An architecture language error occured while opening archive (see log for details)\n" +
|
||||
file.getPath());
|
||||
return true;
|
||||
}
|
||||
|
||||
private void synchronizeCategory(Category firstCategory, Category secondCategory) {
|
||||
Category[] firstCategories = firstCategory.getCategories();
|
||||
for (Category categoryA : firstCategories) {
|
||||
|
||||
@@ -123,18 +123,27 @@
|
||||
|
||||
|
||||
<tocdef id="Ghidra Functionality"
|
||||
sortgroup="e"
|
||||
text="Ghidra Functionality"
|
||||
target = "help/topics/Intro/GhidraFunctionality.htm">
|
||||
<tocdef id="Code Browser" text="Code Browser" target="help/topics/CodeBrowserPlugin/CodeBrowser.htm" >
|
||||
<tocdef id="Browser Field Formatter" sortgroup="a" text="Browser Field Formatter" target="help/topics/CodeBrowserPlugin/Browser_Field_Formatter.htm" />
|
||||
<tocdef id="Markers" sortgroup="b" text="Markers" target="help/topics/CodeBrowserPlugin/CodeBrowser.htm#CBNavigationMarkers" />
|
||||
<tocdef id="Cursor Text Highlight" sortgroup="c" text="Cursor Text Highlight" target="help/topics/CodeBrowserPlugin/CodeBrowser.htm#cursorTextHighlight" />
|
||||
<tocdef id="Code Browser Configuration Options" sortgroup="d" text="Configuration Options" target="help/topics/CodeBrowserPlugin/CodeBrowserOptions.htm" />
|
||||
|
||||
|
||||
sortgroup="e"
|
||||
text="Ghidra Functionality"
|
||||
target = "help/topics/Intro/GhidraFunctionality.htm">
|
||||
<tocdef id="Code Browser" text="Code Browser" target="help/topics/CodeBrowserPlugin/CodeBrowser.htm" >
|
||||
<tocdef id="Browser Field Formatter" sortgroup="a" text="Browser Field Formatter" target="help/topics/CodeBrowserPlugin/Browser_Field_Formatter.htm" />
|
||||
<tocdef id="Markers" sortgroup="b" text="Markers" target="help/topics/CodeBrowserPlugin/CodeBrowser.htm#CBNavigationMarkers" />
|
||||
<tocdef id="Cursor Text Highlight" sortgroup="c" text="Cursor Text Highlight" target="help/topics/CodeBrowserPlugin/CodeBrowser.htm#cursorTextHighlight" />
|
||||
<tocdef id="Code Browser Configuration Options" sortgroup="d" text="Configuration Options" target="help/topics/CodeBrowserPlugin/CodeBrowserOptions.htm" />
|
||||
</tocdef>
|
||||
|
||||
|
||||
<tocdef id="Data Type Manager" sortgroup="c" text="Data Type Manager" target="help/topics/DataTypeManagerPlugin/data_type_manager_description.htm">
|
||||
<tocdef id="DTM Concepts" sortgroup="a" text="Basic Concepts" target="help/topics/DataTypeManagerPlugin/data_type_manager_description.htm#Basic_Concepts" />
|
||||
<tocdef id="DTM Window" sortgroup="b" text="Data Type Window" target="help/topics/DataTypeManagerPlugin/data_type_manager_window.html" />
|
||||
<tocdef id="DTM Working With Archives" sortgroup="c" text="Archives" target="help/topics/DataTypeManagerPlugin/data_type_manager_description.htm#Archives" />
|
||||
<tocdef id="DTM Working With Categories" sortgroup="d" text="Categories" target="help/topics/DataTypeManagerPlugin/data_type_manager_description.htm#Category" />
|
||||
<tocdef id="DTM Working With Data Types" sortgroup="e" text="Data Types" target="help/topics/DataTypeManagerPlugin/data_type_manager_description.htm#Data_Types" />
|
||||
<tocdef id="DTM Managing Archives" sortgroup="f" text="Managing Archives" target="help/topics/DataTypeManagerPlugin/data_type_manager_archives.html" />
|
||||
<tocdef id="Structure Editor" sortgroup="d" text="Structure Editor" target="help/topics/DataTypeEditors/StructureEditor.htm" />
|
||||
<tocdef id="Enum Editor" sortgroup="e" text="Enum Editor" target="help/topics/DataTypeEditors/EnumEditor.htm" />
|
||||
</tocdef>
|
||||
|
||||
<tocdef id="Assembler" text="Assembler" target="help/topics/AssemblerPlugin/Assembler.htm"></tocdef>
|
||||
|
||||
<tocdef id="Entropy Overview" text="Entropy Overview" target="help/topics/OverviewPlugin/Overview.htm#EntropyOverviewBar" >
|
||||
@@ -220,16 +229,6 @@
|
||||
<tocdef id="Data" sortgroup="c" text="Data" target="help/topics/DataPlugin/Data.htm" >
|
||||
<tocdef id="Create Data" sortgroup="a" text="Create Data" target="help/topics/DataPlugin/Data.htm" />
|
||||
<tocdef id="Data Types" sortgroup="b" text="Data Types" target="help/topics/DataPlugin/Data.htm#DataTypes" />
|
||||
<tocdef id="Data Type Manager" sortgroup="c" text="Data Type Manager" target="help/topics/DataTypeManagerPlugin/data_type_manager_description.htm">
|
||||
<tocdef id="DTM Concepts" sortgroup="a" text="Basic Concepts" target="help/topics/DataTypeManagerPlugin/data_type_manager_description.htm#Basic_Concepts" />
|
||||
<tocdef id="DTM Window" sortgroup="b" text="Data Type Window" target="help/topics/DataTypeManagerPlugin/data_type_manager_window.html" />
|
||||
<tocdef id="DTM Working With Archives" sortgroup="c" text="Archives" target="help/topics/DataTypeManagerPlugin/data_type_manager_description.htm#Archives" />
|
||||
<tocdef id="DTM Working With Categories" sortgroup="d" text="Categories" target="help/topics/DataTypeManagerPlugin/data_type_manager_description.htm#Category" />
|
||||
<tocdef id="DTM Working With Data Types" sortgroup="e" text="Data Types" target="help/topics/DataTypeManagerPlugin/data_type_manager_description.htm#Data_Types" />
|
||||
<tocdef id="DTM Managing Archives" sortgroup="f" text="Managing Archives" target="help/topics/DataTypeManagerPlugin/data_type_manager_archives.html" />
|
||||
</tocdef>
|
||||
<tocdef id="Structure Editor" sortgroup="d" text="Structure Editor" target="help/topics/DataTypeEditors/StructureEditor.htm" />
|
||||
<tocdef id="Enum Editor" sortgroup="e" text="Enum Editor" target="help/topics/DataTypeEditors/EnumEditor.htm" />
|
||||
<tocdef id="Translate Strings" sortgroup="e" text="Translate Strings" target="help/topics/TranslateStringsPlugin/TranslateStringsPlugin.htm" />
|
||||
<tocdef id="Save Image" sortgroup="e" text="Save Image" target="help/topics/ResourceActionsPlugin/ResourceActions.html" />
|
||||
</tocdef>
|
||||
|
||||
+53
@@ -353,6 +353,14 @@
|
||||
editing, since they support sharing and version control and therefore allow more than one
|
||||
user to modify them at a time. Only one user at a time can have a file archive opened for
|
||||
editing.</P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<P><IMG alt="" src="help/shared/tip.png">You can assign a specific <I>"Architecture"</I>
|
||||
to a Data Type Archive while it is open for editing. This is recommended when an archive is targeting
|
||||
a specific processor and compiler specification (see <A href="#Set_Archive_Architecture">Setting
|
||||
Data Type Archive Architecture</A>).</P>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
@@ -406,6 +414,51 @@
|
||||
Archive.</P>
|
||||
</BLOCKQUOTE>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<H3><A name="Set_Archive_Architecture"></A>Setting Data Type Archive Architecture</H3>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<P>By default, data type archives are not assigned an architecture and adopt a default
|
||||
<I>Data Organization</I> which determines primitive data type sizing (e.g., int, long, pointer, etc.)
|
||||
as well as alignment and packing behavior. While data types copied between archives or a program
|
||||
with disimilar <I>Data Organizations</I> will generally resolve correctly, unexpected results
|
||||
may sometimes arise (e.g., bit-field packing within structures). In addition, this situation
|
||||
frequently causes some confusion when viewing and editing data types where the <I>Data
|
||||
Organization</I> differs from the intended target architecture.</P>
|
||||
|
||||
<P>With either a file or project data type archive open for editing, a specific architecture
|
||||
may be assigned to the archive. This is done by selecting the open archive node from the
|
||||
data type tree, right-click on it and select the <I><B>Set Architecture...</B></I> action.
|
||||
This will popup a processor/compiler-specification selection dialog from which a selection
|
||||
may be made and the <B>OK</B> button clicked. A final confirmation dialog will be displayed
|
||||
before completing the change from which the <B>Set Architecture</B> or <B>Cancel</B> button
|
||||
must be clicked to confirm or cancel the change. If confirmed, any architecture transition
|
||||
will resolve all data types to the new data organization. Details related to custom variable
|
||||
storage for Function Definitions (not yet implemented) will be preserved if possible but
|
||||
may be discarded.</P>
|
||||
|
||||
<P>At present, the user will be forced to save any unsaved archive changes prior to completing
|
||||
an architecture setting change to allow for a fallback if neccessary.</P>
|
||||
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<H3><A name="Clear_Archive_Architecture"></A>Clearing Data Type Archive Architecture</H3>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
|
||||
<P>With either a file or project data type archive open for editing, a currently assigned architecture
|
||||
may be cleared for a selected archive. This is done by selecting the open archive node from the
|
||||
data type tree, right-click on it and select the <I><B>Clear Architecture</B></I> action.
|
||||
A final confirmation dialog will be displayed
|
||||
before completing the change from which the <B>Clear Architecture</B> or <B>Cancel</B> button
|
||||
must be clicked to confirm or cancel the change. If confirmed, the archive will revert a default
|
||||
<I>Data Organization</I> and any custom variable storage for Function Definitions
|
||||
(not yet implemented) will be discarded.
|
||||
|
||||
<P>At present, the user will be forced to save any unsaved changes prior to clearing the
|
||||
architecture setting to allow for a fallback if neccessary.</P>
|
||||
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<H3><A name="Close_Archive"></A>Closing a Data Type Archive</H3>
|
||||
|
||||
|
||||
+12
-19
@@ -140,6 +140,7 @@ public class ApplyFunctionSignatureCmd extends BackgroundCommand {
|
||||
func.updateFunction(conventionName, returnParam, params,
|
||||
FunctionUpdateType.DYNAMIC_STORAGE_FORMAL_PARAMS, false, source);
|
||||
func.setVarArgs(signature.hasVarArgs());
|
||||
func.setNoReturn(signature.hasNoReturn());
|
||||
}
|
||||
catch (DuplicateNameException e) {
|
||||
// should not happen unless caused by a concurrent operation
|
||||
@@ -212,29 +213,21 @@ public class ApplyFunctionSignatureCmd extends BackgroundCommand {
|
||||
}
|
||||
|
||||
private String getCallingConvention(Function function, CompilerSpec compilerSpec) {
|
||||
PrototypeModel preferredModel = null;
|
||||
if (signature.getGenericCallingConvention() != GenericCallingConvention.unknown) {
|
||||
preferredModel = compilerSpec.matchConvention(signature.getGenericCallingConvention());
|
||||
|
||||
// Ignore signature's calling convention if unknown/not-defined
|
||||
String callingConvention = signature.getCallingConventionName();
|
||||
if (compilerSpec.getCallingConvention(callingConvention) == null) {
|
||||
callingConvention = null;
|
||||
}
|
||||
|
||||
PrototypeModel convention = function.getCallingConvention();
|
||||
if (convention == null || !preserveCallingConvention) {
|
||||
convention = preferredModel;
|
||||
// NOTE: This has been disable since it can cause imported signature information to be
|
||||
// ignored and overwritten by subsequent analysis
|
||||
// if (convention == null && compilerSpec.getCallingConventions().length > 1) {
|
||||
// // use default source for signature if convention is really unknown so that we
|
||||
// // know dynamic storage assignment is unreliable
|
||||
// source = SourceType.DEFAULT;
|
||||
// }
|
||||
// Continue using function's current calling convention if valid and either
|
||||
// reservation was requested or signature's convention is unknown/not-defined.
|
||||
PrototypeModel currentConvention = function.getCallingConvention();
|
||||
if (currentConvention != null && (callingConvention == null || preserveCallingConvention)) {
|
||||
callingConvention = function.getCallingConventionName();
|
||||
}
|
||||
|
||||
// Calling convention is permitted to change
|
||||
String conventionName = function.getCallingConventionName();
|
||||
if (!preserveCallingConvention && convention != null) {
|
||||
conventionName = convention.getName();
|
||||
}
|
||||
return conventionName;
|
||||
return callingConvention;
|
||||
}
|
||||
|
||||
private static void updateStackPurgeSize(Function function, Program program) {
|
||||
|
||||
+2
@@ -1473,6 +1473,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||
ParameterDefinition[] sourceVars = sourceFunctionDefDt.getArguments();
|
||||
ParameterDefinition[] destVars = new ParameterDefinition[sourceVars.length];
|
||||
boolean sourceHasVarArgs = sourceFunctionDefDt.hasVarArgs();
|
||||
boolean sourceHasNoReturn = sourceFunctionDefDt.hasNoReturn();
|
||||
|
||||
DataType resolvedRDT = DataType.DEFAULT;
|
||||
if (sourceReturnType != null) {
|
||||
@@ -1492,6 +1493,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||
}
|
||||
destDt.setArguments(destVars);
|
||||
destDt.setVarArgs(sourceHasVarArgs);
|
||||
destDt.setNoReturn(sourceHasNoReturn);
|
||||
|
||||
destDt.setLastChangeTime(oldLastChangeTime);
|
||||
destDt.setLastChangeTimeInSourceArchive(oldLastChangeTimeInSourceArchive);
|
||||
|
||||
@@ -29,6 +29,7 @@ import ghidra.docking.settings.Settings;
|
||||
import ghidra.docking.settings.SettingsDefinition;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.data.Enum;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.listing.FunctionSignature;
|
||||
import ghidra.util.StringUtilities;
|
||||
import ghidra.util.UniversalID;
|
||||
@@ -348,7 +349,14 @@ class DataTypePanel extends JPanel {
|
||||
ParameterDefinition[] vars = fd.getArguments();
|
||||
|
||||
DataType returnType = fd.getReturnType();
|
||||
if (fd.hasNoReturn()) {
|
||||
insertString(FunctionSignature.NORETURN_DISPLAY_STRING + " ", contentAttrSet);
|
||||
}
|
||||
insertString(returnType.getDisplayName(), contentAttrSet);
|
||||
String callingConventionName = fd.getCallingConventionName();
|
||||
if (!Function.UNKNOWN_CALLING_CONVENTION_STRING.equals(callingConventionName)) {
|
||||
insertString(callingConventionName + " ", contentAttrSet);
|
||||
}
|
||||
insertString(" " + fd.getDisplayName(), nameAttrSet);
|
||||
insertString(" (", contentAttrSet);
|
||||
boolean hasVarArgs = fd.hasVarArgs();
|
||||
|
||||
+38
-6
@@ -15,7 +15,13 @@
|
||||
*/
|
||||
package ghidra.app.plugin.core.compositeeditor;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.lang.ProgramArchitecture;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
public class CompositeViewerDataTypeManager extends StandAloneDataTypeManager {
|
||||
|
||||
@@ -23,10 +29,10 @@ public class CompositeViewerDataTypeManager extends StandAloneDataTypeManager {
|
||||
* The data type manager for original composite data type being edited.
|
||||
* This is where the edited datatype will be written back to.
|
||||
*/
|
||||
private DataTypeManager originalDTM;
|
||||
private Composite originalComposite;
|
||||
private Composite viewComposite;
|
||||
private int transactionID;
|
||||
private final DataTypeManager originalDTM;
|
||||
private final Composite originalComposite;
|
||||
private final Composite viewComposite;
|
||||
private final int transactionID;
|
||||
|
||||
/**
|
||||
* Creates a data type manager that the structure editor will use
|
||||
@@ -39,16 +45,42 @@ public class CompositeViewerDataTypeManager extends StandAloneDataTypeManager {
|
||||
this.originalComposite = originalComposite;
|
||||
transactionID = startTransaction("");
|
||||
originalDTM = originalComposite.getDataTypeManager();
|
||||
universalID = originalDTM.getUniversalID(); // mimic original DTM
|
||||
|
||||
ProgramArchitecture arch = originalDTM.getProgramArchitecture();
|
||||
if (arch != null) {
|
||||
try {
|
||||
setProgramArchitecture(arch, null, true, TaskMonitor.DUMMY);
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
throw new AssertException(e); // unexpected
|
||||
}
|
||||
catch (IOException e) {
|
||||
errHandler.dbError(e);
|
||||
}
|
||||
}
|
||||
|
||||
viewComposite = (Composite) super.resolve(originalComposite, null);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected final boolean isArchitectureChangeAllowed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
endTransaction(transactionID, true);
|
||||
super.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link DataTypeManager} associated with the original composite datatype being edited.
|
||||
* @return original datatype manager
|
||||
*/
|
||||
public DataTypeManager getOriginalDataTypeManager() {
|
||||
return originalDTM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArchiveType getType() {
|
||||
return originalDTM.getType();
|
||||
|
||||
+4
@@ -1344,4 +1344,8 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
||||
return originalCompositeId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void programArchitectureChanged(DataTypeManager dataTypeManager) {
|
||||
// don't care
|
||||
}
|
||||
}
|
||||
|
||||
+59
-152
@@ -15,19 +15,13 @@
|
||||
*/
|
||||
package ghidra.app.plugin.core.cparser;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import org.apache.commons.io.DirectoryWalker.CancelException;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.action.DockingAction;
|
||||
import docking.action.MenuData;
|
||||
@@ -38,21 +32,17 @@ import ghidra.app.CorePluginPackage;
|
||||
import ghidra.app.plugin.PluginCategoryNames;
|
||||
import ghidra.app.plugin.ProgramPlugin;
|
||||
import ghidra.app.services.DataTypeManagerService;
|
||||
import ghidra.app.util.cparser.C.CParser;
|
||||
import ghidra.app.util.cparser.CPP.PreProcessor;
|
||||
import ghidra.app.util.cparser.C.CParserUtils;
|
||||
import ghidra.app.util.cparser.C.CParserUtils.CParseResults;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.options.SaveState;
|
||||
import ghidra.framework.plugintool.PluginInfo;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.framework.plugintool.util.PluginStatus;
|
||||
import ghidra.program.database.data.ProgramDataTypeManager;
|
||||
import ghidra.program.model.data.BuiltInDataTypeManager;
|
||||
import ghidra.program.model.data.DataTypeManager;
|
||||
import ghidra.program.model.data.FileDataTypeManager;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.util.HTMLUtilities;
|
||||
import ghidra.util.HelpLocation;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.*;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
@@ -66,22 +56,20 @@ import ghidra.util.task.TaskMonitor;
|
||||
)
|
||||
//@formatter:on
|
||||
public class CParserPlugin extends ProgramPlugin {
|
||||
final static String PARSE_ACTION_NAME = "Import C DataTypes";
|
||||
public final static String PARSE_ACTION_NAME = "Import C DataTypes";
|
||||
|
||||
final static String USER_PROFILES_DIR =
|
||||
Application.getUserSettingsDirectory().getAbsolutePath() + File.separatorChar +
|
||||
"parserprofiles";
|
||||
|
||||
private ParseDialog parseDialog;
|
||||
private File userProfileDir;
|
||||
|
||||
private String parserMessages;
|
||||
private String cppMessages;
|
||||
private CParseResults results;
|
||||
|
||||
final static String DESCRIPTION =
|
||||
"Parse C and C Header files, extracting data definitions and function signatures.";
|
||||
|
||||
private static final String PARSER_DEBUG_OUTFILE = "CParserPlugin.out";
|
||||
|
||||
public CParserPlugin(PluginTool plugintool) {
|
||||
super(plugintool);
|
||||
createActions();
|
||||
@@ -155,26 +143,37 @@ public class CParserPlugin extends ProgramPlugin {
|
||||
if (parseDialog == null) {
|
||||
parseDialog = new ParseDialog(this);
|
||||
}
|
||||
else {
|
||||
parseDialog.toFront();
|
||||
}
|
||||
parseDialog.setupForDisplay();
|
||||
tool.showDialog(parseDialog);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse into a saved data type data base file
|
||||
*/
|
||||
protected void parse(String[] filenames, String options, String dataFilename) {
|
||||
CParserTask parseTask = new CParserTask(this, filenames, options, dataFilename);
|
||||
protected void parse(String[] filenames, String includePaths[], String options,
|
||||
String languageIDString, String compilerSpecID, String dataFilename) {
|
||||
|
||||
CParserTask parseTask = new CParserTask(this, dataFilename)
|
||||
.setFileNames(filenames)
|
||||
.setIncludePaths(includePaths)
|
||||
.setOptions(options)
|
||||
.setLanguageID(languageIDString)
|
||||
.setCompilerID(compilerSpecID);
|
||||
|
||||
this.getTool().execute(parseTask, 500);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Parse C-source into a data type manager
|
||||
*/
|
||||
protected void parse(String[] filenames, String options, DataTypeManager dtMgr,
|
||||
protected void parse(String[] filenames, String includePaths[], String options,
|
||||
String languageIDString, String compilerSpecID, DataTypeManager dtMgr,
|
||||
TaskMonitor monitor) throws ghidra.app.util.cparser.C.ParseException,
|
||||
ghidra.app.util.cparser.CPP.ParseException {
|
||||
|
||||
results = null;
|
||||
|
||||
String[] args = parseOptions(options);
|
||||
|
||||
DataTypeManager openDTmanagers[] = null;
|
||||
@@ -184,100 +183,22 @@ public class CParserPlugin extends ProgramPlugin {
|
||||
return; // parse canceled
|
||||
}
|
||||
|
||||
cppMessages = "";
|
||||
PreProcessor cpp = new PreProcessor();
|
||||
|
||||
cpp.setArgs(args);
|
||||
|
||||
PrintStream os = System.out;
|
||||
String homeDir = System.getProperty("user.home");
|
||||
String fName = homeDir + File.separator + "CParserPlugin.out";
|
||||
try {
|
||||
os = new PrintStream(new FileOutputStream(fName));
|
||||
}
|
||||
catch (FileNotFoundException e2) {
|
||||
Msg.error(this, "Unexpected Exception: " + e2.getMessage(), e2);
|
||||
}
|
||||
|
||||
PrintStream old = System.out;
|
||||
System.setOut(os);
|
||||
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
cpp.setOutputStream(bos);
|
||||
cpp.setMonitor(monitor);
|
||||
|
||||
try {
|
||||
for (String filename : filenames) {
|
||||
if (monitor.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
// any file beginning with a "#" is assumed to be a comment
|
||||
if (filename.trim().startsWith("#")) {
|
||||
continue;
|
||||
}
|
||||
File file = new File(filename);
|
||||
|
||||
if (file.isDirectory()) {
|
||||
// process each header file in the directory
|
||||
String[] children = file.list();
|
||||
if (children == null) {
|
||||
continue;
|
||||
}
|
||||
for (String element : children) {
|
||||
File child = new File(file.getAbsolutePath() + "/" + element);
|
||||
if (child.getName().endsWith(".h")) {
|
||||
parseFile(child.getAbsolutePath(), monitor, cpp);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
parseFile(filename, monitor, cpp);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (RuntimeException re) {
|
||||
os.close();
|
||||
throw new ghidra.app.util.cparser.CPP.ParseException(re.getMessage());
|
||||
}
|
||||
|
||||
// process all the defines and add any that are integer values into
|
||||
// the Equates table
|
||||
cpp.getDefinitions().populateDefineEquates(openDTmanagers, dtMgr);
|
||||
|
||||
System.out.println(bos.toString());
|
||||
|
||||
System.setOut(old);
|
||||
os.close();
|
||||
|
||||
if (!monitor.isCancelled()) {
|
||||
monitor.setMessage("Parsing C");
|
||||
|
||||
CParser cParser = new CParser(dtMgr, true, openDTmanagers);
|
||||
cParser.setParseFileName(PARSER_DEBUG_OUTFILE);
|
||||
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
|
||||
try {
|
||||
parserMessages = "";
|
||||
cParser.setParseFileName(fName);
|
||||
cParser.setMonitor(monitor);
|
||||
cParser.parse(bis);
|
||||
}
|
||||
finally {
|
||||
parserMessages = cParser.getParseMessages();
|
||||
}
|
||||
|
||||
results = CParserUtils.parseHeaderFiles(openDTmanagers, filenames, includePaths,
|
||||
args, dtMgr, languageIDString, compilerSpecID, monitor);
|
||||
|
||||
final boolean isProgramDtMgr = (dtMgr instanceof ProgramDataTypeManager);
|
||||
|
||||
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
// CParserTask will show any errors
|
||||
if (!cParser.didParseSucceed()) {
|
||||
if (!results.successful()) {
|
||||
return;
|
||||
}
|
||||
if (isProgramDtMgr) {
|
||||
MultiLineMessageDialog.showModalMessageDialog(parseDialog.getComponent(),
|
||||
"C-Parse of Header Files Complete",
|
||||
"Successfully parsed header file(s) to Program.",
|
||||
getFormattedParseMessage(
|
||||
"Check the Manage Data Types window for added data types."),
|
||||
getFormattedParseMessage("Check the Manage Data Types window for added data types."),
|
||||
MultiLineMessageDialog.INFORMATION_MESSAGE);
|
||||
}
|
||||
else {
|
||||
@@ -286,20 +207,22 @@ public class CParserPlugin extends ProgramPlugin {
|
||||
archiveName = ((FileDataTypeManager) dtMgr).getFilename();
|
||||
}
|
||||
MultiLineMessageDialog.showModalMessageDialog(parseDialog.getComponent(),
|
||||
"C-Parse of Header Files Complete. ",
|
||||
"C-Parse of Header Files Complete",
|
||||
"Successfully parsed header file(s) to Archive File: " + archiveName,
|
||||
getFormattedParseMessage(null), MultiLineMessageDialog.INFORMATION_MESSAGE);
|
||||
getFormattedParseMessage(null),
|
||||
MultiLineMessageDialog.INFORMATION_MESSAGE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get open data type managers.
|
||||
* User can Use Open managers, Select not to use, or Cancel
|
||||
*
|
||||
* @param openDTmanagers open mgrs, null if don't use
|
||||
* @return array of open data type managers
|
||||
*
|
||||
* @throws CancelledException if user cancels
|
||||
@@ -335,7 +258,7 @@ public class CParserPlugin extends ProgramPlugin {
|
||||
"</ul>" + "<p><b>The new archive will become dependent on these archives<br>" +
|
||||
"for any datatypes already defined in them </b>(only unique <br>" +
|
||||
"data types will be added to the new archive).",
|
||||
"Use Open Archives?", "Don't Use Open Archives", OptionDialog.QUESTION_MESSAGE);
|
||||
"Use Open Archives", "Don't Use Open Archives", OptionDialog.QUESTION_MESSAGE);
|
||||
if (result == OptionDialog.CANCEL_OPTION) {
|
||||
throw new CancelledException("User Cancelled");
|
||||
}
|
||||
@@ -346,62 +269,40 @@ public class CParserPlugin extends ProgramPlugin {
|
||||
|
||||
return openDTmanagers;
|
||||
}
|
||||
|
||||
public CParseResults getParseResults() {
|
||||
return results;
|
||||
}
|
||||
|
||||
public String getParseMessage() {
|
||||
return (results != null ? results.cParseMessages() : "");
|
||||
}
|
||||
|
||||
public String getFormattedParseMessage(String errMsg) {
|
||||
protected String getFormattedParseMessage(String errMsg) {
|
||||
String message = "";
|
||||
|
||||
if (errMsg != null) {
|
||||
message += errMsg + "\n\n";
|
||||
}
|
||||
|
||||
String msg = getParseMessage();
|
||||
String msg = (results == null ? null : results.cParseMessages());
|
||||
if (msg != null && msg.length() != 0) {
|
||||
message += "CParser Messages:\n" + msg + "\n\n";
|
||||
}
|
||||
|
||||
msg = getPreProcessorMessage();
|
||||
msg = (results == null ? null : results.cppParseMessages());
|
||||
if (msg != null && msg.length() != 0) {
|
||||
message += "PreProcessor Messages:\n" + getPreProcessorMessage();
|
||||
message += "PreProcessor Messages:\n" + msg;
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get any parse messages produced by parsing good, or informational
|
||||
*
|
||||
* @return messages from parser
|
||||
*/
|
||||
public String getParseMessage() {
|
||||
return parserMessages;
|
||||
}
|
||||
|
||||
public String getPreProcessorMessage() {
|
||||
return cppMessages;
|
||||
}
|
||||
|
||||
private void parseFile(String filename, TaskMonitor monitor, PreProcessor cpp)
|
||||
throws ghidra.app.util.cparser.CPP.ParseException {
|
||||
monitor.setMessage("PreProcessing " + filename);
|
||||
try {
|
||||
Msg.info(this, "parse " + filename);
|
||||
cpp.parse(filename);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
Msg.error(this, "Parsing file :" + filename);
|
||||
Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
|
||||
|
||||
throw new ghidra.app.util.cparser.CPP.ParseException(e.getMessage());
|
||||
}
|
||||
finally {
|
||||
cppMessages += cpp.getParseMessages();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse into the current programs data type manager
|
||||
*/
|
||||
protected void parse(String[] filenames, String options) {
|
||||
protected void parse(String[] filenames, String[] includePaths, String options,
|
||||
String languageIDString, String compilerIDString) {
|
||||
if (currentProgram == null) {
|
||||
Msg.showInfo(getClass(), parseDialog.getComponent(), "No Open Program",
|
||||
"A program must be open to \"Parse to Program\"");
|
||||
@@ -413,8 +314,14 @@ public class CParserPlugin extends ProgramPlugin {
|
||||
if (result == OptionDialog.CANCEL_OPTION) {
|
||||
return;
|
||||
}
|
||||
|
||||
CParserTask parseTask =
|
||||
new CParserTask(this, filenames, options, currentProgram.getDataTypeManager());
|
||||
new CParserTask(this, currentProgram.getDataTypeManager())
|
||||
.setFileNames(filenames)
|
||||
.setIncludePaths(includePaths)
|
||||
.setOptions(options)
|
||||
.setLanguageID(languageIDString)
|
||||
.setCompilerID(compilerIDString);
|
||||
|
||||
tool.execute(parseTask);
|
||||
}
|
||||
|
||||
+71
-13
@@ -20,44 +20,97 @@ import java.io.File;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import docking.widgets.dialogs.MultiLineMessageDialog;
|
||||
import ghidra.program.model.data.DataTypeManager;
|
||||
import ghidra.program.model.data.FileDataTypeManager;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.DuplicateFileException;
|
||||
import ghidra.util.task.Task;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* This is called by the dialog box.
|
||||
* Background task to parse files for cparser plugin
|
||||
*
|
||||
*
|
||||
*/
|
||||
class CParserTask extends Task {
|
||||
private String[] filenames;
|
||||
private String options;
|
||||
|
||||
private CParserPlugin plugin;
|
||||
private String dataFileName;
|
||||
|
||||
private String[] filenames;
|
||||
private String[] includePaths;
|
||||
|
||||
private String options;
|
||||
|
||||
private String languageString;
|
||||
private String compilerString;
|
||||
|
||||
private DataTypeManager dtMgr;
|
||||
|
||||
CParserTask(CParserPlugin plugin, String[] filenames, String options, String dataFileName) {
|
||||
|
||||
/**
|
||||
* Create task to parse to a dataFile
|
||||
*
|
||||
* @param plugin CParserPlugin that will do the work
|
||||
* @param dataFileName name of the file to parse to
|
||||
*/
|
||||
CParserTask(CParserPlugin plugin, String dataFileName) {
|
||||
super("Parsing C Files", true, false, false);
|
||||
|
||||
this.plugin = plugin;
|
||||
this.filenames = filenames;
|
||||
this.options = options;
|
||||
this.dataFileName = dataFileName;
|
||||
}
|
||||
|
||||
public CParserTask(CParserPlugin plugin, String[] filenames, String options,
|
||||
DataTypeManager dataTypeManager) {
|
||||
/**
|
||||
* Create task to parse to a dataTypeManager
|
||||
*
|
||||
* @param plugin
|
||||
* @param dataTypeManager
|
||||
*/
|
||||
public CParserTask(CParserPlugin plugin, DataTypeManager dataTypeManager) {
|
||||
super("Parsing C Files", true, false, false);
|
||||
|
||||
this.plugin = plugin;
|
||||
this.filenames = filenames;
|
||||
this.options = options;
|
||||
this.dtMgr = dataTypeManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create task to parse to a ProgramDataTypeManager
|
||||
*
|
||||
* @param plugin
|
||||
* @param dataTypeManager
|
||||
*/
|
||||
public CParserTask(CParserPlugin plugin, ProgramBasedDataTypeManager dataTypeManager) {
|
||||
super("Parsing C Files", true, false, false);
|
||||
|
||||
this.plugin = plugin;
|
||||
this.dtMgr = dataTypeManager;
|
||||
}
|
||||
|
||||
public CParserTask setLanguageID(String languageID) {
|
||||
this.languageString = languageID;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CParserTask setCompilerID(String compilerID) {
|
||||
this.compilerString = compilerID;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CParserTask setIncludePaths(String includePaths[]) {
|
||||
this.includePaths = includePaths.clone();
|
||||
return this;
|
||||
}
|
||||
|
||||
public CParserTask setFileNames(String names[]) {
|
||||
this.filenames = names.clone();
|
||||
return this;
|
||||
}
|
||||
|
||||
public CParserTask setOptions(String options) {
|
||||
this.options = options;
|
||||
return this;
|
||||
}
|
||||
|
||||
private String getFirstMessageLine(final String errMsg) {
|
||||
int indexOf = errMsg.indexOf('\n');
|
||||
String msg = errMsg;
|
||||
@@ -77,8 +130,9 @@ class CParserTask extends Task {
|
||||
fileDtMgr = dtMgr;
|
||||
}
|
||||
|
||||
plugin.parse(filenames, options, dtMgr, monitor);
|
||||
plugin.parse(filenames, includePaths, options, languageString, compilerString, dtMgr, monitor);
|
||||
if (dataFileName != null) {
|
||||
// TODO: does not consider existing datatypes
|
||||
if (dtMgr.getDataTypeCount(true) != 0) {
|
||||
try {
|
||||
((FileDataTypeManager) dtMgr).save();
|
||||
@@ -102,6 +156,10 @@ class CParserTask extends Task {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// no results, was canceled
|
||||
if (plugin.getParseResults() == null) {
|
||||
return;
|
||||
}
|
||||
MultiLineMessageDialog.showModalMessageDialog(
|
||||
plugin.getDialog().getComponent(), "Parse Errors",
|
||||
"File was not created due to parse errors: " +
|
||||
|
||||
+404
-81
File diff suppressed because it is too large
Load Diff
+4
@@ -180,6 +180,10 @@ public class DataTypesProvider extends ComponentProviderAdapter {
|
||||
addLocalAction(new LockArchiveAction(plugin)); // Archive
|
||||
addLocalAction(new UnlockArchiveAction(plugin)); // Archive
|
||||
|
||||
// Arch group
|
||||
addLocalAction(new SetArchiveArchitectureAction(plugin)); // Archive
|
||||
addLocalAction(new ClearArchiveArchitectureAction(plugin)); // Archive
|
||||
|
||||
// Repository group : version control actions
|
||||
addVersionControlActions(); // Archive
|
||||
|
||||
|
||||
+187
@@ -0,0 +1,187 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.plugin.core.datamgr.actions;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.action.DockingAction;
|
||||
import docking.action.MenuData;
|
||||
import docking.widgets.OptionDialog;
|
||||
import docking.widgets.tree.GTree;
|
||||
import docking.widgets.tree.GTreeNode;
|
||||
import generic.theme.GThemeDefaults.Colors.Messages;
|
||||
import ghidra.app.plugin.core.datamgr.DataTypeManagerPlugin;
|
||||
import ghidra.app.plugin.core.datamgr.DataTypesActionContext;
|
||||
import ghidra.app.plugin.core.datamgr.archive.*;
|
||||
import ghidra.app.plugin.core.datamgr.tree.*;
|
||||
import ghidra.framework.model.DomainFile;
|
||||
import ghidra.framework.store.LockException;
|
||||
import ghidra.program.model.data.StandAloneDataTypeManager;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.*;
|
||||
|
||||
public class ClearArchiveArchitectureAction extends DockingAction {
|
||||
|
||||
private final DataTypeManagerPlugin plugin;
|
||||
|
||||
public ClearArchiveArchitectureAction(DataTypeManagerPlugin plugin) {
|
||||
super("Clear Archive Architecture", plugin.getName());
|
||||
this.plugin = plugin;
|
||||
|
||||
setPopupMenuData(new MenuData(new String[] { "Clear Architecture" }, null, "SetArch"));
|
||||
|
||||
setDescription(
|
||||
"Clear program-architecture associated with a data type archive (existing custom storage details will be discarded)");
|
||||
|
||||
setEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabledForContext(ActionContext context) {
|
||||
if (!(context instanceof DataTypesActionContext)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Object contextObject = context.getContextObject();
|
||||
GTree gtree = (GTree) contextObject;
|
||||
TreePath[] selectionPaths = gtree.getSelectionPaths();
|
||||
|
||||
if (selectionPaths.length != 1) {
|
||||
return false;
|
||||
}
|
||||
GTreeNode node = (GTreeNode) selectionPaths[0].getLastPathComponent();
|
||||
if (!(node instanceof FileArchiveNode) && !(node instanceof ProjectArchiveNode)) {
|
||||
return false;
|
||||
}
|
||||
ArchiveNode archiveNode = (ArchiveNode) node;
|
||||
StandAloneDataTypeManager dtm =
|
||||
(StandAloneDataTypeManager) archiveNode.getArchive().getDataTypeManager();
|
||||
|
||||
return dtm.getProgramArchitectureSummary() != null && dtm.isUpdatable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
GTree gtree = (GTree) context.getContextObject();
|
||||
TreePath[] selectionPaths = gtree.getSelectionPaths();
|
||||
if (selectionPaths.length != 1) {
|
||||
return;
|
||||
}
|
||||
GTreeNode node = (GTreeNode) selectionPaths[0].getLastPathComponent();
|
||||
if (!(node instanceof FileArchiveNode) && !(node instanceof ProjectArchiveNode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (node instanceof ProjectArchiveNode) {
|
||||
ProjectArchiveNode paNode = (ProjectArchiveNode) node;
|
||||
ProjectArchive pa = (ProjectArchive) paNode.getArchive();
|
||||
if (!pa.hasExclusiveAccess()) {
|
||||
Msg.showError(this, null, "Clear Program Architecture Failed",
|
||||
"Clearing program-architecture on Project Archive requires exclusive checkout.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ArchiveNode archiveNode = (ArchiveNode) node;
|
||||
StandAloneDataTypeManager dtm =
|
||||
(StandAloneDataTypeManager) archiveNode.getArchive().getDataTypeManager();
|
||||
|
||||
if (dtm.isChanged()) {
|
||||
if (OptionDialog.OPTION_ONE != OptionDialog.showOptionDialogWithCancelAsDefaultButton(
|
||||
null, "Save Archive Changes",
|
||||
"Archive has unsaved changes which must be saved before continuing." +
|
||||
"\nThis is required to allow for a reversion to the previous saved state.",
|
||||
"Save")) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
archiveNode.getArchive().save();
|
||||
}
|
||||
catch (IOException e) {
|
||||
Msg.showError(this, null, "Save Archive Failed",
|
||||
"Failed to save changes for Archive: " + dtm.getName() + "\n" + e.getMessage());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Update message indicating that custom storage specification will not be
|
||||
// retained/permitted (once supported)
|
||||
String msg = "<html>Clear program-architecture for Archive?<BR><font color=\"" +
|
||||
Messages.NORMAL + "\">" + dtm.getPath() +
|
||||
"</font><BR> <BR>Archive will revert to using default data organization.";
|
||||
int response = OptionDialog.showOptionDialogWithCancelAsDefaultButton(null,
|
||||
"Confirm Clearing Archive Architecture", msg, "Clear Architecture",
|
||||
OptionDialog.WARNING_MESSAGE);
|
||||
if (response != OptionDialog.OPTION_ONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
new TaskLauncher(new ClearProgramArchitectureTask(archiveNode.getArchive(), dtm));
|
||||
}
|
||||
|
||||
private class ClearProgramArchitectureTask extends Task {
|
||||
|
||||
private final Archive archive;
|
||||
private final StandAloneDataTypeManager dtm;
|
||||
|
||||
public ClearProgramArchitectureTask(Archive archive, StandAloneDataTypeManager dtm) {
|
||||
super("Clearing Program-Architecture for Archive", true, false, true, false);
|
||||
this.archive = archive;
|
||||
this.dtm = dtm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(TaskMonitor monitor) throws CancelledException {
|
||||
boolean success = false;
|
||||
try {
|
||||
dtm.clearProgramArchitecture(monitor);
|
||||
success = true;
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e) {
|
||||
Msg.showError(this, null, "Archive Update Failed",
|
||||
"Failed to clear program-architecture for Archive: " + dtm.getName() + "\n" +
|
||||
e.getMessage());
|
||||
}
|
||||
finally {
|
||||
if (!success) {
|
||||
if (archive instanceof FileArchive) {
|
||||
try {
|
||||
((FileArchive) archive).releaseWriteLock();
|
||||
((FileArchive) archive).acquireWriteLock();
|
||||
}
|
||||
catch (LockException | IOException e) {
|
||||
archive.close();
|
||||
}
|
||||
}
|
||||
else { // if (archive instanceof ProjectArchive) {
|
||||
archive.close();
|
||||
DomainFile df = ((ProjectArchive) archive).getDomainFile();
|
||||
plugin.openArchive(df);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+1
-2
@@ -37,8 +37,7 @@ public class DeleteArchiveAction extends DockingAction {
|
||||
public DeleteArchiveAction(DataTypeManagerPlugin plugin) {
|
||||
super("Delete Archive", plugin.getName());
|
||||
|
||||
// ACTIONS - auto generated
|
||||
setPopupMenuData(new MenuData(new String[] { "Delete Archive" }, null, "Edit"));
|
||||
setPopupMenuData(new MenuData(new String[] { "Delete Archive" }, null, "File"));
|
||||
|
||||
setKeyBindingData(new KeyBindingData(KeyEvent.VK_DELETE, 0));
|
||||
|
||||
|
||||
+259
@@ -0,0 +1,259 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.plugin.core.datamgr.actions;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.action.DockingAction;
|
||||
import docking.action.MenuData;
|
||||
import docking.widgets.OptionDialog;
|
||||
import docking.widgets.tree.GTree;
|
||||
import docking.widgets.tree.GTreeNode;
|
||||
import generic.theme.GThemeDefaults.Colors.Messages;
|
||||
import ghidra.app.plugin.core.datamgr.DataTypeManagerPlugin;
|
||||
import ghidra.app.plugin.core.datamgr.DataTypesActionContext;
|
||||
import ghidra.app.plugin.core.datamgr.archive.*;
|
||||
import ghidra.app.plugin.core.datamgr.tree.*;
|
||||
import ghidra.app.plugin.core.processors.SetLanguageDialog;
|
||||
import ghidra.framework.model.DomainFile;
|
||||
import ghidra.framework.store.LockException;
|
||||
import ghidra.program.model.data.StandAloneDataTypeManager;
|
||||
import ghidra.program.model.data.StandAloneDataTypeManager.LanguageUpdateOption;
|
||||
import ghidra.program.model.lang.*;
|
||||
import ghidra.program.model.listing.IncompatibleLanguageException;
|
||||
import ghidra.program.util.DefaultLanguageService;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.Swing;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.*;
|
||||
|
||||
public class SetArchiveArchitectureAction extends DockingAction {
|
||||
|
||||
private final DataTypeManagerPlugin plugin;
|
||||
|
||||
public SetArchiveArchitectureAction(DataTypeManagerPlugin plugin) {
|
||||
super("Set Archive Architecture", plugin.getName());
|
||||
this.plugin = plugin;
|
||||
|
||||
setPopupMenuData(new MenuData(new String[] { "Set Architecture..." }, null, "SetArch"));
|
||||
|
||||
setDescription("Set program-architecture associated with a data type archive");
|
||||
|
||||
setEnabled(true);
|
||||
}
|
||||
|
||||
private TreePath getSelectionPath(ActionContext context) {
|
||||
Object contextObject = context.getContextObject();
|
||||
GTree gtree = (GTree) contextObject;
|
||||
TreePath[] selectionPaths = gtree.getSelectionPaths();
|
||||
if (selectionPaths.length != 1) {
|
||||
return null;
|
||||
}
|
||||
return selectionPaths[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabledForContext(ActionContext context) {
|
||||
if (!(context instanceof DataTypesActionContext)) {
|
||||
return false;
|
||||
}
|
||||
TreePath selectionPath = getSelectionPath(context);
|
||||
if (selectionPath == null) {
|
||||
return false;
|
||||
}
|
||||
GTreeNode node = (GTreeNode) selectionPath.getLastPathComponent();
|
||||
if (!(node instanceof FileArchiveNode) && !(node instanceof ProjectArchiveNode)) {
|
||||
return false;
|
||||
}
|
||||
ArchiveNode archiveNode = (ArchiveNode) node;
|
||||
StandAloneDataTypeManager dtm =
|
||||
(StandAloneDataTypeManager) archiveNode.getArchive().getDataTypeManager();
|
||||
return dtm.isUpdatable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
TreePath selectionPath = getSelectionPath(context);
|
||||
if (selectionPath == null) {
|
||||
return;
|
||||
}
|
||||
GTreeNode node = (GTreeNode) selectionPath.getLastPathComponent();
|
||||
if (!(node instanceof FileArchiveNode) && !(node instanceof ProjectArchiveNode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (node instanceof ProjectArchiveNode) {
|
||||
ProjectArchiveNode paNode = (ProjectArchiveNode) node;
|
||||
ProjectArchive pa = (ProjectArchive) paNode.getArchive();
|
||||
if (!pa.hasExclusiveAccess()) {
|
||||
Msg.showError(this, null, "Set Program Architecture Failed",
|
||||
"Setting program-architecture on Project Archive requires exclusive checkout.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ArchiveNode archiveNode = (ArchiveNode) node;
|
||||
StandAloneDataTypeManager dtm =
|
||||
(StandAloneDataTypeManager) archiveNode.getArchive().getDataTypeManager();
|
||||
|
||||
if (dtm.isChanged()) {
|
||||
if (OptionDialog.OPTION_ONE != OptionDialog.showOptionDialogWithCancelAsDefaultButton(
|
||||
null, "Save Archive Changes",
|
||||
"Archive has unsaved changes which must be saved before continuing." +
|
||||
"\nThis is required to allow for a reversion to the previous saved state.",
|
||||
"Save")) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
archiveNode.getArchive().save();
|
||||
}
|
||||
catch (IOException e) {
|
||||
Msg.showError(this, null, "Save Archive Failed",
|
||||
"Failed to save changes for Archive: " + dtm.getName() + "\n" + e.getMessage());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SetLanguageDialog dialog = new SetLanguageDialog(plugin.getTool(),
|
||||
dtm.getProgramArchitecture(),
|
||||
"Select Program Architecture for Archive: " + dtm.getName());
|
||||
LanguageID languageId = dialog.getLanguageDescriptionID();
|
||||
CompilerSpecID compilerSpecId = dialog.getCompilerSpecDescriptionID();
|
||||
if ((languageId == null) || (compilerSpecId == null)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Language language = DefaultLanguageService.getLanguageService().getLanguage(languageId);
|
||||
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(languageId.getIdAsString());
|
||||
buf.append(" / ");
|
||||
buf.append(compilerSpecId.getIdAsString());
|
||||
String newProgramArchitectureSummary = buf.toString();
|
||||
|
||||
String programArchitectureSummary = dtm.getProgramArchitectureSummary();
|
||||
String msg =
|
||||
"<html>Set program-architecture for Archive?<BR><font color=\"" + Messages.NORMAL +
|
||||
"\">" + dtm.getPath() + "</font><pre>";
|
||||
if (programArchitectureSummary != null) {
|
||||
msg +=
|
||||
"\nChange Language/Compiler\n from: <font color=\"" + Messages.NORMAL +
|
||||
"\">" +
|
||||
programArchitectureSummary + "</font>\n to: ";
|
||||
}
|
||||
else {
|
||||
msg += "\n\nLanguage/Compiler: ";
|
||||
}
|
||||
msg += "<font color=\"" + Messages.NORMAL + "\">";
|
||||
msg += newProgramArchitectureSummary;
|
||||
msg += "</font></pre>";
|
||||
int response = OptionDialog.showOptionDialogWithCancelAsDefaultButton(null,
|
||||
"Confirm Archive Architecture Change", msg, "Set Architecture",
|
||||
OptionDialog.WARNING_MESSAGE);
|
||||
if (response != OptionDialog.OPTION_ONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
new TaskLauncher(new SetProgramArchitectureTask(archiveNode.getArchive(), dtm, language,
|
||||
compilerSpecId));
|
||||
}
|
||||
catch (LanguageNotFoundException e) {
|
||||
Msg.showError(this, null, "Archive Update Failed",
|
||||
"Failed to set program-architecture for Archive: " + dtm.getName() + "\n" +
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private class SetProgramArchitectureTask extends Task {
|
||||
|
||||
private final Archive archive;
|
||||
private final StandAloneDataTypeManager dtm;
|
||||
private final Language language;
|
||||
private final CompilerSpecID compilerSpecId;
|
||||
|
||||
public SetProgramArchitectureTask(Archive archive, StandAloneDataTypeManager dtm,
|
||||
Language language, CompilerSpecID compilerSpecId) {
|
||||
super("Updating Program-Architecture for Archive", true, false, true, false);
|
||||
this.archive = archive;
|
||||
this.dtm = dtm;
|
||||
this.language = language;
|
||||
this.compilerSpecId = compilerSpecId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(TaskMonitor monitor) throws CancelledException {
|
||||
|
||||
boolean success = false;
|
||||
try {
|
||||
try {
|
||||
dtm.setProgramArchitecture(language, compilerSpecId,
|
||||
LanguageUpdateOption.TRANSLATE, monitor);
|
||||
success = true;
|
||||
}
|
||||
catch (IncompatibleLanguageException e) {
|
||||
int resp = OptionDialog.showOptionDialog(null, "Archive Architecture Change",
|
||||
"<html>Unable to translate storage for specified architecture change.<BR><font color=\"" +
|
||||
Messages.NORMAL + "\">" + dtm.getPath() +
|
||||
"</font><BR><BR>Would you like to Clear custom storage information or Cancel change?",
|
||||
"Clear");
|
||||
if (resp == OptionDialog.CANCEL_OPTION) {
|
||||
success = true; // keep archive open
|
||||
return;
|
||||
}
|
||||
LanguageUpdateOption updateOption = LanguageUpdateOption.CLEAR;
|
||||
if (resp == OptionDialog.OPTION_TWO) {
|
||||
updateOption = LanguageUpdateOption.UNCHANGED;
|
||||
}
|
||||
dtm.setProgramArchitecture(language, compilerSpecId, updateOption, monitor);
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e) {
|
||||
Msg.showError(this, null, "Archive Update Failed",
|
||||
"Failed to set program-architecture for Archive: " + dtm.getName() + "\n" +
|
||||
e.getMessage());
|
||||
}
|
||||
finally {
|
||||
if (!success) {
|
||||
Swing.runNow(() -> {
|
||||
/* flush event queue before closing archive */ });
|
||||
if (archive instanceof FileArchive) {
|
||||
try {
|
||||
((FileArchive) archive).releaseWriteLock();
|
||||
((FileArchive) archive).acquireWriteLock();
|
||||
}
|
||||
catch (LockException | IOException e) {
|
||||
archive.close();
|
||||
}
|
||||
}
|
||||
else { // if (archive instanceof ProjectArchive) {
|
||||
archive.close();
|
||||
DomainFile df = ((ProjectArchive) archive).getDomainFile();
|
||||
plugin.openArchive(df);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+9
-5
@@ -96,17 +96,21 @@ public class ArchiveUtils {
|
||||
return true;
|
||||
}
|
||||
catch (ReadOnlyException e) {
|
||||
Msg.showError(log, null, "Unable to Lock File for Writing", e.getMessage());
|
||||
Msg.showError(log, null, "Unable to Lock Archive for Writing", e.getMessage());
|
||||
}
|
||||
catch (LockException exc) {
|
||||
Msg.showError(log, null, "Unable to Lock File for Writing",
|
||||
Msg.showError(log, null, "Unable to Lock Archive for Writing",
|
||||
"Unable to obtain lock for archive: " + archive.getName() + "\n" +
|
||||
exc.getMessage());
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
Msg.showError(log, null, "Unable to Lock File for Writing",
|
||||
"Problem attempting to lock archive: " + archive.getName() + "\n" +
|
||||
ioe.getMessage());
|
||||
Throwable cause = ioe.getCause();
|
||||
if (cause == null) {
|
||||
cause = ioe;
|
||||
}
|
||||
Msg.showError(log, null, "Unable to Lock Archive for Writing",
|
||||
"Problem attempting to open archive for update: " + archive.getName() + "\n" +
|
||||
cause.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
+5
@@ -219,5 +219,10 @@ public class DataTypeIndexer {
|
||||
public void sourceArchiveChanged(DataTypeManager dtm, SourceArchive dataTypeSource) {
|
||||
markStale();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void programArchitectureChanged(DataTypeManager dataTypeManager) {
|
||||
markStale();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+12
-5
@@ -437,12 +437,13 @@ public class DataTypeManagerHandler {
|
||||
return openArchive(new ResourceFile(file), acquireWriteLock, isUserAction);
|
||||
}
|
||||
|
||||
public Archive openArchive(ResourceFile file, boolean acquireWriteLock, boolean isUserAction)
|
||||
public FileArchive openArchive(ResourceFile file, boolean acquireWriteLock,
|
||||
boolean isUserAction)
|
||||
throws IOException, DuplicateIdException {
|
||||
|
||||
file = file.getCanonicalFile();
|
||||
|
||||
Archive archive = getArchiveForFile(file);
|
||||
FileArchive archive = getArchiveForFile(file);
|
||||
if (archive == null) {
|
||||
archive = new FileArchive(this, file, acquireWriteLock);
|
||||
Archive existingArchive =
|
||||
@@ -451,11 +452,10 @@ public class DataTypeManagerHandler {
|
||||
archive.close();
|
||||
throw new DuplicateIdException(archive.getName(), existingArchive.getName());
|
||||
}
|
||||
|
||||
addArchivePath(file);
|
||||
addArchive(archive);
|
||||
}
|
||||
if (isUserAction && (archive instanceof FileArchive)) {
|
||||
if (isUserAction) {
|
||||
userOpenedFileArchiveNames.add(getSaveableArchive(file.getAbsolutePath()));
|
||||
}
|
||||
return archive;
|
||||
@@ -524,7 +524,7 @@ public class DataTypeManagerHandler {
|
||||
return null;
|
||||
}
|
||||
|
||||
private Archive getArchiveForFile(ResourceFile file) {
|
||||
private FileArchive getArchiveForFile(ResourceFile file) {
|
||||
for (Archive archive : openArchives) {
|
||||
if (archive instanceof FileArchive) {
|
||||
FileArchive fileArchive = (FileArchive) archive;
|
||||
@@ -1230,6 +1230,13 @@ public class DataTypeManagerHandler {
|
||||
listener.sourceArchiveChanged(dataTypeManager, dataTypeSource);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void programArchitectureChanged(DataTypeManager dataTypeManager) {
|
||||
for (DataTypeManagerChangeListener listener : dataTypeManagerListeners) {
|
||||
listener.programArchitectureChanged(dataTypeManager);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user