diff --git a/Ghidra/Configurations/Public_Release/src/global/docs/ChangeHistory.html b/Ghidra/Configurations/Public_Release/src/global/docs/ChangeHistory.html index 78d2a36c85..102d4b1aab 100644 --- a/Ghidra/Configurations/Public_Release/src/global/docs/ChangeHistory.html +++ b/Ghidra/Configurations/Public_Release/src/global/docs/ChangeHistory.html @@ -22,6 +22,21 @@
++Bugs
++
+- Debugger. Fixes an error in dbgeng launcher. (GP-4674)
+- Debugger:GDB. Fixed issue with using QEMU launchers in Trace RMI (ClassCastException from String to PathIsFile) (GP-4690, Issue #6634)
+- Decompiler. 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)
+- Decompiler. Fixed bug causing "Undefined Pullsub" exceptions. (GP-4672, Issue #6614)
+- Decompiler. Corrected Decompiler process issue which can occur when analysis is cancelled. Issue would incorrectly popup error indicating "Decompiler executable may not be compatible with your system...". (GP-4689)
+- GUI. Fixed mouse button 4/5 processing failure that caused the left-click to stop working. (GP-4681, Issue #6624)
+- Processors. Added support for the Z80 processor undocumented registers. (GP-2881, Issue #4485)
+- Processors. Fixed 6805 branch conditional instruction semantics. (GP-4585, Issue #6482)
+- Project. 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)
+
New Features
diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/data/support/local-dbgeng.py b/Ghidra/Debug/Debugger-agent-dbgeng/data/support/local-dbgeng.py index 6d95b403c1..c20c802679 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/data/support/local-dbgeng.py +++ b/Ghidra/Debug/Debugger-agent-dbgeng/data/support/local-dbgeng.py @@ -39,7 +39,8 @@ else: def main(): # Delay these imports until sys.path is patched from ghidradbg import commands as cmd - from ghidradbg.hooks import on_stop + from pybag.dbgeng import core as DbgEng + from ghidradbg.hooks import on_state_changed from ghidradbg.util import dbg # So that the user can re-enter by typing repl() @@ -62,7 +63,7 @@ def main(): cmd.ghidra_trace_start(os.getenv('OPT_TARGET_IMG')) cmd.ghidra_trace_sync_enable() - on_stop() + on_state_changed(DbgEng.DEBUG_CES_EXECUTION_STATUS, DbgEng.DEBUG_STATUS_BREAK) cmd.repl() diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/AbstractTraceRmiLaunchOffer.java b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/AbstractTraceRmiLaunchOffer.java index 67e6f265ae..97b6fab7ac 100644 --- a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/AbstractTraceRmiLaunchOffer.java +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/AbstractTraceRmiLaunchOffer.java @@ -42,8 +42,7 @@ import ghidra.debug.api.modules.*; import ghidra.debug.api.modules.ModuleMapProposal.ModuleMapEntry; import ghidra.debug.api.tracermi.*; import ghidra.framework.options.SaveState; -import ghidra.framework.plugintool.AutoConfigState.ConfigStateField; -import ghidra.framework.plugintool.AutoConfigState.PathIsFile; +import ghidra.framework.plugintool.AutoConfigState.*; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; @@ -299,8 +298,18 @@ public abstract class AbstractTraceRmiLaunchOffer implements TraceRmiLaunchOffer List
names = program.getLanguage().getLanguageDescription().getExternalNames(tool); if (names != null && !names.isEmpty()) { - var paramStr = (ParameterDescription ) param; - paramStr.set(map, names.get(0)); + if (param.type == String.class) { + var paramStr = (ParameterDescription ) param; + paramStr.set(map, names.get(0)); + } + else if (param.type == PathIsFile.class) { + var paramPIF = (ParameterDescription ) param; + paramPIF.set(map, PathIsFile.fromString(names.get(0))); + } + else if (param.type == PathIsDir.class) { + var paramPID = (ParameterDescription ) param; + paramPID.set(map, PathIsDir.fromString(names.get(0))); + } } } } diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/framework/plugintool/AutoConfigState.java b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/framework/plugintool/AutoConfigState.java index 49a56d95a9..424d5d09c6 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/framework/plugintool/AutoConfigState.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/framework/plugintool/AutoConfigState.java @@ -305,6 +305,10 @@ public interface AutoConfigState { } record PathIsDir(Path path) { + public static PathIsDir fromString(String string) { + return new PathIsDir(Paths.get(string)); + } + @Override public String toString() { return path.toString(); @@ -328,6 +332,10 @@ public interface AutoConfigState { } record PathIsFile(Path path) { + public static PathIsFile fromString(String string) { + return new PathIsFile(Paths.get(string)); + } + @Override public String toString() { return path.toString(); diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/util/bean/opteditor/OptionsDialogTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/util/bean/opteditor/OptionsDialogTest.java index d73843a786..153e181534 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/util/bean/opteditor/OptionsDialogTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/util/bean/opteditor/OptionsDialogTest.java @@ -434,7 +434,7 @@ public class OptionsDialogTest extends AbstractGhidraHeadedIntegrationTest { MouseBinding defaultMouseBinding = getMouseBindingFromTable(actionName, actionOwner); assertNull(defaultMouseBinding); - int button = 1; + int button = 4; int modifiers = 0; MouseBinding newMouseBinding = setMouseBinding(actionName, actionOwner, modifiers, button); @@ -462,7 +462,7 @@ public class OptionsDialogTest extends AbstractGhidraHeadedIntegrationTest { MouseBinding defaultMouseBinding = getMouseBindingFromTable(actionName, actionOwner); assertNull(defaultMouseBinding); - int button = 1; + int button = 4; int modifiers = 0; MouseBinding newMouseBinding = setMouseBinding(actionName, actionOwner, modifiers, button); @@ -500,7 +500,7 @@ public class OptionsDialogTest extends AbstractGhidraHeadedIntegrationTest { int modifiers = InputEvent.CTRL_DOWN_MASK | InputEvent.ALT_DOWN_MASK; KeyStroke newKeyStroke = setKeyBinding(actionName, actionOwner, modifiers, keyCode, 'Q'); - int button = 1; + int button = 4; modifiers = 0; MouseBinding newMouseBinding = setMouseBinding(actionName, actionOwner, modifiers, button); @@ -533,7 +533,7 @@ public class OptionsDialogTest extends AbstractGhidraHeadedIntegrationTest { MouseBinding defaultMouseBinding = getMouseBindingFromTable(actionName, actionOwner); assertNull(defaultMouseBinding); - int button = 1; + int button = 4; int modifiers = 0; MouseBinding newMouseBinding = setMouseBinding(actionName, actionOwner, modifiers, button); diff --git a/Ghidra/Features/Decompiler/certification.manifest b/Ghidra/Features/Decompiler/certification.manifest index b470cd13d8..caf8a82594 100644 --- a/Ghidra/Features/Decompiler/certification.manifest +++ b/Ghidra/Features/Decompiler/certification.manifest @@ -18,6 +18,7 @@ src/decompile/datatests/condmulti.xml||GHIDRA||||END| src/decompile/datatests/convert.xml||GHIDRA||||END| src/decompile/datatests/deadvolatile.xml||GHIDRA||||END| src/decompile/datatests/deindirect.xml||GHIDRA||||END| +src/decompile/datatests/deindirect2.xml||GHIDRA||||END| src/decompile/datatests/displayformat.xml||GHIDRA||||END| src/decompile/datatests/divopt.xml||GHIDRA||||END| src/decompile/datatests/dupptr.xml||GHIDRA||||END| diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/block.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/block.cc index 2a6114188c..7d783e7884 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/block.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/block.cc @@ -1674,13 +1674,20 @@ BlockMultiGoto *BlockGraph::newBlockMultiGoto(FlowBlock *bl,int4 outedge) } else { ret = new BlockMultiGoto(bl); + int4 origSizeOut = bl->sizeOut(); vector nodes; nodes.push_back(bl); identifyInternal(ret,nodes); addBlock(ret); ret->addEdge(targetbl); - if (targetbl != bl) // If the target is itself, edge is already removed by identifyInternal - removeEdge(ret,targetbl); + if (targetbl != bl) { + if (ret->sizeOut() != origSizeOut) { // If there are less out edges after identifyInternal + // it must have collapsed a self edge (switch out edges are already deduped) + ret->forceOutputNum(ret->sizeOut()+1); // preserve the self edge (it is not the goto edge) + } + removeEdge(ret,targetbl); // Remove the edge to the goto target + } + // else -- the goto edge is a self edge and will get removed by identifyInternal if (isdefaultedge) ret->setDefaultGoto(); } diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/blockaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/blockaction.cc index 799fb002c8..71d7d5c41a 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/blockaction.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/blockaction.cc @@ -84,12 +84,14 @@ void LoopBody::extendToContainer(const LoopBody &container,vector & } } -/// This updates the \b head and \b tail nodes to FlowBlock in the current collapsed graph. -/// This returns the first \b tail and passes back the head. -/// \param top is where \b head is passed back +/// This updates the \b head node to the FlowBlock in the current collapsed graph. +/// The \b tail nodes are also updated until one is found that has not collapsed into \b head. +/// This first updated \b tail is returned. The loop may still exist as a \b head node with an +/// out edge back into itself, in which case \b head is returned as the active \b tail. +/// If the loop has been completely collapsed, null is returned. /// \param graph is the containing control-flow structure -/// \return the current loop \b head -FlowBlock *LoopBody::getCurrentBounds(FlowBlock **top,FlowBlock *graph) +/// \return the current loop \b tail or null +FlowBlock *LoopBody::update(FlowBlock *graph) { while(head->getParent() != graph) @@ -101,10 +103,13 @@ FlowBlock *LoopBody::getCurrentBounds(FlowBlock **top,FlowBlock *graph) bottom = bottom->getParent(); tails[i] = bottom; if (bottom != head) { // If the loop hasn't been fully collapsed yet - *top = head; return bottom; } } + for(int4 i=head->sizeOut()-1;i>=0;--i) { + if (head->getOut(i) == head) // Check for head looping with itself + return head; + } return (FlowBlock *)0; } @@ -391,17 +396,17 @@ void LoopBody::emitLikelyEdges(list &likely,FlowBlock *graph) break; } } - likely.push_back(FloatingEdge(inbl,outbl)); + likely.emplace_back(inbl,outbl); } for(int4 i=tails.size()-1;i>=0;--i) { // Go in reverse order, to put out less preferred back-edges first if ((holdin!=(FlowBlock *)0)&&(i==0)) - likely.push_back(FloatingEdge(holdin,holdout)); // Put in delayed exit, right before final backedge + likely.emplace_back(holdin,holdout); // Put in delayed exit, right before final backedge FlowBlock *tail = tails[i]; int4 sizeout = tail->sizeOut(); for(int4 j=0;j getOut(j); if (bl == head) // If out edge to head (back-edge for this loop) - likely.push_back(FloatingEdge(tail,head)); // emit it + likely.emplace_back(tail,head); // emit it } } } @@ -652,7 +657,7 @@ void TraceDAG::removeTrace(BlockTrace *trace) { // Record that we should now treat this edge like goto - likelygoto.push_back(FloatingEdge(trace->bottom,trace->destnode)); // Create goto record + likelygoto.emplace_back(trace->bottom,trace->destnode); // Create goto record trace->destnode->setVisitCount( trace->destnode->getVisitCount() + trace->edgelump ); // Ignore edge(s) BranchPoint *parentbp = trace->top; @@ -1194,11 +1199,21 @@ bool CollapseStructure::updateLoopBody(void) FlowBlock *loopbottom = (FlowBlock *)0; FlowBlock *looptop = (FlowBlock *)0; while (loopbodyiter != loopbody.end()) { // Last innermost loop - loopbottom = (*loopbodyiter).getCurrentBounds(&looptop,&graph); + LoopBody &curBody( *loopbodyiter ); + loopbottom = curBody.update(&graph); if (loopbottom != (FlowBlock *)0) { - if ((!likelylistfull) || - (likelyiter != likelygoto.end())) // Reaching here means, we removed edges but loop still didn't collapse + looptop = curBody.getHead(); + if (loopbottom == looptop) { // Check for single node looping back to itself + // If sizeout is 1 or 2, the loop would have collapsed, so the node is likely a switch. + likelygoto.clear(); + likelygoto.emplace_back(looptop,looptop); // Mark the loop edge as a goto + likelyiter = likelygoto.begin(); + likelylistfull = true; + return true; + } + if (!likelylistfull || likelyiter != likelygoto.end()) { break; // Loop still exists + } } ++loopbodyiter; likelylistfull = false; // Need to generate likely list for new loopbody (or no loopbody) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/blockaction.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/blockaction.hh index 6cebf98850..4cef5f4498 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/blockaction.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/blockaction.hh @@ -55,7 +55,7 @@ class LoopBody { public: LoopBody(FlowBlock *h) { head=h; immed_container = (LoopBody *)0; depth=0; } ///< Construct with a loop head FlowBlock *getHead(void) const { return head; } ///< Return the head FlowBlock of the loop - FlowBlock *getCurrentBounds(FlowBlock **top,FlowBlock *graph); ///< Return current loop bounds (\b head and \b bottom). + FlowBlock *update(FlowBlock *graph); ///< Update loop body to current view void addTail(FlowBlock *bl) { tails.push_back(bl); } ///< Add a \e tail to the loop FlowBlock *getExitBlock(void) const { return exitblock; } ///< Get the exit FlowBlock or NULL void findBase(vector &body); ///< Mark the body FlowBlocks of \b this loop diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc index 247c90c598..65c1cc7889 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc @@ -4984,38 +4984,37 @@ int4 FuncCallSpecs::transferLockedInputParam(ProtoParameter *param) return 0; } -/// Return the p-code op whose output Varnode corresponds to the given parameter (return value) +/// \brief Return any outputs of \b this CALL that contain or are contained by the given return value parameter /// -/// The Varnode may be attached to the base CALL or CALLIND, but it also may be -/// attached to an INDIRECT preceding the CALL. The output Varnode may not exactly match -/// the dimensions of the given parameter. We return non-null if either: +/// The output Varnodes may be attached to the base CALL or CALLIND, but also may be +/// attached to an INDIRECT preceding the CALL. The output Varnodes may not exactly match +/// the dimensions of the given parameter. We pass back a Varnode if either: /// - The parameter contains the Varnode (the easier case) OR if /// - The Varnode properly contains the parameter /// \param param is the given paramter (return value) +/// \param newoutput will hold any overlapping output Varnodes /// \return the matching PcodeOp or NULL -PcodeOp *FuncCallSpecs::transferLockedOutputParam(ProtoParameter *param) +void FuncCallSpecs::transferLockedOutputParam(ProtoParameter *param,vector &newoutput) { Varnode *vn = op->getOut(); if (vn != (Varnode *)0) { - if (param->getAddress().justifiedContain(param->getSize(),vn->getAddr(),vn->getSize(),false)==0) - return op; - if (vn->getAddr().justifiedContain(vn->getSize(),param->getAddress(),param->getSize(),false)==0) - return op; - return (PcodeOp *)0; + if (param->getAddress().justifiedContain(param->getSize(),vn->getAddr(),vn->getSize(),false)>=0) + newoutput.push_back(vn); + else if (vn->getAddr().justifiedContain(vn->getSize(),param->getAddress(),param->getSize(),false)>=0) + newoutput.push_back(vn); } PcodeOp *indop = op->previousOp(); while((indop!=(PcodeOp *)0)&&(indop->code()==CPUI_INDIRECT)) { if (indop->isIndirectCreation()) { vn = indop->getOut(); - if (param->getAddress().justifiedContain(param->getSize(),vn->getAddr(),vn->getSize(),false)==0) - return indop; - if (vn->getAddr().justifiedContain(vn->getSize(),param->getAddress(),param->getSize(),false)==0) - return indop; + if (param->getAddress().justifiedContain(param->getSize(),vn->getAddr(),vn->getSize(),false)>=0) + newoutput.push_back(vn); + else if (vn->getAddr().justifiedContain(vn->getSize(),param->getAddress(),param->getSize(),false)>=0) + newoutput.push_back(vn); } indop = indop->previousOp(); } - return (PcodeOp *)0; } /// \brief List and/or create a Varnode for each input parameter of matching a source prototype @@ -5057,19 +5056,14 @@ bool FuncCallSpecs::transferLockedInput(vector &newinput,const FuncPr /// \param newoutput will hold the passed back Varnode /// \param source is the source prototype /// \return \b true if the passed back value is accurate -bool FuncCallSpecs::transferLockedOutput(Varnode *&newoutput,const FuncProto &source) +bool FuncCallSpecs::transferLockedOutput(vector &newoutput,const FuncProto &source) { ProtoParameter *param = source.getOutput(); if (param->getType()->getMetatype() == TYPE_VOID) { - newoutput = (Varnode *)0; return true; } - PcodeOp *outop = transferLockedOutputParam(param); - if (outop == (PcodeOp *)0) - newoutput = (Varnode *)0; - else - newoutput = outop->getOut(); + transferLockedOutputParam(param,newoutput); return true; } @@ -5126,103 +5120,136 @@ void FuncCallSpecs::commitNewInputs(Funcdata &data,vector &newinput) /// \brief Update output Varnode to \b this CALL to reflect the formal return value /// -/// The current return value must be locked and is presumably out of date -/// with the current CALL output. Unless the return value is \e void, the -/// output Varnode must exist and must be provided. -/// The Varnode is updated to reflect the return value, -/// which may involve truncating or extending. Any active trials are updated, -/// and the new Varnode is set as the CALL output. +/// The current return value must be locked and is presumably out of date with the current CALL output. +/// Unless the return value is \e void, the output Varnode must exist and must be provided. +/// The Varnode is created/updated to reflect the return value and is set as the CALL output. +/// Any other intersecting outputs are updated to be either truncations or extensions of this. +/// Any active trials are updated, /// \param data is the calling function -/// \param newout is the provided old output Varnode (or NULL) -void FuncCallSpecs::commitNewOutputs(Funcdata &data,Varnode *newout) +/// \param newout is the list of intersecting outputs +void FuncCallSpecs::commitNewOutputs(Funcdata &data,vector &newoutput) { if (!isOutputLocked()) return; activeoutput.clear(); - if (newout != (Varnode *)0) { + if (!newoutput.empty()) { ProtoParameter *param = getOutput(); // We could conceivably truncate the output to the correct size to match the parameter activeoutput.registerTrial(param->getAddress(),param->getSize()); - PcodeOp *indop = newout->getDef(); - if (newout->getSize() == 1 && param->getType()->getMetatype() == TYPE_BOOL && data.isTypeRecoveryOn()) + if (param->getSize() == 1 && param->getType()->getMetatype() == TYPE_BOOL && data.isTypeRecoveryOn()) data.opMarkCalculatedBool(op); - if (newout->getSize() == param->getSize()) { - if (indop != op) { - data.opUnsetOutput(indop); - data.opUnlink(indop); // We know this is an indirect creation which is no longer used + Varnode *exactMatch = (Varnode *)0; + for(int4 i=0;i getSize() == param->getSize()) { + exactMatch = newoutput[i]; + break; + } + } + Varnode *realOut; + PcodeOp *indOp; + if (exactMatch != (Varnode *)0) { + // If we have a Varnode that exactly matches param, make sure it is the output of the CALL + indOp = exactMatch->getDef(); + if (op != indOp) { // If we reach here, we know -op- must have no output - data.opSetOutput(op,newout); + data.opSetOutput(op,exactMatch); + data.opUnlink(indOp); // We know this is an indirect creation which is no longer used } + realOut = exactMatch; } - else if (newout->getSize() < param->getSize()) { - // We know newout is properly justified within param - if (indop != op) { - data.opUninsert(indop); - data.opSetOpcode(indop,CPUI_SUBPIECE); - } - else { - indop = data.newOp(2,op->getAddr()); - data.opSetOpcode(indop,CPUI_SUBPIECE); - data.opSetOutput(indop,newout); // Move -newout- from -op- to -indop- - } - Varnode *realout = data.newVarnodeOut(param->getSize(),param->getAddress(),op); - data.opSetInput(indop,realout,0); - data.opSetInput(indop,data.newConstant(4,0),1); - data.opInsertAfter(indop,op); + else { + // Otherwise, we create a Varnode matching param + data.opUnsetOutput(op); + realOut = data.newVarnodeOut(param->getSize(),param->getAddress(),op); } - else { // param->getSize() < newout->getSize() - // We know param is justified contained in newout - VarnodeData vardata; - // Test whether the new prototype naturally extends its output - OpCode opc = assumedOutputExtension(param->getAddress(),param->getSize(),vardata); - Address hiaddr = newout->getAddr(); - if (opc != CPUI_COPY) { - // If -newout- looks like a natural extension of the true output type, create the extension op - if (opc == CPUI_PIECE) { // Extend based on the datatype - if (param->getType()->getMetatype() == TYPE_INT) - opc = CPUI_INT_SEXT; - else - opc = CPUI_INT_ZEXT; - } - if (indop != op) { - data.opUninsert(indop); - data.opRemoveInput(indop,1); - data.opSetOpcode(indop,opc); - Varnode *outvn = data.newVarnodeOut(param->getSize(),param->getAddress(),op); - data.opSetInput(indop,outvn,0); - data.opInsertAfter(indop,op); + + for(int4 i=0;i getDef(); + if (indOp == op) + indOp = (PcodeOp *)0; + if (oldOut->getSize() < param->getSize()) { + if (indOp != (PcodeOp *)0) { + data.opUninsert(indOp); + data.opSetOpcode(indOp,CPUI_SUBPIECE); } else { - PcodeOp *extop = data.newOp(1,op->getAddr()); - data.opSetOpcode(extop,opc); - data.opSetOutput(extop,newout); // Move newout from -op- to -extop- - Varnode *outvn = data.newVarnodeOut(param->getSize(),param->getAddress(),op); - data.opSetInput(extop,outvn,0); - data.opInsertAfter(extop,op); + indOp = data.newOp(2,op->getAddr()); + data.opSetOpcode(indOp,CPUI_SUBPIECE); + data.opSetOutput(indOp,oldOut); // Move oldOut from op to indOp } + int4 overlap = oldOut->overlap(realOut->getAddr(),realOut->getSize()); + data.opSetInput(indOp,realOut,0); + data.opSetInput(indOp,data.newConstant(4,(uintb)overlap),1); + data.opInsertAfter(indOp,op); } - else { // If all else fails, concatenate in extra byte from something "indirectly created" by -op- - int4 hisz = newout->getSize() - param->getSize(); - if (!newout->getAddr().getSpace()->isBigEndian()) - hiaddr = hiaddr + param->getSize(); - PcodeOp *newindop = data.newIndirectCreation(op,hiaddr,hisz,true); - if (indop != op) { - data.opUninsert(indop); - data.opSetOpcode(indop,CPUI_PIECE); - Varnode *outvn = data.newVarnodeOut(param->getSize(),param->getAddress(),op); - data.opSetInput(indop,newindop->getOut(),0); - data.opSetInput(indop,outvn,1); - data.opInsertAfter(indop,op); + else if (param->getSize() < oldOut->getSize()) { + int4 overlap = oldOut->getAddr().justifiedContain(oldOut->getSize(), param->getAddress(), param->getSize(), false); + VarnodeData vardata; + // Test whether the new prototype naturally extends its output + OpCode opc = assumedOutputExtension(param->getAddress(),param->getSize(),vardata); + if (opc != CPUI_COPY && overlap == 0) { + // If oldOut looks like a natural extension of the true output type, create the extension op + if (opc == CPUI_PIECE) { // Extend based on the data-type + if (param->getType()->getMetatype() == TYPE_INT) + opc = CPUI_INT_SEXT; + else + opc = CPUI_INT_ZEXT; + } + if (indOp != (PcodeOp *)0) { + data.opUninsert(indOp); + data.opRemoveInput(indOp,1); + data.opSetOpcode(indOp,opc); + data.opSetInput(indOp,realOut,0); + data.opInsertAfter(indOp,op); + } + else { + PcodeOp *extop = data.newOp(1,op->getAddr()); + data.opSetOpcode(extop,opc); + data.opSetOutput(extop,oldOut); // Move newout from -op- to -extop- + data.opSetInput(extop,realOut,0); + data.opInsertAfter(extop,op); + } } - else { - PcodeOp *concatop = data.newOp(2,op->getAddr()); - data.opSetOpcode(concatop,CPUI_PIECE); - data.opSetOutput(concatop,newout); // Move newout from -op- to -concatop- - Varnode *outvn = data.newVarnodeOut(param->getSize(),param->getAddress(),op); - data.opSetInput(concatop,newindop->getOut(),0); - data.opSetInput(concatop,outvn,1); - data.opInsertAfter(concatop,op); + else { // If all else fails, concatenate in extra byte from something "indirectly created" by -op- + if (indOp != (PcodeOp *)0) { + data.opUnlink(indOp); + } + int4 mostSigSize = oldOut->getSize() - overlap - realOut->getSize(); + PcodeOp *lastOp = op; + if (overlap != 0) { // We need to append less significant bytes to realOut for this oldOut + Address loAddr = oldOut->getAddr(); + if (loAddr.isBigEndian()) + loAddr = loAddr + (oldOut->getSize() - overlap); + PcodeOp *newIndOp = data.newIndirectCreation(op,loAddr,overlap,true); + PcodeOp *concatOp = data.newOp(2,op->getAddr()); + data.opSetOpcode(concatOp,CPUI_PIECE); + data.opSetInput(concatOp,realOut,0); // Most significant part + data.opSetInput(concatOp,newIndOp->getOut(),1); // Least sig + data.opInsertAfter(concatOp,op); + if (mostSigSize != 0) { + if (loAddr.isBigEndian()) + data.newVarnodeOut(overlap+realOut->getSize(),realOut->getAddr(),concatOp); + else + data.newVarnodeOut(overlap+realOut->getSize(),loAddr,concatOp); + } + lastOp = concatOp; + } + if (mostSigSize != 0) { // We need to append more significant bytes to realOut for this oldOut + Address hiAddr = oldOut->getAddr(); + if (!hiAddr.isBigEndian()) + hiAddr = hiAddr + (realOut->getSize() + overlap); + PcodeOp *newIndOp = data.newIndirectCreation(op,hiAddr,mostSigSize,true); + PcodeOp *concatOp = data.newOp(2,op->getAddr()); + data.opSetOpcode(concatOp,CPUI_PIECE); + data.opSetInput(concatOp,newIndOp->getOut(),0); + data.opSetInput(concatOp,lastOp->getOut(),1); + data.opInsertAfter(concatOp,lastOp); + lastOp = concatOp; + } + data.opSetOutput(lastOp,oldOut); // We have completed the redefinition of this oldOut } } } @@ -5307,7 +5334,8 @@ void FuncCallSpecs::doInputJoin(int4 slot1,bool ishislot) /// \param newinput will hold the new list of input Varnodes for the CALL /// \param newoutput will hold the new output Varnode or NULL /// \return \b true if \b this can be fully converted -bool FuncCallSpecs::lateRestriction(const FuncProto &restrictedProto,vector &newinput,Varnode *&newoutput) +bool FuncCallSpecs::lateRestriction(const FuncProto &restrictedProto,vector &newinput, + vector &newoutput) { if (!hasModel()) { @@ -5357,7 +5385,7 @@ void FuncCallSpecs::deindirect(Funcdata &data,Funcdata *newfd) // Try our best to merge existing prototype // with the one we have just been handed vector newinput; - Varnode *newoutput; + vector newoutput; FuncProto &newproto( newfd->getFuncProto() ); if ((!newproto.isNoReturn())&&(!newproto.isInline())) { if (isOverride()) // If we are overridden at the call-site @@ -5387,7 +5415,7 @@ void FuncCallSpecs::forceSet(Funcdata &data,const FuncProto &fp) { vector newinput; - Varnode *newoutput; + vector newoutput; // Copy the recovered prototype into the override manager so that // future restarts don't have to rediscover it diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.hh index 55ec487467..9509fe7f34 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.hh @@ -1657,11 +1657,11 @@ class FuncCallSpecs : public FuncProto { Varnode *getSpacebaseRelative(void) const; ///< Get the active stack-pointer Varnode at \b this call site Varnode *buildParam(Funcdata &data,Varnode *vn,ProtoParameter *param,Varnode *stackref); int4 transferLockedInputParam(ProtoParameter *param); - PcodeOp *transferLockedOutputParam(ProtoParameter *param); + void transferLockedOutputParam(ProtoParameter *param,vector &newoutput); bool transferLockedInput(vector &newinput,const FuncProto &source); - bool transferLockedOutput(Varnode *&newoutput,const FuncProto &source); + bool transferLockedOutput(vector &newoutput,const FuncProto &source); void commitNewInputs(Funcdata &data,vector &newinput); - void commitNewOutputs(Funcdata &data,Varnode *newout); + void commitNewOutputs(Funcdata &data,vector &newoutput); void collectOutputTrialVarnodes(vector &trialvn); void setStackPlaceholderSlot(int4 slot) { stackPlaceholderSlot = slot; if (isinputactive) activeinput.setPlaceholderSlot(); } ///< Set the slot of the stack-pointer placeholder @@ -1702,7 +1702,7 @@ public: bool checkInputJoin(int4 slot1,bool ishislot,Varnode *vn1,Varnode *vn2) const; void doInputJoin(int4 slot1,bool ishislot); - bool lateRestriction(const FuncProto &restrictedProto,vector &newinput,Varnode *&newoutput); + bool lateRestriction(const FuncProto &restrictedProto,vector &newinput,vector &newoutput); void deindirect(Funcdata &data,Funcdata *newfd); void forceSet(Funcdata &data,const FuncProto &fp); void insertPcode(Funcdata &data); diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/subflow.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/subflow.cc index bde73ee843..b6917f31fd 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/subflow.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/subflow.cc @@ -1515,6 +1515,8 @@ bool SplitFlow::addOp(PcodeOp *op,TransformVar *rvn,int4 slot) if (op->code() == CPUI_INDIRECT) { opSetInput(loOp,newIop(op->getIn(1)),1); opSetInput(hiOp,newIop(op->getIn(1)),1); + loOp->inheritIndirect(op); + hiOp->inheritIndirect(op); numParam = 1; } for(int4 i=0;i isIndirectCreation()) { + if (indOp->getIn(0)->isIndirectZero()) + special |= TransformOp::indirect_creation; + else + special |= TransformOp::indirect_creation_possible_out; + } +} + void LanedRegister::LanedIterator::normalize(void) { diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/transform.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/transform.hh index e8cf9877a0..08462ed07c 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/transform.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/transform.hh @@ -87,6 +87,7 @@ private: public: TransformVar *getOut(void) const { return output; } ///< Get the output placeholder variable for \b this operator TransformVar *getIn(int4 i) const { return input[i]; } ///< Get the i-th input placeholder variable for \b this + void inheritIndirect(PcodeOp *indOp); ///< Set \e indirect \e creation flags for \b this based on given INDIRECT }; /// \brief Describes a (register) storage location and the ways it might be split into lanes diff --git a/Ghidra/Features/Decompiler/src/decompile/datatests/deindirect2.xml b/Ghidra/Features/Decompiler/src/decompile/datatests/deindirect2.xml new file mode 100644 index 0000000000..9d0b940f6e --- /dev/null +++ b/Ghidra/Features/Decompiler/src/decompile/datatests/deindirect2.xml @@ -0,0 +1,28 @@ + + diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompileProcess.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompileProcess.java index 6ff9aa2039..b73169f9e7 100644 --- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompileProcess.java +++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompileProcess.java @@ -145,42 +145,48 @@ public class DecompileProcess { throw new IOException("Could not find decompiler executable"); } IOException exc = null; - String err = ""; statusGood = false; + try { nativeProcess = runtime.exec(exepath); + // Give process time to load and report possible error - nativeProcess.waitFor(200, TimeUnit.MILLISECONDS); + try { + nativeProcess.waitFor(200, TimeUnit.MILLISECONDS); + } + catch (InterruptedException e) { + // Restore interrupted thread state since we are continuing with setup. + // It does not appear that the decompiler interface is affected by an + // interrupted thread so why stop here. + Thread.currentThread().interrupt(); + } + nativeIn = nativeProcess.getInputStream(); nativeOut = nativeProcess.getOutputStream(); + statusGood = nativeProcess.isAlive(); if (!statusGood) { - err = new String(nativeProcess.getErrorStream().readAllBytes()); - nativeProcess.destroy(); - nativeProcess = null; + if (!getAndSetErrorDisplayed()) { + String err = new String(nativeProcess.getErrorStream().readAllBytes()); + String errorDetail = "Decompiler executable may not be compatible with your system and may need to be rebuilt.\n" + + "(see InstallationGuide.html, 'Building Native Components').\n\n" + + err; + Msg.showError(this, null, "Failed to launch Decompiler process", errorDetail); + } } } catch (IOException e) { - exc = e; - } - catch (InterruptedException e) { - // ignore + exc = e; // permission error, etc. } finally { if (!statusGood) { disposestate = DisposeState.DISPOSED_ON_STARTUP_FAILURE; - if (!getAndSetErrorDisplayed()) { - String errorDetail = err; - if (exc != null) { - errorDetail = exc.getMessage() + "\n" + errorDetail; - } - errorDetail = "Decompiler executable may not be compatible with your system and may need to be rebuilt.\n" + - "(see InstallationGuide.html, 'Building Native Components').\n\n" + - errorDetail; - Msg.showError(this, null, "Failed to launch Decompiler process", errorDetail); + if (nativeProcess != null) { + nativeProcess.destroy(); + nativeProcess = null; } if (exc == null) { - throw new IOException("Decompiler process failed to launch (see log for details)"); + exc = new IOException("Decompiler process failed to launch (see log for details)"); } throw exc; } diff --git a/Ghidra/Features/Decompiler/src/test.slow/java/ghidra/app/plugin/core/decompile/DecompilerNavigationTest.java b/Ghidra/Features/Decompiler/src/test.slow/java/ghidra/app/plugin/core/decompile/DecompilerNavigationTest.java index 5544ea5bfd..6a5d56a991 100644 --- a/Ghidra/Features/Decompiler/src/test.slow/java/ghidra/app/plugin/core/decompile/DecompilerNavigationTest.java +++ b/Ghidra/Features/Decompiler/src/test.slow/java/ghidra/app/plugin/core/decompile/DecompilerNavigationTest.java @@ -197,9 +197,8 @@ public class DecompilerNavigationTest extends AbstractDecompilerTest { public void testFunctionNavigation_WithAViewThatCachesTheLastValidFunction() throws Exception { // - // This is testing the case where the user starts on a function foo(). Ancillary windows - // will display tool, such as a decompiled view. Now, if the user clicks to a - // non-function location, such as data, the ancillary window may still show foo(), even + // This is testing the case where the user starts on a function foo(). When the user clicks + // away to a non-function location, such as data, the window may still show foo(), even // though the user is no longer in foo. At this point, if the user wishes to go to the // previous function, then from the ancillary window's perspective, it is the function // that came before foo(). @@ -212,12 +211,13 @@ public class DecompilerNavigationTest extends AbstractDecompilerTest { goTo(f1); goTo(f2); goTo(nonFunctionAddress); + waitForDecompiler(); String title = provider.getTitle(); - assertTrue("Decompiler did not retain last function visited", title.contains("sscanf")); + assertTrue("Decompiler did not retain last function visited. " + + "Expected sscanf, but was '%s'".formatted(title), title.contains("sscanf")); - provider.requestFocus(); - waitForSwing(); + focusDecompiler(); // // The Decompiler is focused, showing 'entry'. Going back while it is focused should go @@ -227,22 +227,6 @@ public class DecompilerNavigationTest extends AbstractDecompilerTest { assertCurrentAddress(f1); } - private void previousFunction() { - NextPrevAddressPlugin plugin = env.getPlugin(NextPrevAddressPlugin.class); - DockingAction previousFunctionAction = - (DockingAction) getInstanceField("previousFunctionAction", plugin); - - ActionContext context = provider.getActionContext(null); - assertTrue(previousFunctionAction.isEnabledForContext(context)); - performAction(previousFunctionAction, context, true); - waitForSwing(); - } - - private void assertListingAddress(Address expected) { - waitForCondition(() -> expected.equals(codeBrowser.getCurrentLocation().getAddress()), - "The Listing is not at the expected address"); - } - @Override public void assertCurrentAddress(Address expected) { codeBrowser.updateNow(); @@ -255,6 +239,27 @@ public class DecompilerNavigationTest extends AbstractDecompilerTest { }, "Listing is not at the expected address"); } + private void focusDecompiler() { + runSwing(() -> provider.requestFocus()); + waitForSwing(); + } + + private void previousFunction() { + NextPrevAddressPlugin plugin = env.getPlugin(NextPrevAddressPlugin.class); + DockingAction previousFunctionAction = + (DockingAction) getInstanceField("previousFunctionAction", plugin); + + ActionContext context = runSwing(() -> provider.getActionContext(null)); + assertTrue(previousFunctionAction.isEnabledForContext(context)); + performAction(previousFunctionAction, context, true); + waitForSwing(); + } + + private void assertListingAddress(Address expected) { + waitForCondition(() -> expected.equals(codeBrowser.getCurrentLocation().getAddress()), + "The Listing is not at the expected address"); + } + private void assertExternalNavigationPerformed() { // going to the 'external linkage' means we went to the thunk function and not the // external program @@ -269,9 +274,7 @@ public class DecompilerNavigationTest extends AbstractDecompilerTest { private void createThunkToExternal(String addressString) throws Exception { - int txId = program.startTransaction("Set External Location"); - try { - + tx(program, () -> { program.getExternalManager().setExternalPath("ADVAPI32.dll", "/FILE1", true); Address address = addr(addressString); @@ -289,12 +292,6 @@ public class DecompilerNavigationTest extends AbstractDecompilerTest { Function function = program.getFunctionManager().getFunctionAt(addr(addressString)); function.setThunkedFunction(externalLocation.getFunction()); - } - finally { - program.endTransaction(txId, true); - } - - program.flushEvents(); - waitForSwing(); + }); } } diff --git a/Ghidra/Framework/DB/src/main/java/db/buffers/BufferMgr.java b/Ghidra/Framework/DB/src/main/java/db/buffers/BufferMgr.java index 88eda4b1ba..ade2f55f36 100644 --- a/Ghidra/Framework/DB/src/main/java/db/buffers/BufferMgr.java +++ b/Ghidra/Framework/DB/src/main/java/db/buffers/BufferMgr.java @@ -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() { diff --git a/Ghidra/Framework/Docking/src/main/java/docking/ComponentProvider.java b/Ghidra/Framework/Docking/src/main/java/docking/ComponentProvider.java index 324db9f96a..90d12575d6 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/ComponentProvider.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/ComponentProvider.java @@ -181,7 +181,7 @@ public abstract class ComponentProvider implements HelpDescriptor, ActionContext } if (isVisible()) { - // if we are visible, then we don't need to update as the system updates all + // if we are visible, then we don't need to update as the system updates all // visible components return; } @@ -231,7 +231,6 @@ public abstract class ComponentProvider implements HelpDescriptor, ActionContext return; } - dockingTool.toFront(); if (defaultFocusComponent != null) { DockingWindowManager.requestFocus(defaultFocusComponent); return; @@ -848,7 +847,7 @@ public abstract class ComponentProvider implements HelpDescriptor, ActionContext * will adjust the font for the registered font id if it has been registered using * {@link #registeredFontId}. Subclasses can override this method to a more comprehensive * adjustment to multiple fonts if necessary. - * @param bigger if true, the font should be made bigger, otherwise the font should be made + * @param bigger if true, the font should be made bigger, otherwise the font should be made * smaller */ public void adjustFontSize(boolean bigger) { diff --git a/Ghidra/Framework/Docking/src/main/java/docking/MouseBindingMouseEventDispatcher.java b/Ghidra/Framework/Docking/src/main/java/docking/MouseBindingMouseEventDispatcher.java index 8be74a3a01..57a9629d4a 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/MouseBindingMouseEventDispatcher.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/MouseBindingMouseEventDispatcher.java @@ -4,9 +4,9 @@ * 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. @@ -70,6 +70,17 @@ public class MouseBindingMouseEventDispatcher { toolkit.addAWTEventListener(listener, AWTEvent.MOUSE_EVENT_MASK); } + private boolean isSettingMouseBinding(MouseEvent e) { + Component destination = e.getComponent(); + if (destination == null) { + Component focusOwner = focusProvider.getFocusOwner(); + destination = focusOwner; + } + + // This is the class we use to set mouse bindings + return destination instanceof MouseEntryTextField; + } + private void process(MouseEvent e) { int id = e.getID(); @@ -77,6 +88,10 @@ public class MouseBindingMouseEventDispatcher { return; } + if (isSettingMouseBinding(e)) { + return; // the user is setting the binding; do not process system actions + } + // always let the application finish processing key events that it started if (actionInProgress(e)) { return; @@ -126,6 +141,16 @@ public class MouseBindingMouseEventDispatcher { new ActionEvent(source, ActionEvent.ACTION_PERFORMED, command, when, modifiers)); } + int eventButton = e.getButton(); + int bindingButton = mouseBinding.getButton(); + if (eventButton != bindingButton) { + // We may have missed an event or the user pressed multiple mouse buttons in an + // unexpected sequence. Clear the in-progress action here so we do not consume all + // mouse events indefinitely. + inProgressAction = null; + return false; + } + e.consume(); return true; } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/MouseEntryTextField.java b/Ghidra/Framework/Docking/src/main/java/docking/MouseEntryTextField.java index a7b23f78f2..5ee2e14722 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/MouseEntryTextField.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/MouseEntryTextField.java @@ -92,6 +92,15 @@ public class MouseEntryTextField extends HintTextField { int modifiersEx = e.getModifiersEx(); int button = e.getButton(); + + int buttonDownMask = InputEvent.getMaskForButton(button); + if (button == MouseEvent.BUTTON1 && buttonDownMask == modifiersEx) { + // Don't allow the user to bind an unmodified left-click, as odd behavior can ensue. + // We can revisit this if a valid use case is found. + e.consume(); + return; + } + processMouseBinding(new MouseBinding(button, modifiersEx), true); e.consume(); } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/data/GhidraFileData.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/data/GhidraFileData.java index dda4f1e667..120f59174b 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/data/GhidraFileData.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/data/GhidraFileData.java @@ -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(); } } diff --git a/Ghidra/Processors/MC6800/data/languages/6805.slaspec b/Ghidra/Processors/MC6800/data/languages/6805.slaspec index 23d42bbe4b..7edef3f495 100644 --- a/Ghidra/Processors/MC6800/data/languages/6805.slaspec +++ b/Ghidra/Processors/MC6800/data/languages/6805.slaspec @@ -169,7 +169,7 @@ DIRECT: imm8 is imm8 { export *:1 imm8; } } :BHI REL is op=0x22;REL { - local tmp = C + Z; + local tmp = C || Z; if (tmp == 0) goto REL; } @@ -195,7 +195,7 @@ DIRECT: imm8 is imm8 { export *:1 imm8; } :BLS REL is op=0x23;REL { - local tmp = C + Z; + local tmp = C || Z; if (tmp) goto REL; } diff --git a/Ghidra/Processors/Z80/build.gradle b/Ghidra/Processors/Z80/build.gradle index b59b151b6f..2bf51219de 100644 --- a/Ghidra/Processors/Z80/build.gradle +++ b/Ghidra/Processors/Z80/build.gradle @@ -18,4 +18,6 @@ apply from: "$rootProject.projectDir/gradle/processorProject.gradle" apply plugin: 'eclipse' eclipse.project.name = 'Processors Z80' - +sleighCompileOptions = [ + '-l' +] diff --git a/Ghidra/Processors/Z80/data/languages/z80.slaspec b/Ghidra/Processors/Z80/data/languages/z80.slaspec index 6d2bc351af..12a590ba7f 100644 --- a/Ghidra/Processors/Z80/data/languages/z80.slaspec +++ b/Ghidra/Processors/Z80/data/languages/z80.slaspec @@ -20,7 +20,7 @@ define register offset=0x00 size=2 [ AF BC DE HL ]; define register offset=0x20 size=1 [ F_ A_ C_ B_ E_ D_ L_ H_ ]; # Alternate registers define register offset=0x20 size=2 [ AF_ BC_ DE_ HL_ ]; # Alternate registers define register offset=0x40 size=2 [ _ PC SP IX IY ]; - +define register offset=0x46 size=1 [ IXL IXH IYL IYH ]; # Undocumented registers define register offset=0x50 size=1 [ rCBAR rCBR rBBR ]; # Fake Registers used for pcode control @@ -451,16 +451,18 @@ cc2: "C" is bits3_3=0x7 { c:1 = $(C_flag); export c; } } :LD A,I is op0_8=0xed & A & I; op0_8=0x57 { - A = I; - setResultFlags(I); + local val = I; + A = val; + setResultFlags(val); $(H_flag) = 0; # $(PV_flag) = IFF2; $(N_flag) = 0; } :LD A,R is op0_8=0xed & A & R; op0_8=0x5f { - A = R; - setResultFlags(R); + local val = R; + A = val; + setResultFlags(val); $(H_flag) = 0; # $(PV_flag) = IFF2; $(N_flag) = 0; @@ -591,49 +593,73 @@ cc2: "C" is bits3_3=0x7 { c:1 = $(C_flag); export c; } swap(IY); } -# ?? Instruction manual contradicts itself - not sure what to do here ?? :LDI is op0_8=0xed; op0_8=0xa0 { val:1 = 0; - MemRead(val,HL); - MemStore(DE,val); - DE = DE + 1; - HL = HL + 1; - BC = BC - 1; + local inloc = HL; + local outloc = DE; + MemRead(val,inloc); + MemStore(outloc,val); + + DE = outloc + 1; + HL = inloc + 1; + local test = BC - 1; + BC = test; + $(H_flag) = 0; - $(PV_flag) = (BC != 0); + $(PV_flag) = (test != 0); $(N_flag) = 0; } :LDIR is op0_8=0xed; op0_8=0xb0 { - tmp:1 = 0; - MemRead(tmp,HL); - MemStore(DE,tmp); - DE = DE + 1; - HL = HL + 1; - BC = BC - 1; - if (BC != 0) goto inst_start; + val:1 = 0; + local inloc = HL; + local outloc = DE; + MemRead(val,inloc); + MemStore(outloc,val); + + DE = outloc + 1; + HL = inloc + 1; + local test = BC - 1; + BC = test; + + if (test != 0) goto inst_start; + $(H_flag) = 0; - $(PV_flag) = (BC != 0); + $(PV_flag) = 0; $(N_flag) = 0; } :LDD is op0_8=0xed; op0_8=0xa8 { - DE = DE - 1; - HL = HL - 1; - BC = BC - 1; + val:1 = 0; + local inloc = HL; + local outloc = DE; + MemRead(val,inloc); + MemStore(outloc,val); + + DE = outloc - 1; + HL = inloc - 1; + local test = BC - 1; + BC = test; + $(H_flag) = 0; - $(PV_flag) = (BC != 0); + $(PV_flag) = (test != 0); $(N_flag) = 0; } :LDDR is op0_8=0xed; op0_8=0xb8 { - tmp:1 = 0; - MemRead(tmp,HL); - MemStore(DE,tmp); - DE = DE - 1; - HL = HL - 1; - BC = BC - 1; - if (BC != 0) goto inst_start; + val:1 = 0; + local inloc = HL; + local outloc = DE; + MemRead(val,inloc); + MemStore(outloc,val); + + DE = outloc - 1; + HL = inloc - 1; + local test = BC - 1; + BC = test; + + if (test != 0) goto inst_start; + $(H_flag) = 0; $(PV_flag) = 0; $(N_flag) = 0; @@ -641,395 +667,498 @@ cc2: "C" is bits3_3=0x7 { c:1 = $(C_flag); export c; } :CPI is op0_8=0xed; op0_8=0xa1 { val:1 = 0; - MemRead(val,HL); - cmp:1 = A - val; + local loc = HL; + MemRead(val,loc); + local a_temp = A; + + cmp:1 = a_temp - val; setResultFlags(cmp); - HL = HL + 1; - BC = BC - 1; + HL = loc + 1; + local test = BC - 1; + BC = test; - carries:1 = (~A & val) | (val & cmp) | (cmp & ~A); + carries:1 = (~a_temp & val) | (val & cmp) | (cmp & ~a_temp); $(H_flag) = (carries & 0b00001000) != 0; - $(PV_flag) = (BC != 0); + $(PV_flag) = (test != 0); $(N_flag) = 1; } :CPIR is op0_8=0xed; op0_8=0xb1 { val:1 = 0; - MemRead(val,HL); - cmp:1 = A - val; - setResultFlags(cmp); - HL = HL + 1; - BC = BC - 1; + local loc = HL; + MemRead(val,loc); + local a_temp = A; - if (cmp != 0 || BC != 0) goto inst_start; + cmp:1 = a_temp - val; + setResultFlags(cmp); + HL = loc + 1; + local test = BC - 1; + BC = test; + + if (cmp != 0 || test != 0) goto inst_start; - carries:1 = (~A & val) | (val & cmp) | (cmp & ~A); + carries:1 = (~a_temp & val) | (val & cmp) | (cmp & ~a_temp); $(H_flag) = (carries & 0b00001000) != 0; - $(PV_flag) = (BC != 0); + $(PV_flag) = (test != 0); $(N_flag) = 1; } :CPD is op0_8=0xed; op0_8=0xa9 { val:1 = 0; - MemRead(val,HL); - cmp:1 = A - val; - setResultFlags(cmp); - HL = HL - 1; - BC = BC - 1; + local loc = HL; + MemRead(val,loc); + local a_temp = A; - carries:1 = (~A & val) | (val & cmp) | (cmp & ~A); + cmp:1 = a_temp - val; + setResultFlags(cmp); + HL = loc - 1; + local test = BC - 1; + BC = test; + + carries:1 = (~a_temp & val) | (val & cmp) | (cmp & ~a_temp); $(H_flag) = (carries & 0b00001000) != 0; - $(PV_flag) = (BC != 0); + $(PV_flag) = (test != 0); $(N_flag) = 1; } :CPDR is op0_8=0xed; op0_8=0xb9 { val:1 = 0; - MemRead(val,HL); - cmp:1 = A - val; + local loc = HL; + MemRead(val,loc); + local a_temp = A; + + cmp:1 = a_temp - val; setResultFlags(cmp); - HL = HL - 1; - BC = BC - 1; + HL = loc - 1; + local test = BC - 1; + BC = test; - if (cmp != 0 || BC != 0) goto inst_start; - - carries:1 = (~A & val) | (val & cmp) | (cmp & ~A); + if (cmp != 0 || test != 0) goto inst_start; + + carries:1 = (~a_temp & val) | (val & cmp) | (cmp & ~a_temp); $(H_flag) = (carries & 0b00001000) != 0; - $(PV_flag) = (BC != 0); + $(PV_flag) = (test != 0); $(N_flag) = 1; } :ADD A, reg0_3 is op6_2=0x2 & bits3_3=0x0 & reg0_3 & A { - local A_temp = A; + local a_temp = A; local reg_temp = reg0_3; - - A = A + reg0_3; - setResultFlags(A); - additionFlags(A_temp, reg_temp); + + additionFlags(a_temp, reg_temp); + a_temp= a_temp + reg0_3; + setResultFlags(a_temp); + A = a_temp; } :ADD A, imm8 is op0_8=0xc6; imm8 & A { - local A_temp = A; - - A = A + imm8; - setResultFlags(A); - additionFlags(A_temp, imm8); + local a_temp = A; + + additionFlags(a_temp, imm8); + a_temp = a_temp + imm8; + setResultFlags(a_temp); + A = a_temp; } :ADD A, (HL) is op0_8=0x86 & HL & A { val:1 = 0; MemRead(val,HL); - local A_temp = A; - - A = A + val; - setResultFlags(A); - additionFlags(A_temp, val); + local a_temp = A; + + additionFlags(a_temp, val); + a_temp = a_temp + val; + setResultFlags(a_temp); + A = a_temp; } :ADD A, ixMem8 is op0_8=0xdd; op0_8=0x86; ixMem8 & A { val:1 = ixMem8; - local A_temp = A; - - A = A + val; - setResultFlags(A); - additionFlags(A_temp, val); + local a_temp = A; + + additionFlags(a_temp, val); + a_temp = a_temp + val; + setResultFlags(a_temp); + A = a_temp; } :ADD A, iyMem8 is op0_8=0xfd; op0_8=0x86; iyMem8 & A { val:1 = iyMem8; - local A_temp = A; - - A = A + val; - setResultFlags(A); - additionFlags(A_temp, val); + local a_temp = A; + + additionFlags(a_temp, val); + a_temp = a_temp + val; + setResultFlags(a_temp); + A = a_temp; } :ADC A, reg0_3 is op6_2=0x2 & bits3_3=0x1 & reg0_3 & A { - additionWithCarry(A, reg0_3, A); - setResultFlags(A); + local a_temp = A; + local r_temp = reg0_3; + + additionWithCarry(a_temp, r_temp, a_temp); + setResultFlags(a_temp); + A = a_temp; } :ADC A, imm8 is op0_8=0xce; imm8 & A { - additionWithCarry(A, imm8, A); - setResultFlags(A); + val:1 = imm8; + local a_temp = A; + + additionWithCarry(a_temp, val, a_temp); + setResultFlags(a_temp); + A = a_temp; } :ADC A, (HL) is op0_8=0x8e & HL & A { val:1 = 0; MemRead(val,HL); - additionWithCarry(A, val, A); - setResultFlags(A); + local a_temp = A; + + additionWithCarry(a_temp, val, a_temp); + setResultFlags(a_temp); + A = a_temp; } :ADC A, ixMem8 is op0_8=0xdd; op0_8=0x8e; ixMem8 & A{ val:1 = ixMem8; - additionWithCarry(A, val, A); - setResultFlags(A); + MemRead(val,HL); + local a_temp = A; + + additionWithCarry(a_temp, val, a_temp); + setResultFlags(a_temp); + A = a_temp; } :ADC A, iyMem8 is op0_8=0xfd; op0_8=0x8e; iyMem8 & A { + val:1 = iyMem8; - additionWithCarry(A, val, A); - setResultFlags(A); + MemRead(val,HL); + local a_temp = A; + + additionWithCarry(a_temp, val, a_temp); + setResultFlags(a_temp); + A = a_temp; } :SUB reg0_3 is op6_2=0x2 & bits3_3=0x2 & reg0_3 { - local A_temp = A; - - A = A - reg0_3; - subtractionFlags(A_temp, reg0_3); - setResultFlags(A); + local a_temp = A; + local r_temp = reg0_3; + + subtractionFlags(a_temp, r_temp); + a_temp = a_temp - r_temp; + setResultFlags(a_temp); + a_temp = A; } :SUB imm8 is op0_8=0xd6; imm8 { - local A_temp = A; - - A = A - imm8; - subtractionFlags(A_temp, imm8); - setResultFlags(A); + local a_temp = A; + + subtractionFlags(a_temp, imm8); + a_temp = a_temp - imm8; + setResultFlags(a_temp); + A = a_temp; } :SUB (HL) is op0_8=0x96 & HL { val:1 = 0; MemRead(val,HL); - local A_temp = A; - - A = A - val; - subtractionFlags(A_temp, val); - setResultFlags(A); + local a_temp = A; + + subtractionFlags(a_temp, val); + a_temp = a_temp - val; + setResultFlags(a_temp); + A = a_temp; } :SUB ixMem8 is op0_8=0xdd; op0_8=0x96; ixMem8 { val:1 = ixMem8; - local A_temp = A; - - A = A - val; - subtractionFlags(A_temp, val); - setResultFlags(A); + local a_temp = A; + + subtractionFlags(a_temp, val); + a_temp = a_temp - val; + setResultFlags(a_temp); + A = a_temp; } :SUB iyMem8 is op0_8=0xfd; op0_8=0x96; iyMem8 { val:1 = iyMem8; - local A_temp = A; - - A = A - val; - subtractionFlags(A_temp, val); - setResultFlags(A); + local a_temp = A; + + subtractionFlags(a_temp, val); + a_temp = a_temp - val; + setResultFlags(a_temp); + A = a_temp; } :SBC A, reg0_3 is op6_2=0x2 & bits3_3=0x3 & reg0_3 & A { - subtractionWithCarry(A, reg0_3, A); - setResultFlags(A); + local a_temp = A; + local r_temp = reg0_3; + + subtractionWithCarry(a_temp, r_temp, a_temp); + setResultFlags(a_temp); + A = a_temp; } :SBC A, imm8 is op0_8=0xde; imm8 & A { - subtractionWithCarry(A, imm8, A); - setResultFlags(A); + local a_temp = A; + + subtractionWithCarry(a_temp, imm8, a_temp); + setResultFlags(a_temp); + A = a_temp; } :SBC A, (HL) is op0_8=0x9e & HL & A { val:1 = 0; MemRead(val,HL); - subtractionWithCarry(A, val, A); - setResultFlags(A); + local a_temp = A; + + subtractionWithCarry(a_temp, val, a_temp); + setResultFlags(a_temp); + A = a_temp; } :SBC A, ixMem8 is op0_8=0xdd; op0_8=0x9e; ixMem8 & A { val:1 = ixMem8; - subtractionWithCarry(A, val, A); - setResultFlags(A); + local a_temp = A; + + subtractionWithCarry(a_temp, val, a_temp); + setResultFlags(a_temp); + A = a_temp; } :SBC A, iyMem8 is op0_8=0xfd; op0_8=0x9e; iyMem8 & A { val:1 = iyMem8; - subtractionWithCarry(A, val, A); - setResultFlags(A); + local a_temp = A; + + subtractionWithCarry(a_temp, val, a_temp); + setResultFlags(a_temp); + A = a_temp; } :AND reg0_3 is op6_2=0x2 & bits3_3=0x4 & reg0_3 { + local a_temp = A; $(H_flag) = 1; $(C_flag) = 0; $(N_flag) = 0; - A = A & reg0_3; - setResultFlags(A); - setParity(A); + a_temp = a_temp & reg0_3; + setResultFlags(a_temp); + setParity(a_temp); + A = a_temp; } :AND imm8 is op0_8=0xe6; imm8 { + local a_temp = A; $(H_flag) = 1; $(C_flag) = 0; $(N_flag) = 0; - A = A & imm8; - setResultFlags(A); - setParity(A); + a_temp = a_temp & imm8; + setResultFlags(a_temp); + setParity(a_temp); + A = a_temp; } :AND (HL) is op0_8=0xa6 & HL { + val:1 = 0; + MemRead(val,HL); + local a_temp = A; $(H_flag) = 1; $(C_flag) = 0; $(N_flag) = 0; - tmp:1 = 0; - MemRead(tmp,HL); - A = A & tmp; - setResultFlags(A); - setParity(A); + + a_temp = a_temp & val; + setResultFlags(a_temp); + setParity(a_temp); + A = a_temp; } :AND ixMem8 is op0_8=0xdd; op0_8=0xa6; ixMem8 { + local a_temp = A; $(H_flag) = 1; $(C_flag) = 0; $(N_flag) = 0; - A = A & ixMem8; - setResultFlags(A); - setParity(A); + a_temp = a_temp & ixMem8; + setResultFlags(a_temp); + setParity(a_temp); + A = a_temp; } :AND iyMem8 is op0_8=0xfd; op0_8=0xa6; iyMem8 { + local a_temp = A; $(H_flag) = 1; $(C_flag) = 0; $(N_flag) = 0; - A = A & iyMem8; - setResultFlags(A); - setParity(A); + a_temp = a_temp & iyMem8; + setResultFlags(a_temp); + setParity(a_temp); + A = a_temp; } :OR reg0_3 is op6_2=0x2 & bits3_3=0x6 & reg0_3 { + local a_temp = A; $(H_flag) = 0; $(C_flag) = 0; $(N_flag) = 0; - A = A | reg0_3; - setResultFlags(A); - setParity(A); + a_temp = a_temp | reg0_3; + setResultFlags(a_temp); + setParity(a_temp); + A = a_temp; } :OR imm8 is op0_8=0xf6; imm8 { + local a_temp = A; $(H_flag) = 0; $(C_flag) = 0; $(N_flag) = 0; - A = A | imm8; - setResultFlags(A); - setParity(A); + a_temp = a_temp | imm8; + setResultFlags(a_temp); + setParity(a_temp); + A = a_temp; } :OR (HL) is op0_8=0xb6 & HL { + val:1 = 0; + MemRead(val,HL); + local a_temp = A; + $(H_flag) = 0; $(C_flag) = 0; $(N_flag) = 0; - val:1 = 0; - MemRead(val,HL); - A = A | val; - setResultFlags(A); - setParity(A); + a_temp = a_temp | val; + setResultFlags(a_temp); + setParity(a_temp); + A = a_temp; } :OR ixMem8 is op0_8=0xdd; op0_8=0xb6; ixMem8 { + local a_temp = A; $(H_flag) = 0; $(C_flag) = 0; $(N_flag) = 0; - A = A | ixMem8; - setResultFlags(A); - setParity(A); + a_temp = a_temp | ixMem8; + setResultFlags(a_temp); + setParity(a_temp); + A = a_temp; } :OR iyMem8 is op0_8=0xfd; op0_8=0xb6; iyMem8 { + local a_temp = A; $(H_flag) = 0; $(C_flag) = 0; $(N_flag) = 0; - A = A | iyMem8; - setResultFlags(A); - setParity(A); + a_temp = a_temp | iyMem8; + setResultFlags(a_temp); + setParity(a_temp); + A = a_temp; } :XOR reg0_3 is op6_2=0x2 & bits3_3=0x5 & reg0_3 { + local a_temp = A; $(H_flag) = 0; $(C_flag) = 0; $(N_flag) = 0; - A = A ^ reg0_3; - setResultFlags(A); - setParity(A); + a_temp = a_temp ^ reg0_3; + setResultFlags(a_temp); + setParity(a_temp); + A = a_temp; } :XOR imm8 is op0_8=0xee; imm8 { + local a_temp = A; $(H_flag) = 0; $(C_flag) = 0; $(N_flag) = 0; - A = A ^ imm8; - setResultFlags(A); - setParity(A); + a_temp = a_temp ^ imm8; + setResultFlags(a_temp); + setParity(a_temp); + A = a_temp; } :XOR (HL) is op0_8=0xae & HL { + val:1 = 0; + MemRead(val,HL); + local a_temp = A; + $(H_flag) = 0; $(C_flag) = 0; $(N_flag) = 0; - val:1 = 0; - MemRead(val,HL); - A = A ^ val; - setResultFlags(A); - setParity(A); + + a_temp = a_temp ^ val; + setResultFlags(a_temp); + setParity(a_temp); + A = a_temp; } :XOR ixMem8 is op0_8=0xdd; op0_8=0xae; ixMem8 { + local a_temp = A; $(H_flag) = 0; $(C_flag) = 0; $(N_flag) = 0; - A = A ^ ixMem8; - setResultFlags(A); - setParity(A); + a_temp = a_temp ^ ixMem8; + setResultFlags(a_temp); + setParity(a_temp); + A = a_temp; } :XOR iyMem8 is op0_8=0xfd; op0_8=0xae; iyMem8 { + local a_temp = A; $(H_flag) = 0; $(C_flag) = 0; $(N_flag) = 0; - A = A ^ iyMem8; - setResultFlags(A); - setParity(A); + a_temp = a_temp ^ iyMem8; + setResultFlags(a_temp); + setParity(a_temp); + A = a_temp; } :CP reg0_3 is op6_2=0x2 & bits3_3=0x7 & reg0_3 { - cmp:1 = A - reg0_3; - subtractionFlags(A, reg0_3); + local a_temp = A; + local r_temp = reg0_3; + cmp:1 = a_temp - r_temp; + subtractionFlags(a_temp, r_temp); setResultFlags(cmp); } :CP imm8 is op0_8=0xfe; imm8 { - cmp:1 = A - imm8; - subtractionFlags(A, imm8); + local a_temp = A; + cmp:1 = a_temp - imm8; + subtractionFlags(a_temp, imm8); setResultFlags(cmp); } :CP (HL) is op0_8=0xbe & HL { val:1 = 0; MemRead(val,HL); + local a_temp = A; - cmp:1 = A - val; - subtractionFlags(A, val); + cmp:1 = a_temp - val; + subtractionFlags(a_temp, val); setResultFlags(cmp); } :CP ixMem8 is op0_8=0xdd; op0_8=0xbe; ixMem8 { val:1 = ixMem8; - - cmp:1 = A - val; - subtractionFlags(A, val); + local a_temp = A; + + cmp:1 = a_temp - val; + subtractionFlags(a_temp, val); setResultFlags(cmp); } :CP iyMem8 is op0_8=0xfd; op0_8=0xbe; iyMem8 { val:1 = iyMem8; - - cmp:1 = A - val; - subtractionFlags(A, val); +local a_temp = A; + + cmp:1 = a_temp - val; + subtractionFlags(a_temp, val); setResultFlags(cmp); } :INC reg3_3 is op6_2=0x0 & reg3_3 & bits0_3=0x4 { local r_temp = reg3_3; - - reg3_3 = reg3_3 + 1; - setResultFlags(reg3_3); - additionFlagsNoC(r_temp, 1); + additionFlags(r_temp, 1); + r_temp = r_temp + 1; + reg3_3 = r_temp; + setResultFlags(r_temp); } :INC (HL) is op0_8=0x34 & HL { @@ -1065,10 +1194,10 @@ cc2: "C" is bits3_3=0x7 { c:1 = $(C_flag); export c; } :DEC reg3_3 is op6_2=0x0 & reg3_3 & bits0_3=0x5 { local r_temp = reg3_3; - - reg3_3 = reg3_3 - 1; subtractionFlagsNoC(r_temp, 1); - setResultFlags(reg3_3); + r_temp = r_temp - 1; + reg3_3 = r_temp; + setResultFlags(r_temp); } :DEC (HL) is op0_8=0x35 & HL { @@ -1103,10 +1232,11 @@ cc2: "C" is bits3_3=0x7 { c:1 = $(C_flag); export c; } } :DAA is op0_8=0x27 { + local a_temp = A; if (DECOMPILE_MODE) goto+ + + ++554889e54883ec3048c7c34600100048 +895de84889f94889f7488b5de8ffd348 +8d59104889036631c0c3 + ++ + piVar1 = obtainPtr\(nm\); +return 0; +CONCAT +; - HN:1 = A >> 4; # high nibble - LN:1 = A & 0xF; # low nibbble + HN:1 = a_temp >> 4; # high nibble + LN:1 = a_temp & 0xF; # low nibbble # # If (C and H are both 0, and both nibbles are in range[0,9] no # adjustment is needed. @@ -1130,31 +1260,31 @@ if (DECOMPILE_MODE) goto ; # # Isn't used - A = A + 0x06; + a_temp = a_temp + 0x06; goto ; - A = A + 0x06; + a_temp = a_temp + 0x06; goto ; - A = A + 0x60; + a_temp = a_temp + 0x60; $(C_flag) = 1; goto ; - A = A + 0x66; + a_temp = a_temp + 0x66; $(C_flag) = 1; goto ; - A = A + 0x66; + a_temp = a_temp + 0x66; $(C_flag) = 1; goto ; - A = A + 0x60; + a_temp = a_temp + 0x60; goto ; - A = A + 0x66; + a_temp = a_temp + 0x66; goto ; - A = A + 0x66; + a_temp = a_temp + 0x66; goto ; @@ -1168,30 +1298,32 @@ if (DECOMPILE_MODE) goto ; # # Isn't used - A = A + 0xFA; + a_temp = a_temp + 0xFA; goto ; - A = A + 0xA0; + a_temp = a_temp + 0xA0; goto ; - A = A + 0x9A; + a_temp = a_temp + 0x9A; - setResultFlags(A); - setParity(A); + setResultFlags(a_temp); + setParity(a_temp); + A = a_temp; goto ; - A_temp:1 = A; + - A = BCDadjust(A_temp, $(C_flag), $(H_flag)); - $(C_flag) = BCDadjustCarry(A_temp, $(C_flag), $(H_flag)); + a_temp = BCDadjust(a_temp, $(C_flag), $(H_flag)); + $(C_flag) = BCDadjustCarry(a_temp, $(C_flag), $(H_flag)); - setResultFlags(A); - $(PV_flag) = hasEvenParity(A); + setResultFlags(a_temp); + $(PV_flag) = hasEvenParity(a_temp); + A = a_temp; } @@ -1203,11 +1335,11 @@ if (DECOMPILE_MODE) goto ; } :NEG is op0_8=0xed; op0_8=0x44 { - A_temp:1 = A; - - A = -A; - subtractionFlags(0, A_temp); - setResultFlags(A); + local a_temp = A; + subtractionFlags(0, a_temp); + a_temp = -a_temp; + A = a_temp; + setResultFlags(a_temp); } :CCF is op0_8=0x3f { @@ -1256,38 +1388,43 @@ if (DECOMPILE_MODE) goto ; local HL_temp = HL; local Reg_temp = sRegPair4_2; - HL = HL + sRegPair4_2; additionFlagsNoPV(HL_temp, Reg_temp); + HL = HL_temp + Reg_temp; } :ADC HL,sRegPair4_2 is op0_8=0xed & HL; op6_2=0x1 & sRegPair4_2 & bits0_4=0xa { local HL_temp = HL; local Reg_temp = sRegPair4_2; - HL = HL + sRegPair4_2 + zext($(C_flag)); - setResultFlags(HL); additionFlagsNoPV(HL_temp, Reg_temp); + HL_temp = HL_temp + Reg_temp + zext($(C_flag)); + setResultFlags(HL_temp); + HL = HL_temp; } :SBC HL,sRegPair4_2 is op0_8=0xed & HL; op6_2=0x1 & sRegPair4_2 & bits0_4=0x2 { - subtractionWithCarry(HL, sRegPair4_2, HL); - setResultFlags(HL); + local HL_temp = HL; + local Reg_temp = sRegPair4_2; + + subtractionWithCarry(HL_temp, sRegPair4_2, HL_temp); + setResultFlags(HL_temp); + HL = HL_temp; } :ADD IX,pRegPair4_2 is op0_8=0xdd & IX; op6_2=0x0 & pRegPair4_2 & bits0_4=0x9 { local IX_temp = IX; local Reg_temp = pRegPair4_2; - IX = IX + pRegPair4_2; additionFlagsNoPV(IX_temp, Reg_temp); + IX = IX_temp + pRegPair4_2; } :ADD IY,pRegPair4_2 is op0_8=0xfd & IY; op6_2=0x0 & pRegPair4_2 & bits0_4=0x9 { local IY_temp = IY; local Reg_temp = pRegPair4_2; - IY = IY + pRegPair4_2; additionFlagsNoPV(IY_temp, Reg_temp); + IY = IY_temp + Reg_temp; } :INC sRegPair4_2 is op6_2=0x0 & sRegPair4_2 & bits0_4=0x3 { @@ -1315,41 +1452,47 @@ if (DECOMPILE_MODE) goto ; } :RLCA is op0_8=0x07 { - $(C_flag) = (A >> 7); - A = (A << 1) | $(C_flag); + local a_temp = A; + $(C_flag) = (a_temp >> 7); + A = (a_temp << 1) | $(C_flag); $(H_flag) = 0; $(N_flag) = 0; } :RLA is op0_8=0x17 { - nextC:1 = (A >> 7); - A = (A << 1) | $(C_flag); + local a_temp = A; + nextC:1 = (a_temp >> 7); + A = (a_temp << 1) | $(C_flag); $(C_flag) = nextC; $(H_flag) = 0; $(N_flag) = 0; } :RRCA is op0_8=0x0f { - $(C_flag) = (A & 1); - A = (A >> 1) | ($(C_flag) << 7); + local a_temp = A; + $(C_flag) = (a_temp & 1); + A = (a_temp >> 1) | ($(C_flag) << 7); $(H_flag) = 0; $(N_flag) = 0; } :RRA is op0_8=0x1f { - nextC:1 = (A & 1); - A = (A >> 1) | ($(C_flag) << 7); + local a_temp = A; + nextC:1 = (a_temp & 1); + A = (a_temp >> 1) | ($(C_flag) << 7); $(C_flag) = nextC; $(H_flag) = 0; $(N_flag) = 0; } :RLC reg0_3 is op0_8=0x0cb; op6_2=0x0 & bits3_3=0x0 & reg0_3 { - $(C_flag) = (reg0_3 >> 7); - reg0_3 = (reg0_3 << 1) | $(C_flag); - setResultFlags(reg0_3); + local val = reg0_3; + $(C_flag) = (val >> 7); + val = (val << 1) | $(C_flag); + reg0_3 = val; + setResultFlags(val); $(H_flag) = 0; - setParity(reg0_3); + setParity(val); $(N_flag) = 0; } @@ -1387,12 +1530,14 @@ if (DECOMPILE_MODE) goto ; } :RL reg0_3 is op0_8=0x0cb; op6_2=0x0 & bits3_3=0x2 & reg0_3 { - nextC:1 = (reg0_3 >> 7); - reg0_3 = (reg0_3 << 1) | $(C_flag); + local r_temp = reg0_3; + nextC:1 = (r_temp >> 7); + r_temp = (r_temp << 1) | $(C_flag); + reg0_3 = r_temp; $(C_flag) = nextC; - setResultFlags(reg0_3); + setResultFlags(r_temp); $(H_flag) = 0; - setParity(reg0_3); + setParity(r_temp); $(N_flag) = 0; } @@ -1434,11 +1579,13 @@ if (DECOMPILE_MODE) goto ; } :RRC reg0_3 is op0_8=0x0cb; op6_2=0x0 & bits3_3=0x1 & reg0_3 { - $(C_flag) = (reg0_3 & 1); - reg0_3 = (reg0_3 >> 1) | ($(C_flag) << 7); - setResultFlags(reg0_3); + local r_temp = reg0_3; + $(C_flag) = (r_temp & 1); + r_temp = (r_temp >> 1) | ($(C_flag) << 7); + reg0_3 = r_temp; + setResultFlags(r_temp); $(H_flag) = 0; - setParity(reg0_3); + setParity(r_temp); $(N_flag) = 0; } @@ -1477,12 +1624,14 @@ if (DECOMPILE_MODE) goto ; } :RR reg0_3 is op0_8=0x0cb; op6_2=0x0 & bits3_3=0x3 & reg0_3 { - nextC:1 = (reg0_3 & 1); - reg0_3 = (reg0_3 >> 1) | ($(C_flag) << 7); + local r_temp = reg0_3; + nextC:1 = (r_temp & 1); + r_temp = (r_temp >> 1) | ($(C_flag) << 7); + reg0_3 = r_temp; $(C_flag) = nextC; - setResultFlags(reg0_3); + setResultFlags(r_temp); $(H_flag) = 0; - setParity(reg0_3); + setParity(r_temp); $(N_flag) = 0; } @@ -1524,11 +1673,13 @@ if (DECOMPILE_MODE) goto ; } :SLA reg0_3 is op0_8=0x0cb; op6_2=0x0 & bits3_3=0x4 & reg0_3 { - $(C_flag) = (reg0_3 >> 7); - reg0_3 = reg0_3 << 1; - setResultFlags(reg0_3); + local r_temp = reg0_3; + $(C_flag) = (r_temp >> 7); + r_temp = r_temp << 1; + reg0_3 = r_temp; + setResultFlags(r_temp); $(H_flag) = 0; - setParity(reg0_3); + setParity(r_temp); $(N_flag) = 0; } @@ -1567,11 +1718,13 @@ if (DECOMPILE_MODE) goto ; } :SRA reg0_3 is op0_8=0x0cb; op6_2=0x0 & bits3_3=0x5 & reg0_3 { - $(C_flag) = (reg0_3 & 1); - reg0_3 = reg0_3 s>> 1; - setResultFlags(reg0_3); + local _val = reg0_3; + $(C_flag) = (_val & 1); + _val = _val s>> 1; + reg0_3 = _val; + setResultFlags(_val); $(H_flag) = 0; - setParity(reg0_3); + setParity(_val); $(N_flag) = 0; } @@ -1610,11 +1763,13 @@ if (DECOMPILE_MODE) goto ; } :SRL reg0_3 is op0_8=0x0cb; op6_2=0x0 & bits3_3=0x7 & reg0_3 { - $(C_flag) = (reg0_3 & 1); - reg0_3 = reg0_3 >> 1; - setResultFlags(reg0_3); + local val = reg0_3; + $(C_flag) = (val & 1); + val = val >> 1; + reg0_3 = val; + setResultFlags(val); $(H_flag) = 0; - setParity(reg0_3); + setParity(val); $(N_flag) = 0; } @@ -1654,37 +1809,41 @@ if (DECOMPILE_MODE) goto ; :RLD is op0_8=0xed; op0_8=0x6f { val:1 = 0; + local a_temp = A; MemRead(val,HL); - nibA:1 = A & 0x0f; + nibA:1 = a_temp & 0x0f; nibM:1 = val >> 4; val = (val << 4) | nibA; - A = (A & 0xf0) | nibM; + a_temp = (a_temp & 0xf0) | nibM; + A = a_temp; MemStore(HL,val); @if defined(Z180) setResultFlags(val); @else - setResultFlags(A); + setResultFlags(a_temp); @endif $(H_flag) = 0; - setParity(A); + setParity(a_temp); $(N_flag) = 0; } :RRD is op0_8=0xed; op0_8=0x67 { val:1 = 0; MemRead(val,HL); - nibA:1 = A & 0x0f; + local a_temp = A; + nibA:1 = a_temp & 0x0f; nibM:1 = val & 0x0f; val = (val >> 4) | (nibA << 4); - A = (A & 0xf0) | nibM; + a_temp = (a_temp & 0xf0) | nibM; + A = a_temp; MemStore(HL,val); @if defined(Z180) setResultFlags(val); @else - setResultFlags(A); + setResultFlags(a_temp); @endif $(H_flag) = 0; - setParity(A); + setParity(a_temp); $(N_flag) = 0; } @@ -1855,10 +2014,12 @@ if (DECOMPILE_MODE) goto ; } :IN reg3_3,IOAddrC is op0_8=0xed & IOAddrC; op6_2=0x1 & reg3_3 & bits0_3=0x0 { - ioRead(IOAddrC, reg3_3); - setResultFlags(reg3_3); + val:1 = 0; + ioRead(IOAddrC, val); + reg3_3 = val; + setResultFlags(val); $(H_flag) = 0; - setParity(reg3_3); + setParity(val); $(N_flag) = 0; } @@ -1913,59 +2074,70 @@ if (DECOMPILE_MODE) goto ; } :OUTI is op0_8=0xed & IOAddrC; op0_8=0xa3 { + local test = B - 1; + B = test; val:1 = 0; MemRead(val,HL); + ioWrite(IOAddrC, val); - B = B - 1; HL = HL + 1; - $(Z_flag) = (B == 0); - $(N_flag) = (B s< 0); + $(Z_flag) = (test == 0); + $(N_flag) = (test s< 0); } :OTIR is op0_8=0xed & IOAddrC; op0_8=0xb3 { B = B - 1; val:1 = 0; MemRead(val,HL); + ioWrite(IOAddrC, val); HL = HL + 1; + if (B != 0) goto inst_start; + $(Z_flag) = 1; $(N_flag) = 1; } :OUTD is op0_8=0xed & IOAddrC; op0_8=0xab { - B = B - 1; + local test = B - 1; + B = test; val:1 = 0; MemRead(val,HL); + ioWrite(IOAddrC, val); HL = HL - 1; - $(Z_flag) = (B == 0); - $(N_flag) = (B s< 0); + $(Z_flag) = (test == 0); + $(N_flag) = (test s< 0); } :OTDR is op0_8=0xed & IOAddrC; op0_8=0xbb { B = B - 1; val:1 = 0; MemRead(val,HL); + ioWrite(IOAddrC, val); HL = HL - 1; + if (B != 0) goto inst_start; + $(Z_flag) = 1; $(N_flag) = 1; } @if defined(Z180) :MLT qRegPair4_2 is op0_8=0xed; op6_2=0x1 & qRegPair4_2 & bits0_4=0xc { - hi:2 = qRegPair4_2 >> 8; - lo:2 = qRegPair4_2 & 0xff; + local pair = qRegPair4_2; + hi:2 = pair >> 8; + lo:2 = pair & 0xff; qRegPair4_2 = hi * lo; } :TST reg3_3 is op0_8=0xed; op6_2=0x0 & reg3_3 & bits0_3=0x4 { - r:1 = reg3_3 & A; - setResultFlags(r); + local result = reg3_3 & A; + setResultFlags(result); $(H_flag)=1; - setParity(r); + setParity(result); $(N_flag)=0; $(C_flag)=0; } @@ -1973,37 +2145,40 @@ if (DECOMPILE_MODE) goto ; :TST hlMem8 is op0_8=0xed; op0_8=0x34 & hlMem8 { val:1 = 0; MemRead(val,HL); - r:1 = val & A; - setResultFlags(r); + + local result = val & A; + setResultFlags(result); $(H_flag)=1; - setParity(r); + setParity(result); $(N_flag)=0; $(C_flag)=0; } :TST imm8 is op0_8=0xed; op0_8=0x64; imm8 { - r:1 = imm8 & A; - setResultFlags(r); + val:1 = imm8 & A; + setResultFlags(val); $(H_flag)=1; - setParity(r); + setParity(val); $(N_flag)=0; $(C_flag)=0; } :IN0 Flag,IOAddr8 is op0_8=0xed; op6_2=0x0 & bits3_3=0x6 & Flag & bits0_3=0x0; IOAddr8 { - r:1 = 0; - ioRead(IOAddr8,r); # read input location - setResultFlags(r); + val:1 = 0; + ioRead(IOAddr8,val); # read input location + setResultFlags(val); $(H_flag)=0; - setParity(r); + setParity(val); $(N_flag)=0; } :IN0 reg3_3,IOAddr8 is op0_8=0xed; op6_2=0x0 & reg3_3 & bits0_3=0x0; IOAddr8 { - ioRead(IOAddr8,reg3_3); # read input location - setResultFlags(reg3_3); + local r_temp = reg3_3; + ioRead(IOAddr8,r_temp); # read input location + reg3_3 = r_temp; + setResultFlags(r_temp); $(H_flag)=0; - setParity(reg3_3); + setParity(r_temp); $(N_flag)=0; } @@ -2012,37 +2187,42 @@ if (DECOMPILE_MODE) goto ; } :OTDM is op0_8=0xed; op0_8=0x8b & hlMem8 & IOAddrC { - r:1 = hlMem8; - ioWrite(IOAddrC, r); + val:1 = hlMem8; + ioWrite(IOAddrC, val); HL = HL - 1; C = C - 1; - setSubtractFlags(B,1); # ?? sets $(C_flag) based upon B-1 ?? - B = B - 1; - setResultFlags(B); + local test = B; + setSubtractFlags(test,1); # ?? sets $(C_flag) based upon B-1 ?? + test = test - 1; + B = test; + setResultFlags(test); # P_flag = parity(r); - $(PV_flag) = (r s< 0); + $(PV_flag) = (val s< 0); } :OTDMR is op0_8=0xed; op0_8=0x9b & hlMem8 & IOAddrC { - r:1 = hlMem8; - ioWrite(IOAddrC, r); + local test = B - 1; + B = test; + val:1 = hlMem8; + ioWrite(IOAddrC, val); HL = HL - 1; C = C - 1; - B = B - 1; - if (B != 0) goto inst_start; + + if (test != 0) goto inst_start; + $(S_flag)=0; $(Z_flag)=1; $(H_flag) = 0; # $(PV_flag)=1; - $(PV_flag) = (r s< 0); # based upon last output byte + $(PV_flag) = (val s< 0); # based upon last output byte $(C_flag)=0; } :TSTIO IOAddr8 is op0_8=0xed; op0_8=0x74; IOAddr8 { - v:1 = 0; - ioRead(IOAddr8,v); - r:1 = A & v; - setResultFlags(r); + val:1 = 0; + ioRead(IOAddr8,val); + local result = A & val; + setResultFlags(result); $(H_flag) = 1; # P_flag = parity(v); $(N_flag) = 0; @@ -2050,32 +2230,37 @@ if (DECOMPILE_MODE) goto ; } :OTIM is op0_8=0xed; op0_8=0x83 & hlMem8 & IOAddrC { - r:1 = hlMem8; - ioWrite(IOAddrC, r); + val:1 = hlMem8; + ioWrite(IOAddrC, val); HL = HL + 1; C = C + 1; - setSubtractFlags(B,1); # ?? sets $(C_flag) based upon B-1 ?? - B = B - 1; - setResultFlags(B); + local test = B; + setSubtractFlags(test,1); # ?? sets $(C_flag) based upon B-1 ?? + test = test - 1; + B = test; + setResultFlags(test); $(H_flag) = 1; # P_flag = parity(r); - $(PV_flag) = (r s< 0); + $(PV_flag) = (val s< 0); $(N_flag) = 0; $(C_flag)=0; } :OTIMR is op0_8=0xed; op0_8=0x93 & hlMem8 & IOAddrC { - r:1 = hlMem8; - ioWrite(IOAddrC, r); + val:1 = hlMem8; + local test = B - 1; + B = test; + ioWrite(IOAddrC, val); HL = HL - 1; C = C + 1; - B = B - 1; - if (B != 0) goto inst_start; + + if (test != 0) goto inst_start; + $(S_flag)=0; $(Z_flag)=1; $(H_flag) = 0; # $(PV_flag)=1; - $(PV_flag) = (r s< 0); # based upon last output byte + $(PV_flag) = (val s< 0); # based upon last output byte $(C_flag)=0; } @@ -2084,3 +2269,314 @@ if (DECOMPILE_MODE) goto ; } @endif + +# Undocumented instructions +# information taken from https://clrhome.org/table + +@ifndef Z180 + +# Bad support on Z180 + + +:IM 0 is op0_8=0xed; op0_8=0x4e { + setInterruptMode(0:1); +} + +:IM 1 is op0_8=0xed; op0_8=0x6e { + setInterruptMode(1:1); +} + + +# CB range + +:SLL reg0_3 is op0_8=0x0cb; op6_2=0x0 & bits3_3=0x6 & reg0_3 { + local r_temp = reg0_3; + $(C_flag) = (r_temp >> 7); + r_temp = (r_temp << 1) | 0x01; + reg0_3 = r_temp; + setResultFlags(r_temp); + $(H_flag) = 0; + setParity(r_temp); + $(N_flag) = 0; +} + +:SLL (HL) is op0_8=0x0cb & HL; op0_8=0x36 { + val:1 = 0; + MemRead(val,HL); + $(C_flag) = (val >> 7); + val = val << 1 | 0x01; + setResultFlags(val); + MemStore(HL,val); + $(H_flag) = 0; + setParity(val); + $(N_flag) = 0; +} + +## DD range + +ixh_iyh: IXH is op0_8=0xdd & IXH { export IXH; } +ixh_iyh: IYH is op0_8=0xfd & IYH { export IYH; } +ixl_iyl: IXL is op0_8=0xdd & IXL { export IXL; } +ixl_iyl: IYL is op0_8=0xfd & IYL { export IYL; } + +:INC ixh_iyh is ixh_iyh; op0_8=0x24 { + local val = ixh_iyh; + additionFlags(val, 1); + val = val + 1; + ixh_iyh = val; + setResultFlags(val); +} + +:DEC ixh_iyh is ixh_iyh; op0_8=0x25 { + local val = ixh_iyh; + subtractionFlagsNoC(val, 1); + val = val - 1; + ixh_iyh = val ; + setResultFlags(val); +} + +:INC ixl_iyl is ixl_iyl; op0_8=0x2c { + local val = ixl_iyl; + additionFlags(val, 1); + val = val + 1; + ixl_iyl = val; + setResultFlags(val); +} + +:DEC ixl_iyl is ixl_iyl; op0_8=0x2d { + local val = ixl_iyl; + subtractionFlagsNoC(val, 1); + val = val - 1; + ixl_iyl = val; + setResultFlags(val); +} + +:LD ixh_iyh,imm8 is ixh_iyh; op0_8=0x26; imm8 { + ixh_iyh = imm8; +} + +:LD ixl_iyl,imm8 is ixl_iyl; op0_8=0x2e; imm8 { + ixl_iyl = imm8; +} + +:LD B,ixh_iyh is ixh_iyh & B; op0_8=0x44 { + B = ixh_iyh; +} + +:LD B,ixl_iyl is ixl_iyl & B; op0_8=0x45 { + B = ixl_iyl; +} + +:LD C,ixh_iyh is ixh_iyh & C; op0_8=0x4c { + C = ixh_iyh; +} + +:LD C,ixl_iyl is ixl_iyl & C; op0_8=0x4d { + C = ixl_iyl; +} + +:LD D,ixh_iyh is ixh_iyh & D; op0_8=0x54 { + D = ixh_iyh; +} + +:LD D,ixl_iyl is ixl_iyl & D; op0_8=0x55 { + D = ixl_iyl; +} + +:LD E,ixh_iyh is ixh_iyh & E; op0_8=0x5c { + E = ixh_iyh; +} + +:LD E,ixl_iyl is ixl_iyl & E; op0_8=0x5d { + E = ixl_iyl; +} + +:LD ixh_iyh,reg0_3 is ixh_iyh; op6_2=0x1 & bits3_3=0x4 & reg0_3{ + ixh_iyh = reg0_3; +} + +:LD ixl_iyl,reg0_3 is ixl_iyl; op6_2=0x1 & bits3_3=0x5 & reg0_3 { + ixl_iyl = reg0_3; +} + +:LD ixh_iyh,ixl_iyl is ixh_iyh & ixl_iyl; op0_8=0x65 { + ixh_iyh = ixl_iyl; +} + +:LD ixh_iyh,A is ixh_iyh; op0_8=0x67 & A { + ixh_iyh = A; +} + +:LD ixl_iyl,ixh_iyh is ixl_iyl & ixh_iyh; op0_8=0x6c { + ixl_iyl = ixh_iyh; +} + +:LD ixl_iyl,A is ixl_iyl; op0_8=0x6f & A { + ixl_iyl = A; +} + +:LD A,ixh_iyh is ixh_iyh; op0_8=0x7c & A { + A = ixh_iyh; +} + +:LD A,ixl_iyl is ixl_iyl; op0_8=0x7d & A { + A = ixl_iyl; +} + +:ADD A, ixh_iyh is ixh_iyh; op0_8=0x84 & A { + local a_temp = A; + local val = ixh_iyh; + + additionFlags(a_temp, val); + a_temp = a_temp + val; + setResultFlags(a_temp); + A = a_temp; +} + +:ADD A, ixl_iyl is ixl_iyl; op0_8=0x85 & A { + local a_temp = A; + local val = ixl_iyl; + + additionFlags(a_temp, val); + a_temp = a_temp + val; + setResultFlags(a_temp); + A = a_temp; +} + +:ADC A, ixh_iyh is ixh_iyh; op0_8=0x8c & A { + local a_temp = A; + local val = ixh_iyh; + + additionWithCarry(a_temp, val, a_temp); + setResultFlags(a_temp); + A = a_temp; +} + +:ADC A, ixl_iyl is ixl_iyl; op0_8=0x8d & A { + local a_temp = A; + local val = ixl_iyl; + + additionWithCarry(a_temp, val, a_temp); + setResultFlags(a_temp); + A = a_temp; +} + +:SUB ixh_iyh is ixh_iyh; op0_8=0x94 { + local a_temp = A; + local val = ixh_iyh; + + subtractionFlags(a_temp, val); + a_temp = a_temp - val; + setResultFlags(a_temp); + A = a_temp; +} + +:SUB ixl_iyl is ixl_iyl; op0_8=0x95 { + local a_temp = A; + local val = ixl_iyl; + + subtractionFlags(a_temp, val); + a_temp = a_temp - val; + setResultFlags(a_temp); + A = a_temp; +} + +:SBC A, ixh_iyh is ixh_iyh; op0_8=0x9c & A { + local a_temp = A; + subtractionWithCarry(a_temp, ixh_iyh, a_temp); + setResultFlags(A); + A = a_temp; +} + +:SBC A, ixl_iyl is ixl_iyl; op0_8=0x9d & A { + local a_temp = A; + subtractionWithCarry(a_temp, ixl_iyl, a_temp); + setResultFlags(a_temp); + A = a_temp; +} + +:AND ixh_iyh is ixh_iyh; op0_8=0xa4 { + local a_temp = A; + $(H_flag) = 1; + $(C_flag) = 0; + $(N_flag) = 0; + a_temp = a_temp & ixh_iyh; + setResultFlags(a_temp); + setParity(a_temp); + A = a_temp; +} + +:AND ixl_iyl is ixl_iyl; op0_8=0xa5 { + local a_temp = A; + $(H_flag) = 1; + $(C_flag) = 0; + $(N_flag) = 0; + a_temp = a_temp & ixl_iyl; + setResultFlags(a_temp); + setParity(a_temp); + A = a_temp; +} + +:XOR ixh_iyh is ixh_iyh; op0_8=0xac { + local a_temp = A; + $(H_flag) = 0; + $(C_flag) = 0; + $(N_flag) = 0; + a_temp = a_temp ^ ixh_iyh; + setResultFlags(a_temp); + setParity(a_temp); + A = a_temp; +} + +:XOR ixl_iyl is ixl_iyl; op0_8=0xad { + local a_temp = A; + $(H_flag) = 0; + $(C_flag) = 0; + $(N_flag) = 0; + a_temp = a_temp ^ ixl_iyl; + setResultFlags(a_temp); + setParity(a_temp); + A = a_temp; +} + +:OR ixh_iyh is ixh_iyh; op0_8=0xb4 { + local a_temp = A; + $(H_flag) = 0; + $(C_flag) = 0; + $(N_flag) = 0; + a_temp = a_temp | ixh_iyh; + setResultFlags(a_temp); + setParity(a_temp); + A = a_temp; +} + +:OR ixl_iyl is ixl_iyl; op0_8=0xb5 { + local a_temp = A; + $(H_flag) = 0; + $(C_flag) = 0; + $(N_flag) = 0; + a_temp = a_temp | ixl_iyl; + setResultFlags(a_temp); + setParity(a_temp); + A = a_temp; +} + +:CP ixh_iyh is ixh_iyh; op0_8=0xbc { + local a_temp = A; + local r_temp = ixh_iyh; + + cmp:1 = a_temp - r_temp; + subtractionFlags(a_temp, r_temp); + setResultFlags(cmp); +} + +:CP ixl_iyl is ixl_iyl; op0_8=0xbd { + local a_temp = A; + local r_temp = ixl_iyl; + + cmp:1 = a_temp - r_temp; + subtractionFlags(a_temp, r_temp); + setResultFlags(cmp); +} + +@endif diff --git a/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/framework/main/datatree/VersionControlAction2Test.java b/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/framework/main/datatree/VersionControlAction2Test.java index 7c83d21ea2..32f289971b 100644 --- a/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/framework/main/datatree/VersionControlAction2Test.java +++ b/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/framework/main/datatree/VersionControlAction2Test.java @@ -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 { diff --git a/Ghidra/application.properties b/Ghidra/application.properties index 3453f5597c..63fd497edd 100644 --- a/Ghidra/application.properties +++ b/Ghidra/application.properties @@ -1,5 +1,5 @@ application.name=Ghidra -application.version=11.1 +application.version=11.1.1 application.release.name=DEV application.layout.version=2 application.gradle.min=7.3 diff --git a/eclipse/GhidraEclipseFormatter.xml b/eclipse/GhidraEclipseFormatter.xml index 6ad2f047df..bb36d11835 100644 --- a/eclipse/GhidraEclipseFormatter.xml +++ b/eclipse/GhidraEclipseFormatter.xml @@ -1,6 +1,6 @@ - - + + @@ -158,12 +158,14 @@ + + @@ -335,7 +337,7 @@ - + diff --git a/eclipse/GhidraSharedPreferences.epf b/eclipse/GhidraSharedPreferences.epf index f49ceb7781..462e0c2aab 100644 --- a/eclipse/GhidraSharedPreferences.epf +++ b/eclipse/GhidraSharedPreferences.epf @@ -1,16 +1,5 @@ -#Wed May 20 13:20:18 EDT 2020 +#Tue Jun 11 13:01:08 EDT 2024 \!/= -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.builder.resourceCopyExclusionFilter= -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.argumentPrefixes= -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.argumentSuffixes= -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.fieldPrefixes= -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.fieldSuffixes= -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.localPrefixes= -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.localSuffixes= -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.staticFieldPrefixes= -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.staticFieldSuffixes= -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes= -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes= /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.compliance=1.8 @@ -28,12 +17,12 @@ /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=default +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warning /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning @@ -49,41 +38,66 @@ /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.taskTags=TODO,FIXME,XXX,7937 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns=false /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.align_selector_in_method_invocation_on_expression_first_line=false /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.align_type_members_on_columns=false /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns=false /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.align_with_spaces=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_additive_operator=20 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_annotations_on_enum_constant=49 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field=49 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable=49 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method=49 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package=49 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter=0 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type=49 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=20 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=52 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=0 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=20 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=20 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=20 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_assertion_message=0 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_assignment=20 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_binary_expression=20 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=20 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_compact_loops=16 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain=0 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_enum_constants=48 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_expressions_in_switch_case_with_arrow=0 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_expressions_in_switch_case_with_colon=0 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_logical_operator=20 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_module_statements=16 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=20 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_record_components=16 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=80 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_shift_operator=0 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=20 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=20 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_record_declaration=16 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_switch_case_with_arrow=0 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_type_annotations=0 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_after_last_class_body_declaration=0 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method=1 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_before_field=0 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 @@ -92,6 +106,7 @@ /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_before_package=0 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_between_statement_group_in_switch=0 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line @@ -103,6 +118,8 @@ /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_record_constructor=end_of_line +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_record_declaration=end_of_line /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped=false @@ -118,8 +135,11 @@ /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.format_source_code=true /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.indent_root_tags=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.indent_tag_description=false /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.javadoc_do_not_separate_block_tags=false /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.line_length=80 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true @@ -134,6 +154,7 @@ /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_record_header=true /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.indent_empty_lines=false @@ -158,11 +179,14 @@ /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert @@ -188,11 +212,17 @@ /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_permitted_types=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_record_components=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_switch_case_expressions=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_not_operator=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert @@ -209,6 +239,7 @@ /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_record_declaration=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert @@ -217,13 +248,19 @@ /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_case=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert @@ -240,6 +277,7 @@ /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_record_declaration=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert @@ -266,11 +304,16 @@ /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_permitted_types=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_record_components=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_switch_case_expressions=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert @@ -282,6 +325,8 @@ /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_constructor=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_declaration=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert @@ -297,6 +342,7 @@ /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_record_declaration=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert @@ -307,9 +353,12 @@ /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert @@ -320,7 +369,7 @@ /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.join_lines_in_comments=true -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.join_wrapped_lines=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.join_wrapped_lines=false /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line=one_line_never /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line=one_line_if_empty /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.keep_code_block_on_one_line=one_line_never @@ -333,18 +382,27 @@ /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line=one_line_never /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line=one_line_never /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.keep_method_body_on_one_line=one_line_never +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.keep_record_constructor_on_one_line=one_line_if_empty +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.keep_record_declaration_on_one_line=one_line_if_empty /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line=false /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line=false /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line=false /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.keep_switch_body_block_on_one_line=one_line_never +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.keep_switch_case_with_arrow_on_one_line=one_line_never /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line=one_line_never /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.lineSplit=100 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=true /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.number_of_blank_lines_after_code_block=0 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_code_block=0 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_code_block=0 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_method_body=0 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.number_of_blank_lines_before_code_block=0 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=separate_lines_if_wrapped /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines @@ -352,23 +410,33 @@ /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_record_declaration=common_lines /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.tabulation.char=tab /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.tabulation.size=4 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.text_block_indentation=0 /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.use_on_off_tags=true /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.wrap_before_additive_operator=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.wrap_before_assertion_message_operator=true /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false -/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.wrap_before_binary_operator=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=false /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.wrap_before_logical_operator=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=false /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.wrap_before_relational_operator=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.wrap_before_shift_operator=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.wrap_before_switch_case_arrow_operator=false /instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true /instance/org.eclipse.jdt.ui/formatter_profile=_GhidraEclipseFormatter -/instance/org.eclipse.jdt.ui/formatter_settings_version=15 +/instance/org.eclipse.jdt.ui/formatter_settings_version=23 /instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.exception.name=e -/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.formatterprofiles=\n \n \n -/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.formatterprofiles.version=15 +/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.formatterprofiles=\r\n\n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \r\n \r\n +/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.formatterprofiles.version=23 /instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.gettersetter.use.is=true /instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.ignorelowercasenames=true /instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.importorder=java;javax;org;com; @@ -376,6 +444,149 @@ /instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.overrideannotation=true /instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.staticondemandthreshold=1 /instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.text.custom_code_templates=\r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n /**\n *\n * ${tags}\n *//**\n * ${tags}\n */ -@org.eclipse.jdt.core=3.16.0.v20181130-1748 -@org.eclipse.jdt.ui=3.16.0.v20181203-1249 +/instance/org.eclipse.jdt.ui/sp_cleanup.add_all=false +/instance/org.eclipse.jdt.ui/sp_cleanup.add_default_serial_version_id=true +/instance/org.eclipse.jdt.ui/sp_cleanup.add_generated_serial_version_id=false +/instance/org.eclipse.jdt.ui/sp_cleanup.add_missing_annotations=true +/instance/org.eclipse.jdt.ui/sp_cleanup.add_missing_deprecated_annotations=true +/instance/org.eclipse.jdt.ui/sp_cleanup.add_missing_methods=false +/instance/org.eclipse.jdt.ui/sp_cleanup.add_missing_nls_tags=false +/instance/org.eclipse.jdt.ui/sp_cleanup.add_missing_override_annotations=true +/instance/org.eclipse.jdt.ui/sp_cleanup.add_missing_override_annotations_interface_methods=true +/instance/org.eclipse.jdt.ui/sp_cleanup.add_serial_version_id=false +/instance/org.eclipse.jdt.ui/sp_cleanup.also_simplify_lambda=false +/instance/org.eclipse.jdt.ui/sp_cleanup.always_use_blocks=true +/instance/org.eclipse.jdt.ui/sp_cleanup.always_use_parentheses_in_expressions=false +/instance/org.eclipse.jdt.ui/sp_cleanup.always_use_this_for_non_static_field_access=false +/instance/org.eclipse.jdt.ui/sp_cleanup.always_use_this_for_non_static_method_access=false +/instance/org.eclipse.jdt.ui/sp_cleanup.array_with_curly=false +/instance/org.eclipse.jdt.ui/sp_cleanup.arrays_fill=false +/instance/org.eclipse.jdt.ui/sp_cleanup.bitwise_conditional_expression=false +/instance/org.eclipse.jdt.ui/sp_cleanup.boolean_literal=false +/instance/org.eclipse.jdt.ui/sp_cleanup.boolean_value_rather_than_comparison=false +/instance/org.eclipse.jdt.ui/sp_cleanup.break_loop=false +/instance/org.eclipse.jdt.ui/sp_cleanup.collection_cloning=false +/instance/org.eclipse.jdt.ui/sp_cleanup.comparing_on_criteria=false +/instance/org.eclipse.jdt.ui/sp_cleanup.comparison_statement=false +/instance/org.eclipse.jdt.ui/sp_cleanup.controlflow_merge=false +/instance/org.eclipse.jdt.ui/sp_cleanup.convert_functional_interfaces=false +/instance/org.eclipse.jdt.ui/sp_cleanup.convert_to_enhanced_for_loop=false +/instance/org.eclipse.jdt.ui/sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false +/instance/org.eclipse.jdt.ui/sp_cleanup.convert_to_switch_expressions=false +/instance/org.eclipse.jdt.ui/sp_cleanup.correct_indentation=false +/instance/org.eclipse.jdt.ui/sp_cleanup.do_while_rather_than_while=false +/instance/org.eclipse.jdt.ui/sp_cleanup.double_negation=false +/instance/org.eclipse.jdt.ui/sp_cleanup.else_if=false +/instance/org.eclipse.jdt.ui/sp_cleanup.embedded_if=false +/instance/org.eclipse.jdt.ui/sp_cleanup.evaluate_nullable=false +/instance/org.eclipse.jdt.ui/sp_cleanup.extract_increment=false +/instance/org.eclipse.jdt.ui/sp_cleanup.format_source_code=true +/instance/org.eclipse.jdt.ui/sp_cleanup.format_source_code_changes_only=true +/instance/org.eclipse.jdt.ui/sp_cleanup.hash=false +/instance/org.eclipse.jdt.ui/sp_cleanup.if_condition=false +/instance/org.eclipse.jdt.ui/sp_cleanup.insert_inferred_type_arguments=false +/instance/org.eclipse.jdt.ui/sp_cleanup.instanceof=false +/instance/org.eclipse.jdt.ui/sp_cleanup.instanceof_keyword=false +/instance/org.eclipse.jdt.ui/sp_cleanup.invert_equals=false +/instance/org.eclipse.jdt.ui/sp_cleanup.join=false +/instance/org.eclipse.jdt.ui/sp_cleanup.lazy_logical_operator=false +/instance/org.eclipse.jdt.ui/sp_cleanup.make_local_variable_final=true +/instance/org.eclipse.jdt.ui/sp_cleanup.make_parameters_final=false +/instance/org.eclipse.jdt.ui/sp_cleanup.make_private_fields_final=true +/instance/org.eclipse.jdt.ui/sp_cleanup.make_type_abstract_if_missing_method=false +/instance/org.eclipse.jdt.ui/sp_cleanup.make_variable_declarations_final=false +/instance/org.eclipse.jdt.ui/sp_cleanup.map_cloning=false +/instance/org.eclipse.jdt.ui/sp_cleanup.merge_conditional_blocks=false +/instance/org.eclipse.jdt.ui/sp_cleanup.multi_catch=false +/instance/org.eclipse.jdt.ui/sp_cleanup.never_use_blocks=false +/instance/org.eclipse.jdt.ui/sp_cleanup.never_use_parentheses_in_expressions=true +/instance/org.eclipse.jdt.ui/sp_cleanup.no_string_creation=false +/instance/org.eclipse.jdt.ui/sp_cleanup.no_super=false +/instance/org.eclipse.jdt.ui/sp_cleanup.number_suffix=false +/instance/org.eclipse.jdt.ui/sp_cleanup.objects_equals=false +/instance/org.eclipse.jdt.ui/sp_cleanup.on_save_use_additional_actions=false +/instance/org.eclipse.jdt.ui/sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false +/instance/org.eclipse.jdt.ui/sp_cleanup.operand_factorization=false +/instance/org.eclipse.jdt.ui/sp_cleanup.organize_imports=true +/instance/org.eclipse.jdt.ui/sp_cleanup.overridden_assignment=false +/instance/org.eclipse.jdt.ui/sp_cleanup.overridden_assignment_move_decl=true +/instance/org.eclipse.jdt.ui/sp_cleanup.plain_replacement=false +/instance/org.eclipse.jdt.ui/sp_cleanup.precompile_regex=false +/instance/org.eclipse.jdt.ui/sp_cleanup.primitive_comparison=false +/instance/org.eclipse.jdt.ui/sp_cleanup.primitive_parsing=false +/instance/org.eclipse.jdt.ui/sp_cleanup.primitive_rather_than_wrapper=false +/instance/org.eclipse.jdt.ui/sp_cleanup.primitive_serialization=false +/instance/org.eclipse.jdt.ui/sp_cleanup.pull_out_if_from_if_else=false +/instance/org.eclipse.jdt.ui/sp_cleanup.pull_up_assignment=false +/instance/org.eclipse.jdt.ui/sp_cleanup.push_down_negation=false +/instance/org.eclipse.jdt.ui/sp_cleanup.qualify_static_field_accesses_with_declaring_class=false +/instance/org.eclipse.jdt.ui/sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true +/instance/org.eclipse.jdt.ui/sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true +/instance/org.eclipse.jdt.ui/sp_cleanup.qualify_static_member_accesses_with_declaring_class=false +/instance/org.eclipse.jdt.ui/sp_cleanup.qualify_static_method_accesses_with_declaring_class=false +/instance/org.eclipse.jdt.ui/sp_cleanup.reduce_indentation=false +/instance/org.eclipse.jdt.ui/sp_cleanup.redundant_comparator=false +/instance/org.eclipse.jdt.ui/sp_cleanup.redundant_falling_through_block_end=false +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_private_constructors=true +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_redundant_modifiers=false +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_redundant_semicolons=false +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_redundant_type_arguments=false +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_trailing_whitespaces=false +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_trailing_whitespaces_all=true +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_trailing_whitespaces_ignore_empty=false +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_unnecessary_array_creation=false +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_unnecessary_casts=true +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_unnecessary_nls_tags=false +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_unused_imports=false +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_unused_local_variables=false +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_unused_method_parameters=false +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_unused_private_fields=true +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_unused_private_members=false +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_unused_private_methods=true +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_unused_private_types=true +/instance/org.eclipse.jdt.ui/sp_cleanup.replace_deprecated_calls=false +/instance/org.eclipse.jdt.ui/sp_cleanup.return_expression=false +/instance/org.eclipse.jdt.ui/sp_cleanup.simplify_lambda_expression_and_method_ref=false +/instance/org.eclipse.jdt.ui/sp_cleanup.single_used_field=false +/instance/org.eclipse.jdt.ui/sp_cleanup.sort_members=false +/instance/org.eclipse.jdt.ui/sp_cleanup.sort_members_all=false +/instance/org.eclipse.jdt.ui/sp_cleanup.standard_comparison=false +/instance/org.eclipse.jdt.ui/sp_cleanup.static_inner_class=false +/instance/org.eclipse.jdt.ui/sp_cleanup.strictly_equal_or_different=false +/instance/org.eclipse.jdt.ui/sp_cleanup.stringbuffer_to_stringbuilder=false +/instance/org.eclipse.jdt.ui/sp_cleanup.stringbuilder=false +/instance/org.eclipse.jdt.ui/sp_cleanup.stringbuilder_for_local_vars=true +/instance/org.eclipse.jdt.ui/sp_cleanup.stringconcat_stringbuffer_stringbuilder=false +/instance/org.eclipse.jdt.ui/sp_cleanup.stringconcat_to_textblock=false +/instance/org.eclipse.jdt.ui/sp_cleanup.substring=false +/instance/org.eclipse.jdt.ui/sp_cleanup.switch=false +/instance/org.eclipse.jdt.ui/sp_cleanup.system_property=false +/instance/org.eclipse.jdt.ui/sp_cleanup.system_property_boolean=false +/instance/org.eclipse.jdt.ui/sp_cleanup.system_property_file_encoding=false +/instance/org.eclipse.jdt.ui/sp_cleanup.system_property_file_separator=false +/instance/org.eclipse.jdt.ui/sp_cleanup.system_property_line_separator=false +/instance/org.eclipse.jdt.ui/sp_cleanup.system_property_path_separator=false +/instance/org.eclipse.jdt.ui/sp_cleanup.ternary_operator=false +/instance/org.eclipse.jdt.ui/sp_cleanup.try_with_resource=false +/instance/org.eclipse.jdt.ui/sp_cleanup.unlooped_while=false +/instance/org.eclipse.jdt.ui/sp_cleanup.unreachable_block=false +/instance/org.eclipse.jdt.ui/sp_cleanup.use_anonymous_class_creation=false +/instance/org.eclipse.jdt.ui/sp_cleanup.use_autoboxing=false +/instance/org.eclipse.jdt.ui/sp_cleanup.use_blocks=false +/instance/org.eclipse.jdt.ui/sp_cleanup.use_blocks_only_for_return_and_throw=false +/instance/org.eclipse.jdt.ui/sp_cleanup.use_directly_map_method=false +/instance/org.eclipse.jdt.ui/sp_cleanup.use_lambda=true +/instance/org.eclipse.jdt.ui/sp_cleanup.use_parentheses_in_expressions=false +/instance/org.eclipse.jdt.ui/sp_cleanup.use_string_is_blank=false +/instance/org.eclipse.jdt.ui/sp_cleanup.use_this_for_non_static_field_access=false +/instance/org.eclipse.jdt.ui/sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true +/instance/org.eclipse.jdt.ui/sp_cleanup.use_this_for_non_static_method_access=false +/instance/org.eclipse.jdt.ui/sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true +/instance/org.eclipse.jdt.ui/sp_cleanup.use_unboxing=false +/instance/org.eclipse.jdt.ui/sp_cleanup.use_var=false +/instance/org.eclipse.jdt.ui/sp_cleanup.useless_continue=false +/instance/org.eclipse.jdt.ui/sp_cleanup.useless_return=false +/instance/org.eclipse.jdt.ui/sp_cleanup.valueof_rather_than_instantiation=false +@org.eclipse.jdt.core=3.36.0.v20231115-1055 +@org.eclipse.jdt.ui=3.31.0.v20231115-2128 file_export_version=3.0