Merge remote-tracking branch 'origin/Ghidra_12.0'

This commit is contained in:
Ryan Kurtz 2025-09-25 05:26:54 -04:00
commit 9ad9d0d3db

View file

@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -128,28 +128,28 @@ public class ForceUnionAction extends AbstractDecompilerAction {
int opcode = accessOp.getOpcode(); int opcode = accessOp.getOpcode();
if (opcode == PcodeOp.PTRSUB) { if (opcode == PcodeOp.PTRSUB) {
parentDt = typeIsUnionRelated(accessOp.getInput(0)); parentDt = typeIsUnionRelated(accessOp.getInput(0));
if (parentDt == null) { if (parentDt != null) {
accessOp = null; accessVn = accessOp.getInput(0);
return; accessSlot = 0;
} if (accessOp.getInput(1).getOffset() == 0) { // Artificial op
accessVn = accessOp.getInput(0); do {
accessSlot = 0; Varnode tmpVn = accessOp.getOutput();
if (accessOp.getInput(1).getOffset() == 0) { // Artificial op PcodeOp tmpOp = tmpVn.getLoneDescend();
do { if (tmpOp == null) {
Varnode tmpVn = accessOp.getOutput(); break;
PcodeOp tmpOp = tmpVn.getLoneDescend(); }
if (tmpOp == null) { accessOp = tmpOp;
break; accessVn = tmpVn;
accessSlot = accessOp.getSlot(accessVn);
} }
accessOp = tmpOp; while (accessOp.getOpcode() == PcodeOp.PTRSUB &&
accessVn = tmpVn; accessOp.getInput(1).getOffset() == 0);
accessSlot = accessOp.getSlot(accessVn);
} }
while (accessOp.getOpcode() == PcodeOp.PTRSUB && return;
accessOp.getInput(1).getOffset() == 0);
} }
} }
else { else {
parentDt = null;
for (accessSlot = 0; accessSlot < accessOp.getNumInputs(); ++accessSlot) { for (accessSlot = 0; accessSlot < accessOp.getNumInputs(); ++accessSlot) {
accessVn = accessOp.getInput(accessSlot); accessVn = accessOp.getInput(accessSlot);
parentDt = typeIsUnionRelated(accessVn); parentDt = typeIsUnionRelated(accessVn);
@ -157,22 +157,26 @@ public class ForceUnionAction extends AbstractDecompilerAction {
break; break;
} }
} }
if (accessSlot >= accessOp.getNumInputs()) { if (parentDt != null) {
accessSlot = -1; if (opcode == PcodeOp.SUBPIECE && accessSlot == 0 &&
accessVn = accessOp.getOutput(); !(parentDt instanceof Pointer)) {
parentDt = typeIsUnionRelated(accessVn); // SUBPIECE acts directly as resolution operator
if (parentDt == null) { // Choose field based on output varnode, even though it isn't the union data-type
accessOp = null; accessSlot = -1;
return; // Give up, could not find type associated with field accessVn = accessOp.getOutput();
} }
} return;
if (opcode == PcodeOp.SUBPIECE && accessSlot == 0 && !(parentDt instanceof Pointer)) {
// SUBPIECE acts directly as resolution operator
// Choose field based on output varnode, even though it isn't the union data-type
accessSlot = -1;
accessVn = accessOp.getOutput();
} }
} }
accessSlot = -1;
accessVn = accessOp.getOutput();
if (accessVn != null) {
parentDt = typeIsUnionRelated(accessVn);
if (parentDt != null) {
return;
}
}
accessOp = null; // Give up, could not find type associated with field
} }
/** /**