mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-02-18 00:20:10 +00:00
Merge remote-tracking branch
'origin/GP-4263_ghidra1_EditSignatureOverride--SQUASHED' (Closes #6000)
This commit is contained in:
commit
54e2910694
@ -905,6 +905,9 @@ public class DecompilerProvider extends NavigatableComponentProviderAdapter
|
||||
OverridePrototypeAction overrideSigAction = new OverridePrototypeAction();
|
||||
setGroupInfo(overrideSigAction, functionGroup, subGroupPosition++);
|
||||
|
||||
EditPrototypeOverrideAction editOverrideSigAction = new EditPrototypeOverrideAction();
|
||||
setGroupInfo(editOverrideSigAction, functionGroup, subGroupPosition++);
|
||||
|
||||
DeletePrototypeOverrideAction deleteSigAction = new DeletePrototypeOverrideAction();
|
||||
setGroupInfo(deleteSigAction, functionGroup, subGroupPosition++);
|
||||
|
||||
@ -1144,6 +1147,7 @@ public class DecompilerProvider extends NavigatableComponentProviderAdapter
|
||||
addLocalAction(editDataTypeAction);
|
||||
addLocalAction(specifyCProtoAction);
|
||||
addLocalAction(overrideSigAction);
|
||||
addLocalAction(editOverrideSigAction);
|
||||
addLocalAction(deleteSigAction);
|
||||
addLocalAction(renameFunctionAction);
|
||||
addLocalAction(renameLabelAction);
|
||||
|
@ -159,7 +159,7 @@ public abstract class AbstractDecompilerAction extends DockingAction {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the function corresponding to the specified decompiler context.
|
||||
* Get the function corresponding to the specified decompiler context token.
|
||||
*
|
||||
* @param context decompiler action context
|
||||
* @return the function associated with the current context token or null if none identified.
|
||||
|
@ -16,16 +16,13 @@
|
||||
package ghidra.app.plugin.core.decompile.actions;
|
||||
|
||||
import docking.action.MenuData;
|
||||
import ghidra.app.decompiler.ClangToken;
|
||||
import ghidra.app.plugin.core.decompile.DecompilerActionContext;
|
||||
import ghidra.app.util.HelpTopics;
|
||||
import ghidra.program.database.symbol.CodeSymbol;
|
||||
import ghidra.program.model.data.ProgramBasedDataTypeManager;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.pcode.HighFunction;
|
||||
import ghidra.program.model.pcode.PcodeOp;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.program.model.pcode.DataTypeSymbol;
|
||||
import ghidra.program.model.pcode.HighFunctionDBUtil;
|
||||
import ghidra.program.model.symbol.Symbol;
|
||||
import ghidra.util.HelpLocation;
|
||||
import ghidra.util.UndefinedFunction;
|
||||
|
||||
@ -37,38 +34,6 @@ public class DeletePrototypeOverrideAction extends AbstractDecompilerAction {
|
||||
setPopupMenuData(new MenuData(new String[] { "Remove Signature Override" }, "Decompile"));
|
||||
}
|
||||
|
||||
public static CodeSymbol getSymbol(Function func, ClangToken tokenAtCursor) {
|
||||
if (tokenAtCursor == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Namespace overspace = HighFunction.findOverrideSpace(func);
|
||||
if (overspace == null) {
|
||||
return null;
|
||||
}
|
||||
PcodeOp op = OverridePrototypeAction.getCallOp(func.getProgram(), tokenAtCursor);
|
||||
if (op == null) {
|
||||
return null;
|
||||
}
|
||||
SymbolTable symtab = func.getProgram().getSymbolTable();
|
||||
SymbolIterator iter = symtab.getSymbolsAsIterator(op.getSeqnum().getTarget());
|
||||
while (iter.hasNext()) {
|
||||
Symbol sym = iter.next();
|
||||
if (!sym.getName().startsWith("prt")) {
|
||||
continue;
|
||||
}
|
||||
if (!(sym instanceof CodeSymbol)) {
|
||||
continue;
|
||||
}
|
||||
if (!sym.getParentNamespace().equals(overspace)) {
|
||||
continue;
|
||||
}
|
||||
return (CodeSymbol) sym;
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isEnabledForDecompilerContext(DecompilerActionContext context) {
|
||||
|
||||
@ -77,22 +42,26 @@ public class DeletePrototypeOverrideAction extends AbstractDecompilerAction {
|
||||
return false;
|
||||
}
|
||||
|
||||
return getSymbol(function, context.getTokenAtCursor()) != null;
|
||||
return OverridePrototypeAction.getSymbol(function, context.getTokenAtCursor()) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void decompilerActionPerformed(DecompilerActionContext context) {
|
||||
Function func = context.getFunction();
|
||||
CodeSymbol sym = getSymbol(func, context.getTokenAtCursor());
|
||||
Symbol sym = OverridePrototypeAction.getSymbol(func, context.getTokenAtCursor());
|
||||
if (sym == null) {
|
||||
return;
|
||||
}
|
||||
Program program = func.getProgram();
|
||||
SymbolTable symtab = program.getSymbolTable();
|
||||
ProgramBasedDataTypeManager dtm = program.getDataTypeManager();
|
||||
int txId = program.startTransaction("Remove Override Signature");
|
||||
try {
|
||||
symtab.removeSymbolSpecial(sym);
|
||||
DataTypeSymbol dts = HighFunctionDBUtil.readOverride(sym);
|
||||
sym.delete();
|
||||
dts.cleanupUnusedOverride();
|
||||
}
|
||||
finally {
|
||||
program.endTransaction(txId, true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,108 @@
|
||||
/* ###
|
||||
* 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.decompile.actions;
|
||||
|
||||
import docking.action.MenuData;
|
||||
import ghidra.app.plugin.core.decompile.DecompilerActionContext;
|
||||
import ghidra.app.util.HelpTopics;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.data.FunctionDefinition;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.pcode.*;
|
||||
import ghidra.program.model.symbol.Symbol;
|
||||
import ghidra.util.*;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
public class EditPrototypeOverrideAction extends AbstractDecompilerAction {
|
||||
|
||||
public EditPrototypeOverrideAction() {
|
||||
super("Edit Signature Override");
|
||||
setHelpLocation(new HelpLocation(HelpTopics.DECOMPILER, "ActionEditOverride"));
|
||||
setPopupMenuData(new MenuData(new String[] { "Edit Signature Override" }, "Decompile"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isEnabledForDecompilerContext(DecompilerActionContext context) {
|
||||
Function function = context.getFunction();
|
||||
if (function == null || function instanceof UndefinedFunction) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Symbol sym = OverridePrototypeAction.getSymbol(function, context.getTokenAtCursor());
|
||||
if (sym == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return HighFunctionDBUtil.readOverride(sym) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void decompilerActionPerformed(DecompilerActionContext context) {
|
||||
Function function = context.getFunction();
|
||||
Symbol sym = OverridePrototypeAction.getSymbol(function, context.getTokenAtCursor());
|
||||
if (sym == null) {
|
||||
return;
|
||||
}
|
||||
DataTypeSymbol dts = HighFunctionDBUtil.readOverride(sym);
|
||||
if (dts == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Function func = context.getFunction();
|
||||
Program program = func.getProgram();
|
||||
PcodeOp op = OverridePrototypeAction.getCallOp(program, context.getTokenAtCursor());
|
||||
Function calledFunc = null;
|
||||
if (op != null) {
|
||||
calledFunc = OverridePrototypeAction.getCalledFunction(program, op);
|
||||
}
|
||||
|
||||
FunctionDefinition updatedFuncDef = null;
|
||||
try {
|
||||
// Copy is used for edit so we can adjust name
|
||||
FunctionDefinition funcDef =
|
||||
(FunctionDefinition) dts.getDataType().copy(program.getDataTypeManager());
|
||||
funcDef.setName(calledFunc != null ? calledFunc.getName() : "func");
|
||||
updatedFuncDef = OverridePrototypeAction.editSignature(context, calledFunc,
|
||||
funcDef.getPrototypeString());
|
||||
if (updatedFuncDef == null) {
|
||||
return;
|
||||
}
|
||||
// TODO: should use comparison to see if funcDef was changed.
|
||||
// Should be able to use equals method after fixing category and name, however
|
||||
// it does not check param names.
|
||||
}
|
||||
catch (InvalidNameException | DuplicateNameException e) {
|
||||
Msg.error(this, "Unexpected error", e);
|
||||
}
|
||||
|
||||
int transaction = program.startTransaction("Override Signature");
|
||||
try {
|
||||
Address addr = sym.getAddress();
|
||||
sym.delete(); // delete old marker symbol
|
||||
HighFunctionDBUtil.writeOverride(func, addr, updatedFuncDef);
|
||||
dts.cleanupUnusedOverride();
|
||||
}
|
||||
catch (Exception e) {
|
||||
Msg.showError(getClass(), context.getDecompilerPanel(), "Override Signature Failed",
|
||||
"Error overriding signature: " + e);
|
||||
}
|
||||
finally {
|
||||
program.endTransaction(transaction, true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -28,8 +28,7 @@ import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.pcode.*;
|
||||
import ghidra.program.model.symbol.Reference;
|
||||
import ghidra.program.model.symbol.SourceType;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.util.*;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.InvalidInputException;
|
||||
@ -48,7 +47,7 @@ public class OverridePrototypeAction extends AbstractDecompilerAction {
|
||||
* @param tokenAtCursor is the point in the window the user has selected
|
||||
* @return the PcodeOp or null
|
||||
*/
|
||||
public static PcodeOp getCallOp(Program program, ClangToken tokenAtCursor) {
|
||||
static PcodeOp getCallOp(Program program, ClangToken tokenAtCursor) {
|
||||
if (tokenAtCursor == null) {
|
||||
return null;
|
||||
}
|
||||
@ -76,6 +75,38 @@ public class OverridePrototypeAction extends AbstractDecompilerAction {
|
||||
return null;
|
||||
}
|
||||
|
||||
static Symbol getSymbol(Function func, ClangToken tokenAtCursor) {
|
||||
if (tokenAtCursor == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Namespace overspace = HighFunction.findOverrideSpace(func);
|
||||
if (overspace == null) {
|
||||
return null;
|
||||
}
|
||||
PcodeOp op = getCallOp(func.getProgram(), tokenAtCursor);
|
||||
if (op == null) {
|
||||
return null;
|
||||
}
|
||||
SymbolTable symtab = func.getProgram().getSymbolTable();
|
||||
SymbolIterator iter = symtab.getSymbolsAsIterator(op.getSeqnum().getTarget());
|
||||
while (iter.hasNext()) {
|
||||
Symbol sym = iter.next();
|
||||
if (sym.getSymbolType() != SymbolType.LABEL) {
|
||||
continue;
|
||||
}
|
||||
if (!sym.getParentNamespace().equals(overspace)) {
|
||||
continue;
|
||||
}
|
||||
if (!sym.getName().startsWith("prt")) {
|
||||
continue;
|
||||
}
|
||||
return sym;
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
private static PcodeOp getOpForAddress(Program program, Address addr, ClangToken token) {
|
||||
|
||||
ClangFunction cfunc = token.getClangFunction();
|
||||
@ -114,7 +145,7 @@ public class OverridePrototypeAction extends AbstractDecompilerAction {
|
||||
return opCode == PcodeOp.CALL || opCode == PcodeOp.CALLIND;
|
||||
}
|
||||
|
||||
private Function getCalledFunction(Program program, PcodeOp op) {
|
||||
static Function getCalledFunction(Program program, PcodeOp op) {
|
||||
if (op.getOpcode() != PcodeOp.CALL) {
|
||||
return null;
|
||||
}
|
||||
@ -226,8 +257,7 @@ public class OverridePrototypeAction extends AbstractDecompilerAction {
|
||||
}
|
||||
|
||||
// don't enable if override already in place
|
||||
return DeletePrototypeOverrideAction.getSymbol(context.getFunction(),
|
||||
context.getTokenAtCursor()) == null;
|
||||
return getSymbol(context.getFunction(), context.getTokenAtCursor()) == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -235,10 +265,10 @@ public class OverridePrototypeAction extends AbstractDecompilerAction {
|
||||
Function func = context.getFunction();
|
||||
Program program = func.getProgram();
|
||||
PcodeOp op = getCallOp(program, context.getTokenAtCursor());
|
||||
Function calledfunc = getCalledFunction(program, op);
|
||||
Function calledFunc = getCalledFunction(program, op);
|
||||
boolean varargs = false;
|
||||
if (calledfunc != null) {
|
||||
varargs = calledfunc.hasVarArgs();
|
||||
if (calledFunc != null) {
|
||||
varargs = calledFunc.hasVarArgs();
|
||||
}
|
||||
if ((op.getOpcode() == PcodeOp.CALL) && !varargs) {
|
||||
if (OptionDialog.showOptionDialog(context.getDecompilerPanel(),
|
||||
@ -250,26 +280,21 @@ public class OverridePrototypeAction extends AbstractDecompilerAction {
|
||||
return;
|
||||
}
|
||||
}
|
||||
Address addr = op.getSeqnum().getTarget();
|
||||
String name = "func"; // Default if we don't have a real name
|
||||
String conv = program.getCompilerSpec().getDefaultCallingConvention().getName();
|
||||
if (calledfunc != null) {
|
||||
name = calledfunc.getName();
|
||||
conv = calledfunc.getCallingConventionName();
|
||||
}
|
||||
|
||||
String signature = generateSignature(op, name, calledfunc);
|
||||
PluginTool tool = context.getTool();
|
||||
ProtoOverrideDialog dialog =
|
||||
new ProtoOverrideDialog(tool, calledfunc != null ? calledfunc : func, signature, conv);
|
||||
tool.showDialog(dialog);
|
||||
FunctionDefinition fdef = dialog.getFunctionDefinition();
|
||||
String name = "func"; // Default if we don't have a real name
|
||||
if (calledFunc != null) {
|
||||
name = calledFunc.getName();
|
||||
}
|
||||
String signature = generateSignature(op, name, calledFunc);
|
||||
|
||||
FunctionDefinition fdef = editSignature(context, calledFunc, signature);
|
||||
if (fdef == null) {
|
||||
return;
|
||||
}
|
||||
int transaction = program.startTransaction("Override Signature");
|
||||
boolean commit = false;
|
||||
try {
|
||||
Address addr = op.getSeqnum().getTarget();
|
||||
HighFunctionDBUtil.writeOverride(func, addr, fdef);
|
||||
commit = true;
|
||||
}
|
||||
@ -282,13 +307,30 @@ public class OverridePrototypeAction extends AbstractDecompilerAction {
|
||||
}
|
||||
}
|
||||
|
||||
static FunctionDefinition editSignature(DecompilerActionContext context, Function calledFunc,
|
||||
String signature) {
|
||||
Function func = context.getFunction();
|
||||
Program program = func.getProgram();
|
||||
PluginTool tool = context.getTool();
|
||||
|
||||
String conv = program.getCompilerSpec().getDefaultCallingConvention().getName();
|
||||
if (calledFunc != null) {
|
||||
conv = calledFunc.getCallingConventionName();
|
||||
}
|
||||
|
||||
ProtoOverrideDialog dialog =
|
||||
new ProtoOverrideDialog(tool, calledFunc != null ? calledFunc : func, signature, conv);
|
||||
tool.showDialog(dialog);
|
||||
return dialog.getFunctionDefinition();
|
||||
}
|
||||
|
||||
/**
|
||||
* <code>ProtoOverrideDialog</code> provides the ability to edit the
|
||||
* function signature associated with a specific function definition override
|
||||
* at a sub-function callsite.
|
||||
* Use of this editor requires the presence of the tool-based datatype manager service.
|
||||
*/
|
||||
private class ProtoOverrideDialog extends EditFunctionSignatureDialog {
|
||||
private static class ProtoOverrideDialog extends EditFunctionSignatureDialog {
|
||||
private FunctionDefinition functionDefinition;
|
||||
private final String initialSignature;
|
||||
private final String initialConvention;
|
||||
|
@ -139,34 +139,23 @@ public class SpecifyCPrototypeAction extends AbstractDecompilerAction {
|
||||
return fsig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get function affected by specified action context
|
||||
*
|
||||
* @param function is the current decompiled function which will be the default if no other
|
||||
* function identified by context token.
|
||||
* @param context decompiler action context
|
||||
* @return the function associated with the current context token. If no function corresponds
|
||||
* to context token the decompiled function will be returned.
|
||||
*/
|
||||
private Function getFunction(Function function, DecompilerActionContext context) {
|
||||
// try to look up the function that is at the current cursor location
|
||||
// If there isn't one, just use the function we are in.
|
||||
Function tokenFunction = getFunction(context);
|
||||
return tokenFunction != null ? tokenFunction : function;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isEnabledForDecompilerContext(DecompilerActionContext context) {
|
||||
Function function = context.getFunction();
|
||||
if (function instanceof UndefinedFunction) {
|
||||
Function decompiledFunction = context.getFunction();
|
||||
Function func = getFunction(context);
|
||||
if (func == null || (func instanceof UndefinedFunction)) {
|
||||
return false;
|
||||
}
|
||||
return getFunction(function, context) != null;
|
||||
if (func != decompiledFunction && OverridePrototypeAction.getSymbol(decompiledFunction,
|
||||
context.getTokenAtCursor()) != null) {
|
||||
return false; // disable action for sub-function call w/ override
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void decompilerActionPerformed(DecompilerActionContext context) {
|
||||
Function function = getFunction(context.getFunction(), context);
|
||||
Function function = getFunction(context);
|
||||
PluginTool tool = context.getTool();
|
||||
DataTypeManagerService service = tool.getService(DataTypeManagerService.class);
|
||||
|
||||
|
@ -21,10 +21,12 @@ import generic.hash.SimpleCRC32;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.listing.FunctionSignature;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.util.InvalidNameException;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
import ghidra.util.exception.InvalidInputException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
public class DataTypeSymbol {
|
||||
private Symbol sym; // Traditional symbol object
|
||||
@ -105,14 +107,12 @@ public class DataTypeSymbol {
|
||||
public static void deleteSymbols(String nmroot, Address addr, SymbolTable symtab,
|
||||
Namespace space) throws InvalidInputException {
|
||||
ArrayList<Symbol> dellist = new ArrayList<Symbol>();
|
||||
SymbolIterator iter = symtab.getSymbols(space);
|
||||
while (iter.hasNext()) {
|
||||
Symbol sym = iter.next();
|
||||
for (Symbol sym : symtab.getSymbols(addr)) {
|
||||
if (!sym.getName().startsWith(nmroot))
|
||||
continue;
|
||||
if (sym.getSymbolType() != SymbolType.LABEL)
|
||||
continue;
|
||||
if (!addr.equals(sym.getAddress()))
|
||||
if (space.equals(sym.getParentNamespace()))
|
||||
continue;
|
||||
if (sym.hasReferences())
|
||||
throw new InvalidInputException("DataTypeSymbol has a reference");
|
||||
@ -123,6 +123,34 @@ public class DataTypeSymbol {
|
||||
}
|
||||
}
|
||||
|
||||
public void cleanupUnusedOverride() {
|
||||
if (sym == null) {
|
||||
throw new RuntimeException("not instantiated with readSymbol method");
|
||||
}
|
||||
|
||||
// NOTE: Although the symbol may have just been deleted its name will still be
|
||||
// be accesible within its retained DB record.
|
||||
String overrideName = sym.getName(); // override marker symbol
|
||||
|
||||
Program program = sym.getProgram();
|
||||
SymbolTable symbolTable = program.getSymbolTable();
|
||||
String prefix = nmroot + "_";
|
||||
String hashSuffix = "_" + extractHash(overrideName);
|
||||
for (Symbol s : symbolTable.scanSymbolsByName(prefix)) {
|
||||
String n = s.getName();
|
||||
if (!n.startsWith(prefix)) {
|
||||
break; // stop scan
|
||||
}
|
||||
if (s.getSymbolType() == SymbolType.LABEL && n.endsWith(hashSuffix) &&
|
||||
HighFunction.isOverrideNamespace(s.getParentNamespace())) {
|
||||
return; // do nothing if any symbol found
|
||||
}
|
||||
}
|
||||
|
||||
// remove unused override signature
|
||||
program.getDataTypeManager().remove(getDataType(), TaskMonitor.DUMMY);
|
||||
}
|
||||
|
||||
public static DataTypeSymbol readSymbol(String cat, Symbol s) {
|
||||
if (s.getSymbolType() != SymbolType.LABEL) {
|
||||
throw new IllegalArgumentException("Expected CODE symbol");
|
||||
|
@ -40,6 +40,8 @@ import ghidra.util.exception.InvalidInputException;
|
||||
*/
|
||||
public class HighFunction extends PcodeSyntaxTree {
|
||||
public final static String DECOMPILER_TAG_MAP = "decompiler_tags";
|
||||
public final static String OVERRIDE_NAMESPACE_NAME = "override";
|
||||
|
||||
private Function func; // The traditional function object
|
||||
private Language language;
|
||||
private CompilerSpec compilerSpec;
|
||||
@ -485,14 +487,22 @@ public class HighFunction extends PcodeSyntaxTree {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isOverrideNamespace(Namespace namespace) {
|
||||
if (!OVERRIDE_NAMESPACE_NAME.equals(namespace.getName())) {
|
||||
return false;
|
||||
}
|
||||
Namespace parent = namespace.getParentNamespace();
|
||||
return (parent instanceof Function);
|
||||
}
|
||||
|
||||
public static Namespace findOverrideSpace(Function func) {
|
||||
SymbolTable symtab = func.getProgram().getSymbolTable();
|
||||
return findNamespace(symtab, func, "override");
|
||||
return findNamespace(symtab, func, OVERRIDE_NAMESPACE_NAME);
|
||||
}
|
||||
|
||||
public static Namespace findCreateOverrideSpace(Function func) {
|
||||
SymbolTable symtab = func.getProgram().getSymbolTable();
|
||||
return findCreateNamespace(symtab, func, "override");
|
||||
return findCreateNamespace(symtab, func, OVERRIDE_NAMESPACE_NAME);
|
||||
}
|
||||
|
||||
public static Namespace findNamespace(SymbolTable symtab, Namespace parent, String name) {
|
||||
|
Loading…
Reference in New Issue
Block a user