Update java code to include parameter names and types
This commit is contained in:
parent
cfb41094d5
commit
bd98761921
|
@ -17,7 +17,11 @@ public class Test extends GhidraScript {
|
||||||
try (FunctionDatabase db = new FunctionDatabase(this)) {
|
try (FunctionDatabase db = new FunctionDatabase(this)) {
|
||||||
List<FunctionDatabase.FunctionEntry> entries = db.loadAllEntries();
|
List<FunctionDatabase.FunctionEntry> entries = db.loadAllEntries();
|
||||||
for (FunctionDatabase.FunctionEntry entry : entries) {
|
for (FunctionDatabase.FunctionEntry entry : entries) {
|
||||||
println("entry.name: " + entry.name + " entry.address: " + entry.address + " entry.type: " + entry.type);
|
println("entry.name: " + entry.name + " entry.address: " + entry.address + " entry.type: " + entry.type
|
||||||
|
+ " calling_convention: " + entry.callingConvention + " return_type: " + entry.returnType);
|
||||||
|
if (!entry.parameterNames.isEmpty()) {
|
||||||
|
println(" parameters: " + entry.parameterNames + " | types: " + entry.parameterTypes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,17 +105,51 @@ public class FunctionDatabase implements AutoCloseable {
|
||||||
public File file;
|
public File file;
|
||||||
public Type type;
|
public Type type;
|
||||||
public CallingConvention callingConvention;
|
public CallingConvention callingConvention;
|
||||||
|
public String parameterNames; // Semicolon-separated parameter names
|
||||||
|
public String parameterTypes; // Semicolon-separated parameter types
|
||||||
|
public String returnType; // Function return type
|
||||||
|
|
||||||
public FunctionEntry(Address address, String name, File file, Type type) {
|
public FunctionEntry(Address address, String name, File file, Type type, CallingConvention callingConvention,
|
||||||
this(address, name, file, type, CallingConvention.Cdecl);
|
String parameterNames, String parameterTypes, String returnType) {
|
||||||
}
|
|
||||||
|
|
||||||
public FunctionEntry(Address address, String name, File file, Type type, CallingConvention callingConvention) {
|
|
||||||
this.address = address;
|
this.address = address;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.callingConvention = callingConvention;
|
this.callingConvention = callingConvention;
|
||||||
|
this.parameterNames = parameterNames != null ? parameterNames : "";
|
||||||
|
this.parameterTypes = parameterTypes != null ? parameterTypes : "";
|
||||||
|
this.returnType = returnType != null ? returnType : "void";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper methods to work with semicolon-separated parameter lists
|
||||||
|
public String[] getParameterNamesArray() {
|
||||||
|
if (parameterNames == null || parameterNames.trim().isEmpty()) {
|
||||||
|
return new String[0];
|
||||||
|
}
|
||||||
|
return parameterNames.split(";");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getParameterTypesArray() {
|
||||||
|
if (parameterTypes == null || parameterTypes.trim().isEmpty()) {
|
||||||
|
return new String[0];
|
||||||
|
}
|
||||||
|
return parameterTypes.split(";");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParameterNamesArray(String[] names) {
|
||||||
|
if (names == null || names.length == 0) {
|
||||||
|
this.parameterNames = "";
|
||||||
|
} else {
|
||||||
|
this.parameterNames = String.join(";", names);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParameterTypesArray(String[] types) {
|
||||||
|
if (types == null || types.length == 0) {
|
||||||
|
this.parameterTypes = "";
|
||||||
|
} else {
|
||||||
|
this.parameterTypes = String.join(";", types);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,21 +244,21 @@ public class FunctionDatabase implements AutoCloseable {
|
||||||
private void prepareCachedStatements() throws SQLException {
|
private void prepareCachedStatements() throws SQLException {
|
||||||
// Find by name
|
// Find by name
|
||||||
findByNameFunctions = connection.prepareStatement(
|
findByNameFunctions = connection.prepareStatement(
|
||||||
"SELECT filepath, name, address, type, calling_convention FROM Functions WHERE name = ?");
|
"SELECT filepath, name, address, type, calling_convention, parameter_names, parameter_types, return_type FROM Functions WHERE name = ?");
|
||||||
findByNameImports = connection.prepareStatement(
|
findByNameImports = connection.prepareStatement(
|
||||||
"SELECT filepath, name, address, type, calling_convention FROM Imports WHERE name = ?");
|
"SELECT filepath, name, address, type, calling_convention, parameter_names, parameter_types, return_type FROM Imports WHERE name = ?");
|
||||||
|
|
||||||
// Find by address
|
// Find by address
|
||||||
findByAddressFunctions = connection.prepareStatement(
|
findByAddressFunctions = connection.prepareStatement(
|
||||||
"SELECT filepath, name, address, type, calling_convention FROM Functions WHERE address = ?");
|
"SELECT filepath, name, address, type, calling_convention, parameter_names, parameter_types, return_type FROM Functions WHERE address = ?");
|
||||||
findByAddressImports = connection.prepareStatement(
|
findByAddressImports = connection.prepareStatement(
|
||||||
"SELECT filepath, name, address, type, calling_convention FROM Imports WHERE address = ?");
|
"SELECT filepath, name, address, type, calling_convention, parameter_names, parameter_types, return_type FROM Imports WHERE address = ?");
|
||||||
|
|
||||||
// Insert or replace
|
// Insert or replace
|
||||||
insertOrReplaceFunctions = connection.prepareStatement(
|
insertOrReplaceFunctions = connection.prepareStatement(
|
||||||
"INSERT OR REPLACE INTO Functions (filepath, name, address, type, calling_convention) VALUES (?, ?, ?, ?, ?)");
|
"INSERT OR REPLACE INTO Functions (filepath, name, address, type, calling_convention, parameter_names, parameter_types, return_type) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
|
||||||
insertOrReplaceImports = connection.prepareStatement(
|
insertOrReplaceImports = connection.prepareStatement(
|
||||||
"INSERT OR REPLACE INTO Imports (filepath, name, address, type, calling_convention) VALUES (?, ?, ?, ?, ?)");
|
"INSERT OR REPLACE INTO Imports (filepath, name, address, type, calling_convention, parameter_names, parameter_types, return_type) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
|
||||||
|
|
||||||
// Delete by filepath
|
// Delete by filepath
|
||||||
deleteByFilepathFunctions = connection.prepareStatement(
|
deleteByFilepathFunctions = connection.prepareStatement(
|
||||||
|
@ -234,9 +268,9 @@ public class FunctionDatabase implements AutoCloseable {
|
||||||
|
|
||||||
// Load all entries
|
// Load all entries
|
||||||
loadAllFunctions = connection.prepareStatement(
|
loadAllFunctions = connection.prepareStatement(
|
||||||
"SELECT filepath, name, address, type, calling_convention FROM Functions");
|
"SELECT filepath, name, address, type, calling_convention, parameter_names, parameter_types, return_type FROM Functions");
|
||||||
loadAllImports = connection.prepareStatement(
|
loadAllImports = connection.prepareStatement(
|
||||||
"SELECT filepath, name, address, type, calling_convention FROM Imports");
|
"SELECT filepath, name, address, type, calling_convention, parameter_names, parameter_types, return_type FROM Imports");
|
||||||
|
|
||||||
// Global statements
|
// Global statements
|
||||||
findByNameGlobals = connection.prepareStatement(
|
findByNameGlobals = connection.prepareStatement(
|
||||||
|
@ -314,6 +348,9 @@ public class FunctionDatabase implements AutoCloseable {
|
||||||
String addressStr = rs.getString("address");
|
String addressStr = rs.getString("address");
|
||||||
int typeValue = rs.getInt("type");
|
int typeValue = rs.getInt("type");
|
||||||
int callingConventionValue = rs.getInt("calling_convention");
|
int callingConventionValue = rs.getInt("calling_convention");
|
||||||
|
String parameterNames = rs.getString("parameter_names");
|
||||||
|
String parameterTypes = rs.getString("parameter_types");
|
||||||
|
String returnType = rs.getString("return_type");
|
||||||
|
|
||||||
if (addressStr != null && !addressStr.isEmpty()) {
|
if (addressStr != null && !addressStr.isEmpty()) {
|
||||||
Address address = script.getCurrentProgram().getAddressFactory().getAddress(addressStr);
|
Address address = script.getCurrentProgram().getAddressFactory().getAddress(addressStr);
|
||||||
|
@ -321,7 +358,8 @@ public class FunctionDatabase implements AutoCloseable {
|
||||||
Type type = Type.fromValue(typeValue);
|
Type type = Type.fromValue(typeValue);
|
||||||
CallingConvention callingConvention = CallingConvention.fromValue(callingConventionValue);
|
CallingConvention callingConvention = CallingConvention.fromValue(callingConventionValue);
|
||||||
|
|
||||||
return new FunctionEntry(address, name, file, type, callingConvention);
|
return new FunctionEntry(address, name, file, type, callingConvention,
|
||||||
|
parameterNames, parameterTypes, returnType);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -334,6 +372,9 @@ public class FunctionDatabase implements AutoCloseable {
|
||||||
address TEXT,
|
address TEXT,
|
||||||
type INTEGER DEFAULT 0,
|
type INTEGER DEFAULT 0,
|
||||||
calling_convention INTEGER DEFAULT 0,
|
calling_convention INTEGER DEFAULT 0,
|
||||||
|
parameter_names TEXT DEFAULT '',
|
||||||
|
parameter_types TEXT DEFAULT '',
|
||||||
|
return_type TEXT DEFAULT '',
|
||||||
PRIMARY KEY (name, filepath)
|
PRIMARY KEY (name, filepath)
|
||||||
)""";
|
)""";
|
||||||
|
|
||||||
|
@ -344,6 +385,9 @@ public class FunctionDatabase implements AutoCloseable {
|
||||||
address TEXT,
|
address TEXT,
|
||||||
type INTEGER DEFAULT 0,
|
type INTEGER DEFAULT 0,
|
||||||
calling_convention INTEGER DEFAULT 0,
|
calling_convention INTEGER DEFAULT 0,
|
||||||
|
parameter_names TEXT DEFAULT '',
|
||||||
|
parameter_types TEXT DEFAULT '',
|
||||||
|
return_type TEXT DEFAULT '',
|
||||||
PRIMARY KEY (name, filepath)
|
PRIMARY KEY (name, filepath)
|
||||||
)""";
|
)""";
|
||||||
|
|
||||||
|
@ -444,16 +488,45 @@ public class FunctionDatabase implements AutoCloseable {
|
||||||
insertOrReplaceFunctions.setString(3, entry.address.toString());
|
insertOrReplaceFunctions.setString(3, entry.address.toString());
|
||||||
insertOrReplaceFunctions.setInt(4, entry.type.getValue());
|
insertOrReplaceFunctions.setInt(4, entry.type.getValue());
|
||||||
insertOrReplaceFunctions.setInt(5, entry.callingConvention.getValue());
|
insertOrReplaceFunctions.setInt(5, entry.callingConvention.getValue());
|
||||||
|
insertOrReplaceFunctions.setString(6, entry.parameterNames);
|
||||||
|
insertOrReplaceFunctions.setString(7, entry.parameterTypes);
|
||||||
|
insertOrReplaceFunctions.setString(8, entry.returnType);
|
||||||
insertOrReplaceFunctions.executeUpdate();
|
insertOrReplaceFunctions.executeUpdate();
|
||||||
|
|
||||||
script.println("Added/updated entry: " + entry.name + " at " + entry.address + " in " + relativePath
|
script.println("Added/updated entry: " + entry.name + " at " + entry.address + " in " + relativePath
|
||||||
+ " (calling convention: " + entry.callingConvention + ")");
|
+ " (calling convention: " + entry.callingConvention + ", return type: " + entry.returnType + ")");
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
script.println("Error adding entry: " + e.getMessage());
|
script.println("Error adding entry: " + e.getMessage());
|
||||||
throw new Exception("Failed to add entry", e);
|
throw new Exception("Failed to add entry", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper method to add import entry
|
||||||
|
public void addImportEntry(FunctionEntry entry) throws Exception {
|
||||||
|
ensureConnection();
|
||||||
|
|
||||||
|
String relativePath = new File(RemanConfig.INSTANCE.outputDir).toPath()
|
||||||
|
.relativize(entry.file.toPath()).toString().replace('\\', '/');
|
||||||
|
|
||||||
|
try {
|
||||||
|
insertOrReplaceImports.setString(1, relativePath);
|
||||||
|
insertOrReplaceImports.setString(2, entry.name);
|
||||||
|
insertOrReplaceImports.setString(3, entry.address.toString());
|
||||||
|
insertOrReplaceImports.setInt(4, entry.type.getValue());
|
||||||
|
insertOrReplaceImports.setInt(5, entry.callingConvention.getValue());
|
||||||
|
insertOrReplaceImports.setString(6, entry.parameterNames);
|
||||||
|
insertOrReplaceImports.setString(7, entry.parameterTypes);
|
||||||
|
insertOrReplaceImports.setString(8, entry.returnType);
|
||||||
|
insertOrReplaceImports.executeUpdate();
|
||||||
|
|
||||||
|
script.println("Added/updated import entry: " + entry.name + " at " + entry.address + " in " + relativePath
|
||||||
|
+ " (calling convention: " + entry.callingConvention + ", return type: " + entry.returnType + ")");
|
||||||
|
} catch (SQLException e) {
|
||||||
|
script.println("Error adding import entry: " + e.getMessage());
|
||||||
|
throw new Exception("Failed to add import entry", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Helper method to remove entry by file path
|
// Helper method to remove entry by file path
|
||||||
public void removeEntryAt(String filePath) throws Exception {
|
public void removeEntryAt(String filePath) throws Exception {
|
||||||
ensureConnection();
|
ensureConnection();
|
||||||
|
@ -689,7 +762,7 @@ public class FunctionDatabase implements AutoCloseable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addGlobal(Address address, String name, String dataType) throws Exception {
|
public void addGlobal(Address address, String name) throws Exception {
|
||||||
ensureConnection();
|
ensureConnection();
|
||||||
|
|
||||||
String filepath = RemanConfig.GLOBAL_H_FILE; // Default filepath for globals
|
String filepath = RemanConfig.GLOBAL_H_FILE; // Default filepath for globals
|
||||||
|
@ -701,7 +774,7 @@ public class FunctionDatabase implements AutoCloseable {
|
||||||
insertOrReplaceGlobals.setString(3, addressStr);
|
insertOrReplaceGlobals.setString(3, addressStr);
|
||||||
insertOrReplaceGlobals.executeUpdate();
|
insertOrReplaceGlobals.executeUpdate();
|
||||||
|
|
||||||
script.println("Added/updated global: " + name + " at " + address + " with type " + dataType);
|
script.println("Added/updated global: " + name + " at " + address);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
script.println("Error adding global: " + e.getMessage());
|
script.println("Error adding global: " + e.getMessage());
|
||||||
throw new Exception("Failed to add global", e);
|
throw new Exception("Failed to add global", e);
|
||||||
|
|
|
@ -47,6 +47,44 @@ public class FunctionDumper {
|
||||||
initFunctionBlacklist();
|
initFunctionBlacklist();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper method to extract parameter names from Ghidra function
|
||||||
|
private String extractParameterNames(Function function) {
|
||||||
|
var parameters = function.getParameters();
|
||||||
|
if (parameters.length == 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder names = new StringBuilder();
|
||||||
|
for (int i = 0; i < parameters.length; i++) {
|
||||||
|
if (i > 0) names.append(";");
|
||||||
|
String paramName = parameters[i].getName();
|
||||||
|
names.append(paramName != null ? paramName : "param" + i);
|
||||||
|
}
|
||||||
|
return names.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper method to extract parameter types from Ghidra function
|
||||||
|
private String extractParameterTypes(Function function) {
|
||||||
|
var parameters = function.getParameters();
|
||||||
|
if (parameters.length == 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder types = new StringBuilder();
|
||||||
|
for (int i = 0; i < parameters.length; i++) {
|
||||||
|
if (i > 0) types.append(";");
|
||||||
|
String paramType = parameters[i].getDataType().toString();
|
||||||
|
types.append(paramType != null ? paramType : "void*");
|
||||||
|
}
|
||||||
|
return types.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper method to extract return type from Ghidra function
|
||||||
|
private String extractReturnType(Function function) {
|
||||||
|
var returnType = function.getReturnType();
|
||||||
|
return returnType != null ? returnType.toString() : "void";
|
||||||
|
}
|
||||||
|
|
||||||
boolean isValidFunction(Function function) {
|
boolean isValidFunction(Function function) {
|
||||||
if (functionAddrBlackList.contains(function.getEntryPoint()))
|
if (functionAddrBlackList.contains(function.getEntryPoint()))
|
||||||
return false;
|
return false;
|
||||||
|
@ -137,6 +175,13 @@ public class FunctionDumper {
|
||||||
.fromString(callingConventionName);
|
.fromString(callingConventionName);
|
||||||
script.println("Detected calling convention: " + callingConventionName + " -> " + callingConvention);
|
script.println("Detected calling convention: " + callingConventionName + " -> " + callingConvention);
|
||||||
|
|
||||||
|
// Extract parameter information and return type
|
||||||
|
String parameterNames = extractParameterNames(externalFunction);
|
||||||
|
String parameterTypes = extractParameterTypes(externalFunction);
|
||||||
|
String returnType = extractReturnType(externalFunction);
|
||||||
|
|
||||||
|
script.println("Parameters: " + parameterNames + " | Types: " + parameterTypes + " | Return: " + returnType);
|
||||||
|
|
||||||
try (PrintWriter writer2 = new PrintWriter(f4, "UTF-8")) {
|
try (PrintWriter writer2 = new PrintWriter(f4, "UTF-8")) {
|
||||||
writer2.println("// AUTO-GENERATED FILE!!!!");
|
writer2.println("// AUTO-GENERATED FILE!!!!");
|
||||||
writer2.println("// This function has yet to be decompiled using 'Dump Current Function' in ghidra");
|
writer2.println("// This function has yet to be decompiled using 'Dump Current Function' in ghidra");
|
||||||
|
@ -147,14 +192,13 @@ public class FunctionDumper {
|
||||||
writer2.println("#include <gh_global.h>");
|
writer2.println("#include <gh_global.h>");
|
||||||
writer2.println();
|
writer2.println();
|
||||||
writer2.println("// " + externalFunction.getEntryPoint());
|
writer2.println("// " + externalFunction.getEntryPoint());
|
||||||
writer2.println("// " + externalFunction.getName() + "(" + callingConvention + ")");
|
writer2.println("// " + externalFunction.getName());
|
||||||
|
|
||||||
// Parse function signature to extract calling convention, return type, and
|
// Parse function signature to extract calling convention, return type, and
|
||||||
// parameters
|
// parameters
|
||||||
String signature = externalFunction.getSignature().getPrototypeString(false);
|
String signature = externalFunction.getSignature().getPrototypeString(false);
|
||||||
signature = signature.replace(externalFunction.getName(), sanitizedExtFunctionName);
|
signature = signature.replace(externalFunction.getName(), sanitizedExtFunctionName);
|
||||||
script.println("Santized Signature: " + signature);
|
script.println("Santized Signature: " + signature);
|
||||||
String returnType = externalFunction.getReturnType().toString();
|
|
||||||
|
|
||||||
// Generate function stub using appropriate forwarding function
|
// Generate function stub using appropriate forwarding function
|
||||||
writer2.println("extern \"C\" " + signature + " {");
|
writer2.println("extern \"C\" " + signature + " {");
|
||||||
|
@ -196,9 +240,10 @@ public class FunctionDumper {
|
||||||
createdFile = true;
|
createdFile = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add stub function to database with calling convention
|
// Add stub function to database with calling convention and parameter information
|
||||||
FunctionDatabase.FunctionEntry newEntry = new FunctionDatabase.FunctionEntry(externalFunction.getEntryPoint(),
|
FunctionDatabase.FunctionEntry newEntry = new FunctionDatabase.FunctionEntry(externalFunction.getEntryPoint(),
|
||||||
externalFunction.getName(), f4, FunctionDatabase.Type.Stub, callingConvention);
|
externalFunction.getName(), f4, FunctionDatabase.Type.Stub, callingConvention,
|
||||||
|
parameterNames, parameterTypes, returnType);
|
||||||
functionDatabase.addEntryAt(newEntry);
|
functionDatabase.addEntryAt(newEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,6 +262,13 @@ public class FunctionDumper {
|
||||||
.fromString(callingConventionName);
|
.fromString(callingConventionName);
|
||||||
script.println("Detected calling convention: " + callingConventionName + " -> " + callingConvention);
|
script.println("Detected calling convention: " + callingConventionName + " -> " + callingConvention);
|
||||||
|
|
||||||
|
// Extract parameter information and return type
|
||||||
|
String parameterNames = extractParameterNames(function);
|
||||||
|
String parameterTypes = extractParameterTypes(function);
|
||||||
|
String returnType = extractReturnType(function);
|
||||||
|
|
||||||
|
script.println("Parameters: " + parameterNames + " | Types: " + parameterTypes + " | Return: " + returnType);
|
||||||
|
|
||||||
// Handle forceFixType flag
|
// Handle forceFixType flag
|
||||||
if (forceFixType) {
|
if (forceFixType) {
|
||||||
targetType = FunctionDatabase.Type.Fix;
|
targetType = FunctionDatabase.Type.Fix;
|
||||||
|
@ -284,9 +336,9 @@ public class FunctionDumper {
|
||||||
File f0 = targetFilename;
|
File f0 = targetFilename;
|
||||||
script.println("Processing " + function.getName() + " => " + f0.toString());
|
script.println("Processing " + function.getName() + " => " + f0.toString());
|
||||||
|
|
||||||
// Update database with calling convention
|
// Update database with calling convention and parameter information
|
||||||
FunctionDatabase.FunctionEntry newEntry = new FunctionDatabase.FunctionEntry(entrypoint, function.getName(), f0,
|
FunctionDatabase.FunctionEntry newEntry = new FunctionDatabase.FunctionEntry(entrypoint, function.getName(), f0,
|
||||||
targetType, callingConvention);
|
targetType, callingConvention, parameterNames, parameterTypes, returnType);
|
||||||
functionDatabase.addEntryAt(newEntry);
|
functionDatabase.addEntryAt(newEntry);
|
||||||
|
|
||||||
List<Function> externalFunctionCalls = new ArrayList<>();
|
List<Function> externalFunctionCalls = new ArrayList<>();
|
||||||
|
@ -429,13 +481,19 @@ public class FunctionDumper {
|
||||||
String proto = externalFunction.getSignature().getPrototypeString(false);
|
String proto = externalFunction.getSignature().getPrototypeString(false);
|
||||||
String name = externalFunction.getName();
|
String name = externalFunction.getName();
|
||||||
proto = proto.replace(name, Utils.sanitizeIdentifier(name));
|
proto = proto.replace(name, Utils.sanitizeIdentifier(name));
|
||||||
|
|
||||||
// Add calling convention information to the comment
|
// Add calling convention information to the comment
|
||||||
String callingConv = externalFunction.getCallingConventionName();
|
String callingConv = externalFunction.getCallingConventionName();
|
||||||
FunctionDatabase.CallingConvention conv = FunctionDatabase.CallingConvention.fromString(callingConv);
|
FunctionDatabase.CallingConvention conv = FunctionDatabase.CallingConvention.fromString(callingConv);
|
||||||
|
|
||||||
|
// Add parameter information to the comment
|
||||||
|
String extParamNames = extractParameterNames(externalFunction);
|
||||||
|
String extParamTypes = extractParameterTypes(externalFunction);
|
||||||
|
String extReturnType = extractReturnType(externalFunction);
|
||||||
|
|
||||||
headers.add("" + proto
|
headers.add("" + proto
|
||||||
+ "; // " + externalFunction.getEntryPoint() + " // "
|
+ "; // " + externalFunction.getEntryPoint() + " // "
|
||||||
+ name + " // " + conv);
|
+ name + " // " + conv + " // Params: " + extParamNames + " | Types: " + extParamTypes + " | Return: " + extReturnType);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String header : headers) {
|
for (String header : headers) {
|
||||||
|
@ -443,6 +501,8 @@ public class FunctionDumper {
|
||||||
}
|
}
|
||||||
writer2.println();
|
writer2.println();
|
||||||
writer2.print("// " + function.getEntryPoint());
|
writer2.print("// " + function.getEntryPoint());
|
||||||
|
writer2.println(" // " + function.getName() + "(" + callingConvention + ")");
|
||||||
|
writer2.println("// Parameters: " + parameterNames + " | Types: " + parameterTypes + " | Return: " + returnType);
|
||||||
String codeString = codeWriter.toString();
|
String codeString = codeWriter.toString();
|
||||||
for (HashMap.Entry<String, String> entry : replacementMap.entrySet()) {
|
for (HashMap.Entry<String, String> entry : replacementMap.entrySet()) {
|
||||||
String oldName = entry.getKey();
|
String oldName = entry.getKey();
|
||||||
|
|
|
@ -226,8 +226,7 @@ public class GlobalDumper {
|
||||||
|
|
||||||
// Add all current globals to database
|
// Add all current globals to database
|
||||||
for (GlobalRec global : globalAddrs.values()) {
|
for (GlobalRec global : globalAddrs.values()) {
|
||||||
String dataTypeName = global.type.getDisplayName();
|
functionDatabase.addGlobal(global.address, global.name);
|
||||||
functionDatabase.addGlobal(global.address, global.name, dataTypeName);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue