From 8c6f3c05b0a44d517f3da0eb844554ce974960c4 Mon Sep 17 00:00:00 2001 From: Andrew Strelsky Date: Fri, 15 Jul 2022 07:10:13 -0400 Subject: [PATCH] Add createNamespace and createClass to FlatProgramAPI --- .../program/flatapi/FlatProgramAPI.java | 60 ++++++++++++++++++- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/Ghidra/Features/Base/src/main/java/ghidra/program/flatapi/FlatProgramAPI.java b/Ghidra/Features/Base/src/main/java/ghidra/program/flatapi/FlatProgramAPI.java index 33933b397e..a0d6143119 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/program/flatapi/FlatProgramAPI.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/program/flatapi/FlatProgramAPI.java @@ -246,7 +246,7 @@ public class FlatProgramAPI { /** * Clears the code units (instructions or data) in the specified range. * @param start the start address - * @param end the end address + * @param end the end address (INCLUSIVE) * @throws CancelledException if cancelled */ public final void clearListing(Address start, Address end) throws CancelledException { @@ -1506,7 +1506,7 @@ public class FlatProgramAPI { /** * Returns the non-function namespace with the given name contained inside the * specified parent namespace. - * Pass null for namespace to indicate the global namespace. + * Pass null for parent to indicate the global namespace. * @param parent the parent namespace, or null for global namespace * @param namespaceName the requested namespace's name * @return the namespace with the given name or null if not found @@ -1514,6 +1514,62 @@ public class FlatProgramAPI { public final Namespace getNamespace(Namespace parent, String namespaceName) { return currentProgram.getSymbolTable().getNamespace(namespaceName, parent); } + +/** + * Creates a new {@link Namespace} with the given name contained inside the + * specified parent namespace. + * Pass null for parent to indicate the global namespace. + * If a {@link Namespace} or {@link GhidraClass} with the given name already exists, the + * existing one will be returned. + * @param parent the parent namespace, or null for global namespace + * @param namespaceName the requested namespace's name + * @return the namespace with the given name + * @throws DuplicateNameException if a {@link Library} symbol exists with the given name + * @throws InvalidInputException if the name is invalid + */ + public final Namespace createNamespace(Namespace parent, String namespaceName) + throws DuplicateNameException, InvalidInputException { + SymbolTable symbolTable = currentProgram.getSymbolTable(); + Namespace ns = symbolTable.getNamespace(namespaceName, parent); + if (ns != null) { + SymbolType type = ns.getSymbol().getSymbolType(); + if (type == SymbolType.NAMESPACE || type == SymbolType.CLASS) { + return ns; + } + } + return symbolTable.createNameSpace(parent, namespaceName, SourceType.USER_DEFINED); + } + + /** + * Creates a new {@link GhidraClass} with the given name contained inside the + * specified parent namespace. + * Pass null for parent to indicate the global namespace. + * If a GhidraClass with the given name already exists, the existing one will be returned. + * @param parent the parent namespace, or null for global namespace + * @param className the requested classes name + * @return the GhidraClass with the given name + * @throws InvalidInputException if the name is invalid + * @throws DuplicateNameException thrown if a {@link Library} or {@link Namespace} + * symbol already exists with the given name. + * Use {@link SymbolTable#convertNamespaceToClass(Namespace)} for converting an + * existing Namespace to a GhidraClass. + * @throws IllegalArgumentException if the given parent namespace is not from + * the {@link #currentProgram}. + * @throws ConcurrentModificationException if the given parent has been deleted + * @see SymbolTable#convertNamespaceToClass(Namespace) + */ + public final GhidraClass createClass(Namespace parent, String className) + throws DuplicateNameException, InvalidInputException { + SymbolTable symbolTable = currentProgram.getSymbolTable(); + Namespace ns = symbolTable.getNamespace(className, parent); + if (ns != null) { + SymbolType type = ns.getSymbol().getSymbolType(); + if (type == SymbolType.CLASS) { + return (GhidraClass) ns; + } + } + return symbolTable.createClass(parent, className, SourceType.USER_DEFINED); + } /** * Creates a fragment in the root folder of the default program tree.