GP-653 ProgramCompilerSpec revisions

This commit is contained in:
ghidra1 2021-05-04 12:20:41 -04:00
parent a5d4ca3cab
commit 03ad680756
3 changed files with 56 additions and 20 deletions

View File

@ -53,6 +53,7 @@ public class SpecExtensionTest extends AbstractDecompilerTest {
try {
SpecExtension specExtension = new SpecExtension(program);
specExtension.addReplaceCompilerSpecExtension(myfixup, TaskMonitor.DUMMY);
fail("expected exception");
}
catch (SleighException | XmlParseException | SAXException | LockException ex) {
errMessage = ex.getMessage();
@ -80,13 +81,16 @@ public class SpecExtensionTest extends AbstractDecompilerTest {
myfixup = "<callfixup name=\"mynewthing\"> </badendtag>";
errMessage = null;
String subError = null;
setErrorsExpected(true);
try {
specExtension.testExtensionDocument(myfixup);
fail("expected exception");
}
catch (Exception e) {
errMessage = e.getMessage();
subError = e.getCause().getMessage();
}
setErrorsExpected(true);
assertTrue(errMessage.contains("Invalid compiler specification"));
assertTrue(subError.contains("must be terminated by the matching"));
@ -95,6 +99,7 @@ public class SpecExtensionTest extends AbstractDecompilerTest {
errMessage = null;
try {
specExtension.testExtensionDocument(myfixup);
fail("expected exception");
}
catch (Exception e) {
errMessage = e.getMessage();
@ -111,6 +116,7 @@ public class SpecExtensionTest extends AbstractDecompilerTest {
SpecExtension specExtension = new SpecExtension(program);
try {
specExtension.addReplaceCompilerSpecExtension(myfixup, TaskMonitor.DUMMY);
fail("expected exception");
}
catch (SleighException | XmlParseException | SAXException | LockException ex) {
errMessage = ex.getMessage();
@ -139,7 +145,7 @@ public class SpecExtensionTest extends AbstractDecompilerTest {
specExtension.addReplaceCompilerSpecExtension(defaultString, TaskMonitor.DUMMY);
}
catch (LockException | SleighException | SAXException | XmlParseException ex) {
throw new AssertionError("Unexpected exception: " + ex.getMessage());
fail("Unexpected exception: " + ex.getMessage());
}
program.endTransaction(id1, true);
PrototypeModel myproto = cspec.getCallingConvention("myproto");
@ -180,7 +186,7 @@ public class SpecExtensionTest extends AbstractDecompilerTest {
specExtension.removeCompilerSpecExtension("prototype_myproto", TaskMonitor.DUMMY);
}
catch (LockException | CancelledException ex) {
throw new AssertionError("Unexpected exception: " + ex.getMessage());
fail("Unexpected exception: " + ex.getMessage());
}
program.endTransaction(id2, true);
myproto = cspec.getCallingConvention("myproto");
@ -203,7 +209,7 @@ public class SpecExtensionTest extends AbstractDecompilerTest {
specExtension.addReplaceCompilerSpecExtension(myfixup, TaskMonitor.DUMMY);
}
catch (LockException | SleighException | SAXException | XmlParseException ex) {
throw new AssertionError("Unexpected exception: " + ex.getMessage());
fail("Unexpected exception: " + ex.getMessage());
}
program.endTransaction(id1, true);
PcodeInjectLibrary library = program.getCompilerSpec().getPcodeInjectLibrary();
@ -244,7 +250,7 @@ public class SpecExtensionTest extends AbstractDecompilerTest {
specExtension.removeCompilerSpecExtension("callfixup_mynewthing", TaskMonitor.DUMMY);
}
catch (LockException | CancelledException ex) {
throw new AssertionError("Unexpected exception: " + ex.getMessage());
fail("Unexpected exception: " + ex.getMessage());
}
program.endTransaction(id2, true);
programPayloads = library.getProgramPayloads();

View File

@ -66,13 +66,9 @@ public class ProgramCompilerSpec extends BasicCompilerSpec {
* @param program is the Program
* @param langSpec is the CompilerSpec from Language to base this on
*/
public ProgramCompilerSpec(Program program, CompilerSpec langSpec) {
super((BasicCompilerSpec) langSpec);
private ProgramCompilerSpec(Program program, BasicCompilerSpec langSpec) {
super(langSpec);
this.program = program;
if (langSpec instanceof ProgramCompilerSpec) {
throw new IllegalArgumentException(
"Cannot instantiate ProgramCompilerSpec from another ProgramCompilerSpec");
}
}
/**
@ -371,4 +367,23 @@ public class ProgramCompilerSpec extends BasicCompilerSpec {
}
return true;
}
/**
* Transition specified compiler specification langSpec into a program-specific
* one which supports extensions. If the specified langSpec is not a {@link BasicCompilerSpec}
* instance, the langSpec argument will be returned unmodified.
* @param program program to which langSpec applies
* @param langSpec initial compiler specification which does not support extensions.
* @return compiler specification to be used with program
*/
static CompilerSpec getProgramCompilerSpec(Program program, CompilerSpec langSpec) {
if (langSpec instanceof ProgramCompilerSpec) {
throw new IllegalArgumentException(
"Cannot instantiate ProgramCompilerSpec from another ProgramCompilerSpec");
}
if (langSpec instanceof BasicCompilerSpec) {
return new ProgramCompilerSpec(program, (BasicCompilerSpec) langSpec);
}
return langSpec;
}
}

View File

@ -190,7 +190,7 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM
private ProgramUserDataDB programUserData;
private Table table;
private Language language;
private ProgramCompilerSpec compilerSpec;
private CompilerSpec compilerSpec;
private LanguageID languageID;
private CompilerSpecID compilerSpecID;
@ -219,8 +219,13 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM
throws IOException {
super(new DBHandle(), name, 500, 1000, consumer);
if (!(compilerSpec instanceof BasicCompilerSpec)) {
throw new IllegalArgumentException(
"unsupported compilerSpec: " + compilerSpec.getClass().getName());
}
this.language = language;
this.compilerSpec = new ProgramCompilerSpec(this, compilerSpec);
this.compilerSpec = ProgramCompilerSpec.getProgramCompilerSpec(this, compilerSpec);
languageID = language.getLanguageID();
compilerSpecID = compilerSpec.getCompilerSpecID();
@ -245,7 +250,7 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM
programUserData = new ProgramUserDataDB(this);
endTransaction(id, true);
clearUndo(false);
this.compilerSpec.registerProgramOptions();
registerCompilerSpecOptions();
getCodeManager().activateContextLocking();
success = true;
}
@ -355,8 +360,8 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM
endTransaction(id, true);
clearUndo(false);
SpecExtension.checkFormatVersion(this);
compilerSpec.installExtensions();
compilerSpec.registerProgramOptions();
installExtensions();
registerCompilerSpecOptions();
getCodeManager().activateContextLocking();
success = true;
}
@ -397,7 +402,7 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM
}
compilerSpecID = compilerSpec.getCompilerSpecID();
}
compilerSpec = new ProgramCompilerSpec(this, langSpec);
compilerSpec = ProgramCompilerSpec.getProgramCompilerSpec(this, langSpec);
}
/**
@ -1837,7 +1842,7 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM
for (int i = 0; i < NUM_MANAGERS; i++) {
managers[i].invalidateCache(all);
}
compilerSpec.installExtensions(); // Reload any extensions
installExtensions(); // Reload any extensions
}
catch (IOException e) {
dbError(e);
@ -2053,7 +2058,7 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM
}
if (newCompilerSpecID != null) {
compilerSpec = new ProgramCompilerSpec(this,
compilerSpec = ProgramCompilerSpec.getProgramCompilerSpec(this,
language.getCompilerSpecByID(newCompilerSpecID));
}
compilerSpecID = compilerSpec.getCompilerSpecID();
@ -2112,7 +2117,6 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM
setChanged(true);
clearCache(true);
invalidate();
}
catch (Throwable t) {
throw new IllegalStateException(
@ -2465,12 +2469,23 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM
* See {@link SpecExtension}.
*/
protected void installExtensions() {
if (!(compilerSpec instanceof ProgramCompilerSpec)) {
return;
}
lock.acquire();
try {
compilerSpec.installExtensions();
((ProgramCompilerSpec) compilerSpec).installExtensions();
}
finally {
lock.release();
}
}
private void registerCompilerSpecOptions() {
if (!(compilerSpec instanceof ProgramCompilerSpec)) {
throw new AssertException(
"unsupported compilerSpec: " + compilerSpec.getClass().getName());
}
((ProgramCompilerSpec) compilerSpec).registerProgramOptions();
}
}