GP-3727 corrected issue with setting data type archive architecture at

time of creation
This commit is contained in:
ghidra1 2023-08-09 10:04:46 -04:00
parent 0952f5839f
commit e7541755a1
7 changed files with 88 additions and 19 deletions

View File

@ -19,8 +19,8 @@ import java.io.IOException;
import java.util.LinkedList;
import java.util.concurrent.locks.ReadWriteLock;
import db.Transaction;
import db.DBHandle;
import db.Transaction;
import ghidra.framework.model.DomainFile;
import ghidra.program.database.data.ProgramBasedDataTypeManagerDB;
import ghidra.program.model.address.Address;
@ -70,6 +70,10 @@ public class DBTraceDataTypeManager extends ProgramBasedDataTypeManagerDB
return trace.getBaseAddressFactory();
}
}, null, false, monitor);
if (openMode == DBOpenMode.CREATE) {
saveDataOrganization();
}
}
@Override

View File

@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -25,6 +24,10 @@ public interface ErrorHandler {
/**
* Notification that an IO exception occurred.
*
* @param e {@link IOException} which was cause of error
* @throws RuntimeException optional exception which may be thrown when
* responding to error condition.
*/
public void dbError(IOException e);
public void dbError(IOException e) throws RuntimeException;
}

View File

@ -0,0 +1,33 @@
/* ###
* 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.framework.model;
import java.io.IOException;
/**
* {@link RuntimeIOException} provide a wrapped {@link IOException} wrapped
* within a {@link RuntimeException}.
*/
public class RuntimeIOException extends RuntimeException {
/**
* Construct {@link RuntimeIOException}
* @param e {@link IOException} instance
*/
public RuntimeIOException(IOException e) {
super(e);
}
}

View File

@ -1773,6 +1773,10 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM
}
listing.setProgram(this);
if (openMode == DBConstants.CREATE) {
getDataTypeManager().saveDataOrganization();
}
monitor.checkCancelled();
if (openMode == UPGRADE) {

View File

@ -31,6 +31,7 @@ import generic.jar.ResourceFile;
import ghidra.app.plugin.core.datamgr.archive.BuiltInSourceArchive;
import ghidra.docking.settings.*;
import ghidra.framework.Application;
import ghidra.framework.model.RuntimeIOException;
import ghidra.framework.store.db.PackedDBHandle;
import ghidra.framework.store.db.PackedDatabase;
import ghidra.graph.*;
@ -123,10 +124,11 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
private TreeSet<String> knownCallingConventions;
private TreeSet<String> definedCallingConventions;
protected DBHandle dbHandle;
private int mode; // open mode (see DBConstants)
protected final boolean readOnlyMode;
protected final DBHandle dbHandle;
protected final String tablePrefix;
protected final ErrorHandler errHandler;
private DataTypeConflictHandler currentHandler;
private CategoryDB root;
@ -209,8 +211,9 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
* support the save or saveAs operation. No Language is associated with instance.
*
* @param dataOrganization applicable data organization
* @throws RuntimeIOException if database error occurs during creation
*/
protected DataTypeManagerDB(DataOrganization dataOrganization) {
protected DataTypeManagerDB(DataOrganization dataOrganization) throws RuntimeIOException {
this.lock = new Lock("DataTypeManagerDB");
this.errHandler = new DbErrorHandler();
this.dataOrganization = dataOrganization;
@ -218,8 +221,8 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
try {
dbHandle = new DBHandle();
readOnlyMode = false;
int id = startTransaction("");
try {
init(DBConstants.CREATE, TaskMonitor.DUMMY);
}
@ -231,7 +234,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
}
}
catch (IOException e) {
errHandler.dbError(e);
throw new RuntimeIOException(e);
}
}
@ -254,6 +257,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
this.errHandler = new DbErrorHandler();
this.lock = new Lock("DataTypeManagerDB");
this.tablePrefix = "";
this.readOnlyMode = (openMode == DBConstants.READ_ONLY);
File file = packedDBfile.getFile(false);
if (file == null && openMode != DBConstants.READ_ONLY) {
@ -359,6 +363,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
throws CancelledException, IOException, VersionException {
this.tablePrefix = tablePrefix != null ? tablePrefix : "";
this.dbHandle = handle;
this.readOnlyMode = (openMode == DBConstants.READ_ONLY);
this.addrMap = addrMap;
this.errHandler = errHandler;
this.lock = lock;
@ -367,7 +372,6 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
private void init(int openMode, TaskMonitor monitor)
throws CancelledException, IOException, VersionException {
this.mode = openMode;
updateID();
initializeAdapters(openMode, monitor);
if (checkForSourceArchiveUpdatesNeeded(openMode, monitor)) {
@ -795,6 +799,8 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
* @param store if true database update will occur and datatypes will be updated if
* any change to the data organization is detected (a stored copy may be used to
* detect this condition). This should never be passed as true if opened read-only.
* This should be false during create mode where only the state is affected without
* changing the Database or existing datatypes.
* @param monitor task monitor
* @throws IOException if IO error occurs
* @throws CancelledException if processing cancelled - data types may not properly reflect
@ -812,10 +818,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
? programArchitecture.getCompilerSpec().getDataOrganization()
: DataOrganizationImpl.getDefaultOrganization();
if (mode == DBConstants.CREATE) {
saveDataOrganization();
}
else if (store) {
if (store) {
try {
compilerSpecChanged(monitor);
updateLastChangeTime();
@ -839,8 +842,8 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
* updated compiler specification
*/
protected void compilerSpecChanged(TaskMonitor monitor) throws IOException, CancelledException {
if (mode == DBConstants.READ_ONLY) {
if (readOnlyMode) {
throw new ReadOnlyException();
}
@ -861,6 +864,11 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
return !Objects.equals(readDataOrganization(), getDataOrganization());
}
/**
* Save the current data organization to facilitate future change detection and
* upgrades.
* @throws IOException if failure occured while saving data organization.
*/
protected void saveDataOrganization() throws IOException {
DataOrganizationImpl.save(getDataOrganization(), getDataMap(true), "dataOrg.");
}
@ -4620,14 +4628,15 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
private class DbErrorHandler implements ErrorHandler {
@Override
public void dbError(IOException e) {
public void dbError(IOException e) throws RuntimeIOException {
String message = e.getMessage();
if (e instanceof ClosedException) {
message = "Data type archive is closed: " + getName();
Msg.showError(this, null, "IO ERROR", message, e);
}
Msg.showError(this, null, "IO ERROR", message, e);
throw new RuntimeIOException(e);
}
}

View File

@ -64,6 +64,17 @@ public class ProgramDataTypeManager extends ProgramBasedDataTypeManagerDB
upgrade = (openMode == DBConstants.UPGRADE);
}
/**
* Save the current data organization to facilitate future change detection and
* upgrades. This method must be invoked by {@link ProgramDB} during the final
* stage of program creation (i.e., openMode == CREATE).
* @throws IOException if failure occured while saving data organization.
*/
@Override
public void saveDataOrganization() throws IOException {
super.saveDataOrganization();
}
@Override
protected void dataSettingChanged(Address dataAddr) {
program.setChanged(ChangeManager.DOCR_DATA_TYPE_SETTING_CHANGED, dataAddr,
@ -81,6 +92,7 @@ public class ProgramDataTypeManager extends ProgramBasedDataTypeManagerDB
try {
setProgramArchitecture(p, p.getSymbolTable().getVariableStorageManager(), false,
TaskMonitor.DUMMY);
// NOTE: Due to late manner in which program architecture is established, any
// response to a data organization change must be handled during a language
// upgrade and setLanguage

View File

@ -26,6 +26,7 @@ import com.google.common.collect.ImmutableList;
import db.*;
import db.util.ErrorHandler;
import generic.jar.ResourceFile;
import ghidra.framework.model.RuntimeIOException;
import ghidra.framework.store.LockException;
import ghidra.program.database.DBStringMapAdapter;
import ghidra.program.database.ProgramAddressFactory;
@ -138,8 +139,9 @@ public class StandAloneDataTypeManager extends DataTypeManagerDB implements Clos
* Constructor for new temporary data-type manager using the default DataOrganization.
* Note that this manager does not support the save or saveAs operation.
* @param rootName Name of the root category.
* @throws RuntimeIOException if database error occurs during creation
*/
public StandAloneDataTypeManager(String rootName) {
public StandAloneDataTypeManager(String rootName) throws RuntimeIOException {
super(DataOrganizationImpl.getDefaultOrganization());
this.name = rootName;
}
@ -149,8 +151,10 @@ public class StandAloneDataTypeManager extends DataTypeManagerDB implements Clos
* Note that this manager does not support the save or saveAs operation.
* @param rootName Name of the root category.
* @param dataOrganzation applicable data organization
* @throws RuntimeIOException if database error occurs during creation
*/
public StandAloneDataTypeManager(String rootName, DataOrganization dataOrganzation) {
public StandAloneDataTypeManager(String rootName, DataOrganization dataOrganzation)
throws RuntimeIOException {
super(dataOrganzation);
this.name = rootName;
}