mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-22 04:05:39 +00:00
Merge remote-tracking branch 'origin/patch'
This commit is contained in:
commit
3ec2dfb201
@ -22,6 +22,21 @@
|
||||
|
||||
<BODY>
|
||||
|
||||
<H1 align="center">Ghidra 11.1.1 Change History (June 2024)</H1>
|
||||
<blockquote><p><u><B>Bugs</B></u></p>
|
||||
<ul>
|
||||
<li><I>Debugger</I>. Fixes an error in <span class="gcode">dbgeng</span> launcher. (GP-4674)</li>
|
||||
<li><I>Debugger:GDB</I>. Fixed issue with using QEMU launchers in Trace RMI (<span class="gcode">ClassCastException</span> from <span class="gcode">String</span> to <span class="gcode">PathIsFile</span>) (GP-4690, Issue #6634)</li>
|
||||
<li><I>Decompiler</I>. Fixed a bug in the Decompiler that could cause it to drop a control-flow edge from a switch's case statement that looped back to the switch. (GP-4582, Issue #6282)</li>
|
||||
<li><I>Decompiler</I>. Fixed bug causing "Undefined Pullsub" exceptions. (GP-4672, Issue #6614)</li>
|
||||
<li><I>Decompiler</I>. Corrected Decompiler process issue which can occur when analysis is cancelled. Issue would incorrectly popup error indicating <em>"Decompiler executable may not be compatible with your system..."</em>. (GP-4689)</li>
|
||||
<li><I>GUI</I>. Fixed mouse button 4/5 processing failure that caused the left-click to stop working. (GP-4681, Issue #6624)</li>
|
||||
<li><I>Processors</I>. Added support for the Z80 processor undocumented registers. (GP-2881, Issue #4485)</li>
|
||||
<li><I>Processors</I>. Fixed 6805 branch conditional instruction semantics. (GP-4585, Issue #6482)</li>
|
||||
<li><I>Project</I>. Fixed a severe regression bug introduced with Ghidra 11.1 which could prevent a user from completing a project file add-to-version-control, checkin or merge when they currently have the file open in a tool. The corresponding open project file would remain in a bad state following the operation. (GP-4692)</li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
|
||||
<H1 align="center">Ghidra 11.1 Change History (June 2024)</H1>
|
||||
<blockquote><p><u><B>New Features</B></u></p>
|
||||
<ul>
|
||||
|
@ -78,8 +78,8 @@ public class BufferMgr {
|
||||
*/
|
||||
private BufferNode cacheHead;
|
||||
private BufferNode cacheTail;
|
||||
private int cacheSize = 0;
|
||||
private int buffersOnHand = 0;
|
||||
private int cacheSize;
|
||||
private int buffersOnHand;
|
||||
private int lockCount = 0;
|
||||
|
||||
/**
|
||||
@ -235,6 +235,10 @@ public class BufferMgr {
|
||||
|
||||
private void initializeCache() throws IOException {
|
||||
|
||||
if (lockCount != 0) {
|
||||
throw new IOException("Unable to re-initialize buffer cache while in-use");
|
||||
}
|
||||
|
||||
if (cacheFile != null) {
|
||||
cacheFile.delete();
|
||||
}
|
||||
@ -244,6 +248,9 @@ public class BufferMgr {
|
||||
cacheTail = new BufferNode(TAIL, -1);
|
||||
cacheHead.nextCached = cacheTail;
|
||||
cacheTail.prevCached = cacheHead;
|
||||
|
||||
cacheSize = 0;
|
||||
buffersOnHand = 0;
|
||||
|
||||
// Create disk cache file
|
||||
cacheFile = new LocalBufferFile(bufferSize, CACHE_FILE_PREFIX, CACHE_FILE_EXT);
|
||||
@ -257,6 +264,8 @@ public class BufferMgr {
|
||||
cacheFile.setParameter(name, sourceFile.getParameter(name));
|
||||
}
|
||||
}
|
||||
|
||||
resetCacheStatistics();
|
||||
|
||||
if (alwaysPreCache) {
|
||||
startPreCacheIfNeeded();
|
||||
@ -2058,7 +2067,7 @@ public class BufferMgr {
|
||||
public void resetCacheStatistics() {
|
||||
cacheHits = 0;
|
||||
cacheMisses = 0;
|
||||
lowWaterMark = cacheSize;
|
||||
lowWaterMark = cacheSize - 1;
|
||||
}
|
||||
|
||||
public String getStatusInfo() {
|
||||
|
@ -1149,7 +1149,7 @@ public class GhidraFileData {
|
||||
|
||||
if (keepCheckedOut) {
|
||||
|
||||
// Maintain exclusive chekout if private repository or file is open for update
|
||||
// Maintain exclusive checkout if private repository or file is open for update
|
||||
boolean exclusive = !versionedFileSystem.isShared() || (inUseDomainObj != null);
|
||||
|
||||
ProjectLocator projectLocator = parent.getProjectLocator();
|
||||
@ -1169,6 +1169,11 @@ public class GhidraFileData {
|
||||
projectLocator.isTransient()));
|
||||
folderItem.setCheckout(checkout.getCheckoutId(), exclusive,
|
||||
checkout.getCheckoutVersion(), folderItem.getCurrentVersion());
|
||||
|
||||
if (inUseDomainObj != null) {
|
||||
// Reset source file and change-sets for open database
|
||||
getContentHandler().resetDBSourceFile(folderItem, inUseDomainObj);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// NOTE: file open read-only may prevent removal and result in hijack
|
||||
@ -1180,10 +1185,7 @@ public class GhidraFileData {
|
||||
// Ignore - should result in Hijacked file
|
||||
}
|
||||
}
|
||||
|
||||
if (inUseDomainObj != null) {
|
||||
getContentHandler().resetDBSourceFile(folderItem, inUseDomainObj);
|
||||
}
|
||||
|
||||
} // end of synchronized block
|
||||
|
||||
if (inUseDomainObj != null) {
|
||||
@ -1535,15 +1537,16 @@ public class GhidraFileData {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (inUseDomainObj != null) {
|
||||
// Reset source file and change-sets for open database
|
||||
contentHandler.resetDBSourceFile(folderItem, inUseDomainObj);
|
||||
}
|
||||
}
|
||||
else {
|
||||
undoCheckout(false, true);
|
||||
}
|
||||
|
||||
if (inUseDomainObj != null) {
|
||||
contentHandler.resetDBSourceFile(folderItem, inUseDomainObj);
|
||||
}
|
||||
|
||||
} // end of synchronized block
|
||||
|
||||
if (inUseDomainObj != null) {
|
||||
@ -1915,6 +1918,8 @@ public class GhidraFileData {
|
||||
try {
|
||||
inUseDomainObj = getAndLockInUseDomainObjectForMergeUpdate("merge");
|
||||
|
||||
ContentHandler<?> contentHandler = getContentHandler();
|
||||
|
||||
if (!modifiedSinceCheckout()) {
|
||||
// Quick merge
|
||||
folderItem.updateCheckout(versionedFolderItem, true, monitor);
|
||||
@ -1925,8 +1930,6 @@ public class GhidraFileData {
|
||||
throw new IOException("Merge failed, merge is not supported in headless mode");
|
||||
}
|
||||
|
||||
ContentHandler<?> contentHandler = getContentHandler();
|
||||
|
||||
// Test versioned file for VersionException
|
||||
int mergeVer = versionedFolderItem.getCurrentVersion();
|
||||
if (!okToUpgrade) {
|
||||
@ -1995,14 +1998,13 @@ public class GhidraFileData {
|
||||
versionedFolderItem.updateCheckoutVersion(checkoutId, mergeVer,
|
||||
ClientUtil.getUserName());
|
||||
tmpItem = null;
|
||||
Msg.info(this, "Merge completed for " + name);
|
||||
|
||||
if (inUseDomainObj != null) {
|
||||
contentHandler.resetDBSourceFile(folderItem, inUseDomainObj);
|
||||
}
|
||||
}
|
||||
|
||||
Msg.info(this, "Updated checkout completed for " + name);
|
||||
|
||||
if (inUseDomainObj != null) {
|
||||
// Reset source file and change-sets for open database
|
||||
contentHandler.resetDBSourceFile(folderItem, inUseDomainObj);
|
||||
inUseDomainObj.invalidate();
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,8 @@ import generic.theme.GIcon;
|
||||
import ghidra.framework.main.projectdata.actions.VersionControlAction;
|
||||
import ghidra.framework.model.DomainFile;
|
||||
import ghidra.framework.model.DomainFolder;
|
||||
import ghidra.program.database.ProgramDB;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.model.listing.CodeUnit;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.symbol.SourceType;
|
||||
@ -219,7 +221,7 @@ public class VersionControlAction2Test extends AbstractVersionControlActionTest
|
||||
waitForSwing();
|
||||
waitForTasks();
|
||||
|
||||
Program program = (Program) ((DomainFileNode) node).getDomainFile()
|
||||
ProgramDB program = (ProgramDB) ((DomainFileNode) node).getDomainFile()
|
||||
.getDomainObject(this,
|
||||
true, false, TaskMonitor.DUMMY);
|
||||
int transactionID = program.startTransaction("test");
|
||||
@ -253,6 +255,58 @@ public class VersionControlAction2Test extends AbstractVersionControlActionTest
|
||||
assertTrue(!df.isCheckedOut());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckInWhileOpen() throws Exception {
|
||||
GTreeNode node = getNode(PROGRAM_A);
|
||||
addToVersionControl(node, false);
|
||||
|
||||
selectNode(node);
|
||||
DockingActionIf action = getAction("CheckOut");
|
||||
runSwing(() -> action.actionPerformed(getDomainFileActionContext(node)), false);
|
||||
waitForSwing();
|
||||
waitForTasks();
|
||||
|
||||
ProgramDB program = (ProgramDB) ((DomainFileNode) node).getDomainFile()
|
||||
.getDomainObject(this,
|
||||
true, false, TaskMonitor.DUMMY);
|
||||
int transactionID = program.startTransaction("test");
|
||||
try {
|
||||
// Ensure that buffer memory cache has been completely consumed
|
||||
// Max BufferMgr cache size is 256*16KByte=4MByte
|
||||
AddressSpace space = program.getAddressFactory().getDefaultAddressSpace();
|
||||
program.getMemory().createInitializedBlock("BigBlock", space.getAddress(0x80000000L),
|
||||
4*1024*1024, (byte)0xff, TaskMonitor.DUMMY, false);
|
||||
}
|
||||
finally {
|
||||
program.endTransaction(transactionID, true);
|
||||
program.save(null, TaskMonitor.DUMMY);
|
||||
}
|
||||
|
||||
try {
|
||||
DockingActionIf checkInAction = getAction("CheckIn");
|
||||
runSwing(() -> checkInAction.actionPerformed(getDomainFileActionContext(node)), false);
|
||||
waitForSwing();
|
||||
VersionControlDialog dialog = waitForDialogComponent(VersionControlDialog.class);
|
||||
assertNotNull(dialog);
|
||||
JTextArea textArea = findComponent(dialog, JTextArea.class);
|
||||
assertNotNull(textArea);
|
||||
JCheckBox cb = findComponent(dialog, JCheckBox.class);
|
||||
assertNotNull(cb);
|
||||
runSwing(() -> {
|
||||
textArea.setText("This is a test");
|
||||
cb.setSelected(false);
|
||||
});
|
||||
pressButtonByText(dialog, "OK");
|
||||
waitForTasks();
|
||||
DomainFile df = ((DomainFileNode) node).getDomainFile();
|
||||
assertTrue(df.isCheckedOut());
|
||||
}
|
||||
finally {
|
||||
program.release(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteVersionCheckedOut() throws Exception {
|
||||
|
Loading…
Reference in New Issue
Block a user