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..b5d5f5cc96 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,66 @@ 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
+ * @throws IllegalArgumentException if parent Namespace does not correspond to
+ * currerntProgram
+ */
+ 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
+ * @throws IllegalArgumentException if parent Namespace does not correspond to
+ * currerntProgram
+ * @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.
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/symbol/SymbolManager.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/symbol/SymbolManager.java
index 8657972ff9..ee31fac974 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/symbol/SymbolManager.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/symbol/SymbolManager.java
@@ -2579,6 +2579,11 @@ public class SymbolManager implements SymbolTable, ManagerDB {
checkValidNamespaceArgument(namespace);
+ if (namespace.isGlobal() || namespace.isLibrary()) {
+ throw new IllegalArgumentException(
+ "May not convert namespace to class: " + namespace.getName(true));
+ }
+
Symbol namespaceSymbol = namespace.getSymbol();
String name = namespaceSymbol.getName();
SourceType originalSource = namespaceSymbol.getSource();
@@ -2729,7 +2734,7 @@ public class SymbolManager implements SymbolTable, ManagerDB {
* it will be returned.
* @param addr the address for the new symbol (memory or external)
* @param name the name of the new symbol
- * @param namespace the namespace for the new symbol
+ * @param namespace the namespace for the new symbol (null may be specified for global namespace)
* @param source the SourceType of the new symbol
* @param stringData special use depending on the symbol type and whether or not it is external
* @return the new symbol
@@ -2789,7 +2794,7 @@ public class SymbolManager implements SymbolTable, ManagerDB {
*
* @param addr the address for the new symbol
* @param name the name of the new symbol
- * @param namespace the namespace for the new symbol
+ * @param namespace the namespace for the new symbol (null may be specified for global namespace)
* @param source the SourceType of the new symbol
* @param stringData special use depending on the symbol type and whether or not it is external.
* @return the new symbol
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/symbol/SymbolTable.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/symbol/SymbolTable.java
index 43096be32b..3c97f23937 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/symbol/SymbolTable.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/symbol/SymbolTable.java
@@ -86,7 +86,8 @@ public interface SymbolTable {
* @throws InvalidInputException thrown if names contains white space, is zero length, or is
* null for non-default source. Also thrown if invalid parentNamespace is specified.
* @throws IllegalArgumentException if you try to set the source to DEFAULT for a symbol type
- * that doesn't allow it, or an improper addr is specified
+ * that doesn't allow it, specify an improper addr, or specify a namespace which does not
+ * correspond to this symbol table's program.
*/
public Symbol createLabel(Address addr, String name, Namespace namespace, SourceType source)
throws InvalidInputException;
@@ -137,6 +138,8 @@ public interface SymbolTable {
* @param namespace the namespace of the symbol to retrieve. May be null which indicates global
* namespace.
* @return the symbol which matches the specified criteria or null if not found
+ * @throws IllegalArgumentException amespace which does not correspond to this
+ * symbol table's program.
* @see #getGlobalSymbol(String, Address) for a convenience method if the namespace is the
* global namespace.
*/
@@ -182,6 +185,8 @@ public interface SymbolTable {
* @param name the name of the symbols to search for.
* @param namespace the namespace to search. If null, then the global namespace is assumed.
* @return a list of all the label or function symbols with the given name in the given namespace.
+ * @throws IllegalArgumentException amespace which does not correspond to this
+ * symbol table's program.
*/
public List getLabelOrFunctionSymbols(String name, Namespace namespace);
@@ -190,6 +195,8 @@ public interface SymbolTable {
* @param name the name of the namespace symbol to retrieve.
* @param namespace the namespace containing the symbol to retrieve.
* @return a generic namespace symbol with the given name in the given namespace.
+ * @throws IllegalArgumentException amespace which does not correspond to this
+ * symbol table's program.
*/
public Symbol getNamespaceSymbol(String name, Namespace namespace);
@@ -205,6 +212,8 @@ public interface SymbolTable {
* @param name the name of the class.
* @param namespace the namespace to search for the class.
* @return the class symbol with the given name in the given namespace.
+ * @throws IllegalArgumentException amespace which does not correspond to this
+ * symbol table's program.
*/
public Symbol getClassSymbol(String name, Namespace namespace);
@@ -213,6 +222,8 @@ public interface SymbolTable {
* @param name the name of the parameter.
* @param namespace the namespace (function) to search for the class.
* @return the parameter symbol with the given name in the given namespace.
+ * @throws IllegalArgumentException amespace which does not correspond to this
+ * symbol table's program.
*/
public Symbol getParameterSymbol(String name, Namespace namespace);
@@ -221,6 +232,8 @@ public interface SymbolTable {
* @param name the name of the local variable.
* @param namespace the namespace (function) to search for the class.
* @return the local variable symbol with the given name in the given namespace.
+ * @throws IllegalArgumentException amespace which does not correspond to this
+ * symbol table's program.
*/
public Symbol getLocalVariableSymbol(String name, Namespace namespace);
@@ -233,6 +246,8 @@ public interface SymbolTable {
* @param name the name of the symbols to retrieve.
* @param namespace the namespace to search for symbols.
* @return all symbols which satisfy specified criteria
+ * @throws IllegalArgumentException amespace which does not correspond to this
+ * symbol table's program.
*/
public List getSymbols(String name, Namespace namespace);
@@ -252,6 +267,8 @@ public interface SymbolTable {
* @param name the name of the namespace to be retrieved.
* @param namespace the parent namespace of the namespace to be retrieved.
* @return the namespace with the given name in the given parent namespace.
+ * @throws IllegalArgumentException amespace which does not correspond to this
+ * symbol table's program.
*/
public Namespace getNamespace(String name, Namespace namespace);
@@ -333,6 +350,8 @@ public interface SymbolTable {
*
* @param namespace the namespace to search for symbols.
* @return symbol iterator
+ * @throws IllegalArgumentException amespace which does not correspond to this
+ * symbol table's program.
*/
public SymbolIterator getSymbols(Namespace namespace);
@@ -527,14 +546,15 @@ public interface SymbolTable {
/**
* Create a class namespace in the given parent namespace.
- * @param parent parent namespace
+ * @param parent parent namespace (may be null for global namespace)
* @param name name of the namespace
* @param source the source of this class namespace's symbol
* @return new class namespace
* @throws DuplicateNameException thrown if another non function or label symbol exists with
* the given name
* @throws InvalidInputException throw if the name has invalid characters or is null
- * @throws IllegalArgumentException if you try to set the source to 'Symbol.DEFAULT'.
+ * @throws IllegalArgumentException if you try to set the source to 'Symbol.DEFAULT'
+ * or specify a parent Namespace which does not correspond to this symbol table's program.
*/
public GhidraClass createClass(Namespace parent, String name, SourceType source)
throws DuplicateNameException, InvalidInputException;
@@ -565,14 +585,15 @@ public interface SymbolTable {
/**
* Creates a new namespace.
- * @param parent the parent namespace for the new namespace
+ * @param parent the parent namespace for the new namespace (may be null for global namespace)
* @param name the name of the new namespace
* @param source the source of this namespace's symbol
* @return the new Namespace object.
* @throws DuplicateNameException thrown if another non function or label symbol
* exists with the given name
* @throws InvalidInputException if the name is invalid.
- * @throws IllegalArgumentException if you try to set the source to 'Symbol.DEFAULT'.
+ * @throws IllegalArgumentException if you try to set the source to 'Symbol.DEFAULT'
+ * or specify a parent Namespace which does not correspond to this symbol table's program.
*/
public Namespace createNameSpace(Namespace parent, String name, SourceType source)
throws DuplicateNameException, InvalidInputException;
@@ -585,6 +606,8 @@ public interface SymbolTable {
* @throws IllegalArgumentException if the given parent namespace is from a different program
* than that of this symbol table
* @throws ConcurrentModificationException if the given parent namespace has been deleted
+ * @throws IllegalArgumentException namespace does not correspond to this symbol table's program
+ * or namespace not allowed (e.g., global or library namespace).
*/
public GhidraClass convertNamespaceToClass(Namespace namespace);